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.tomlfile 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.ymlfile in the same directory with the contents and then bring it up usingdocker-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.tomlwith 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.