Skip to main content

Sharing localhost service with a remote network

·2 mins

This past week I got asked a question that keeps arising from time to time. How do I share a docker service that is running on my local machine with a remote host and/or a remote network. For situations like this, I tend to lean on ssh’s remote port forwarding feature. Every single time though I ended up looking up the information. So once and for all I thought to myself, why don’t I just write my own definitive guide that makes sense to me.

In order to understand the solution, let’s go over some details of the systems and environment we are working with. The service is running on a macOS (Sequoia) client. Docker is being run via Lima. Lima has been configure to bind port forwards to a loopback alias 127.0.0.3. The remote system is Linux and the ssh daemon does not have GatewayPorts enabled.

With details out of the way, let’s get the experiment setup.

Start Nginx container #

docker run -d --rm -p 8000:80 nginx

Verify that nginx is running and response:

curl -l 127.0.0.3:8000

Forward local port to remote host #

This is a simple ssh command, so let’s have a see and then break it down:

ssh -R 44216:127.0.0.3:8000 remotehost

Breaking down the command #

-R - Used to specify remote sockets, in our case a remote port, will be forwarded to the client/local side. Args following flag configures the specifics.

44216 - Remote port, only accessible on the remote host via the loopback interface.

: - Delineates remote parameters from local parameters. Left side being the remote declarations, while the right side being the local.

127.0.0.3:8000 - IP and port of service running on client host.

Expose port on remote host on all interfaces #

If on the remote sshd daemon the GatewayPorts option is set to yes, what follows should not be required. On the other hand if the option is set to no, we will use gost’s PortForwarding feature to expose the forwarded port: 44216.

If you have been following along at this point nginx should be accessible on the remote host via the loopback interface on port 44216. You can confirm by running:

curl -L localhost:44216

Now, we will expose the service by running a forwarding listener that listens on all interfaces:

gost -L tcp://:44217/127.0.0.1:44216

At this point the service running on the client should be accessible on any routable IP of the remote host.