Expose docker server on localhost using rathole on VPS

If you have a server running in a docker container on your local machine behind a NAT and firewall, this post will cover steps to expose it to the internet without opening up any ports in your firewall. This will work even if your home server is not on a static IP.

Assuming your local server is running on port 8080, which you want to expose outside your NAT/firewall, you can follow these steps. This assumes familiarity with using docker.

  • Generate keys for noise protocol to encrypt traffic between VPS and localhost.
$ docker run -it --rm rapiz1/rathole --genkey
Private Key:
<private_key>

Public Key:
<public_key>
  • On your remote VPS in a new directory, create a new directory and add rathole.server.toml file to it.
[server]
bind_addr = "0.0.0.0:2333"  # port to run rathole on.

[server.services.blog]
token = "secret_token"  # change to any secret string.
bind_addr = "0.0.0.0:8080"  # port to expose the local service on vps.

[server.transport]
type = "noise"
[server.transport.noise]
local_private_key = "<private_key>"  # private key from the command above.
  • Create a docker-compose.yml file in the same directory with the contents and then bring it up using docker-compose up -d.
services:
  rathole:
    image: rapiz1/rathole
    command: --server /config/rathole.server.toml
    restart: unless-stopped
    ports:
      - 2333:2333
      - 8080:8080
    volumes:
      - ./rathole.server.toml:/config/server.toml:ro
  • On your local server, add the rathole service to docker-compose.yml
services:
  rathole:
    image: rapiz1/rathole
    command: --client /config/client.toml
    restart: unless-stopped
    volumes:
      - ./rathole.client.toml:/config/client.toml:ro

  blog:  # this is the local server on port 8080.
    ....
  • Create a file rathole.client.toml with the contents
[client]
remote_addr = "<ip-of-vps>:2333"
[client.transport]
type = "noise"
[client.transport.noise]
remote_public_key = "<public_key>"

[client.services.blog]
token = "secret_token"
local_addr = "blog:8080"  # address for the service you want to expose
  • Visit <ip-of-vps>:8080, and it should be tunneled to your local service.

Instead of exposing port 8080 directly on VPS, you can use your existing reverse proxy setup like nginx, traefik on the rathole service too.

Leave a Reply