Expose a Docker Compose service
Expose a Docker Compose service to the internet with a Horizon tunnel, using the service's published port.
Share a web service from a Compose project, with an HTTPS URL. You run hrzn on your host, not in a container.
Before you begin
- Node.js 18 or later
- A Horizon account and the CLI on your host (see Getting started)
- A reserved subdomain for
-s. Reserve one on the Subdomains page. - Docker Compose, and a service whose app listens on port 3000
Publish the port
Add a ports entry to the service. Write it as a quoted string, as Docker recommends, to avoid a YAML parsing conflict.
services:
web:
image: my-image
ports:
- "3000:3000"The short syntax is [HOST:]CONTAINER. To keep the port off your network, use "127.0.0.1:3000:3000". The Horizon CLI still reaches it, because it runs on your host.
Start the service.
docker compose up -dStart a tunnel
Use -s with a subdomain you reserved. Reserved subdomains are a paid feature, see Pricing.
hrzn tunnel http://localhost:3000 -s my-appHORIZON: Tunnel connected
URL https://my-app.hrzn.run (reserved)
Forwarding http://localhost:3000
Request log https://hrzn.run/dashboard/tunnels/my-appKeep this terminal open.
Open the URL
Open https://my-app.hrzn.run. A first-time browser visitor sees the Before you continue page. Select Continue to site.
Check it works
The Horizon terminal prints a line per request:
GET 200 /Troubleshooting
Bind for 0.0.0.0:3000 failed: port is already allocated
Another container or process holds host port 3000. Change the left side of the entry, for example "3001:3000", and tunnel to http://localhost:3001.
Nothing reaches your app
- Check that the Horizon terminal is still running. If its last line is
Connection lost. Reconnecting…, wait forReconnected. - Run
curl http://localhost:3000on the host. If it fails, the problem is the service, not the tunnel. Rundocker compose psand check the ports column. - A service without a
portsentry isn't reachable from your host. Tunnel only to a service that publishes a port.
The URL changed after a restart
You started the tunnel without -s, so Horizon gave you a new random subdomain. Restart with -s my-app.
Next steps
- Read Docker's
portsreference.
Expose a Docker container
Expose a Docker container running a web app to the internet with a Horizon tunnel, using a published port such as -p 3000:3000.
Expose a site behind local NGINX
Expose a site served by local NGINX through a Horizon tunnel, including a server_name virtual host such as mysite.test.