Publish a NAS web app over HTTPS without router port forwarding
Run ClientProxy on your NAS to make a local HTTP web app available through a public HTTPS address. The NAS opens an outbound tunnel to the proxy, which forwards visitors' requests to your app.
This guide starts with a website or app you already run on the NAS. The Synology path uses a DSM 7 package; the other path uses Docker Compose on a NAS with Docker support.
What you need
- A working HTTP web app on your NAS, and its local port.
- A ClientProxy account, tunnel, and assigned product that permits the tunnel to run.
- For Synology: DSM 7 and a compatible ClientProxy package.
- For Docker: a NAS with Docker/Compose support, such as a suitably configured QNAP, TrueNAS SCALE, Unraid, or OpenMediaVault system.
Use a small website or an app with its own login for your first test. Anyone with the public URL can reach the published service; the tunnel API key authenticates the tunnel client, not visitors to your app.
1. Check your app locally
Open the app's HTTP address from your home network, for example:
http://192.168.1.20:8080
Here 192.168.1.20 is the NAS address and 8080 is the app's HTTP port. Replace both with your values. If the app runs in a container, use the port published on the NAS host.
The current tunnel client connects to backends using plain HTTP. Choose the app's HTTP port; visitors will use HTTPS at the public proxy.
2. Create a tunnel
In the ClientProxy dashboard:
- Open Client Tunnels and create a tunnel, for example
My NAS website. - Choose an available proxy server.
- Use Assign Product to assign an eligible product to the tunnel.
- Copy the tunnel's Tunnel ID and your subscription's API Key.
Keep those credentials private. Choose the API region used for your setup:
| Region | API URL |
|---|---|
| Europe | https://api-eu.clientproxy.io/api |
| United States | https://api-us.clientproxy.io/api |
| Asia | https://api-asia.clientproxy.io/api |
3A. Install on Synology DSM 7
- Download the DSM 7
.spkpackage from the tunnel-client releases. - In DSM, open Package Center → Manual Install and select the file.
- Follow the installation wizard. Enter the API region, Tunnel ID, and API Key when prompted.
- Confirm that clientproxy.io Tunnel is running.
Synology documents uploading .spk files through Manual Install in its Package Center guide.
The ClientProxy package starts the tunnel client after installation and on boot. Continue to step 4.
3B. Install with Docker Compose
Create a Compose project using your NAS's supported Compose interface. Paste the following configuration and replace the two credential placeholders:
services:
tunnel-client:
image: ghcr.io/clientproxy-io/tunnel-client:latest
restart: unless-stopped
network_mode: host
environment:
TUNNEL_API_URL: https://api-eu.clientproxy.io/api
TUNNEL_ID: YOUR_TUNNEL_ID
TUNNEL_API_KEY: YOUR_API_KEY
On a system with the Docker Compose CLI, save this as compose.yaml and run:
docker compose up -d
docker compose logs --tail=50 tunnel-client
With Linux host networking, the tunnel client can reach the NAS's published HTTP ports through 127.0.0.1. This container needs no incoming port mapping. Restrict access to the Compose file because it contains your API key.
4. Map a public domain to the app
In Client Tunnels, open Domains for your tunnel and choose Add Domain.
- Select Auto-generate default domain for the first test.
- Set Local IP:port to
127.0.0.1:8080, replacing8080with your app's HTTP port. - Save the mapping and copy the generated domain.
127.0.0.1 means the machine running the tunnel client. It works for the Synology package and the Linux host-networked container above if the app listens on loopback or all host interfaces. If the app listens only on the NAS's LAN address, use that address instead.
For a different device on your network, use that device's LAN IP and HTTP port, for example 192.168.1.42:80. Reserve that address in your router's DHCP settings.
Restart the Synology package, or run docker compose restart tunnel-client, to load the new mapping immediately.
5. Verify access from outside your network
Turn off Wi-Fi on your phone and open https://YOUR_GENERATED_DOMAIN. You should see the same app you opened locally.
Check an actual page or app action, not just the login screen. Apps that require WebSockets need separate compatibility testing: the current tunnel client does not relay WebSocket upgrades.
Troubleshooting
| Problem | What to check |
|---|---|
| App does not open locally | Fix the app or its published port before debugging the tunnel |
| Tunnel does not connect | Check region, Tunnel ID, API Key, assigned product, and client logs |
| Public page reports a backend error | Verify the backend address is reachable from the tunnel client's network context |
| Plain HTTP sent to HTTPS port | Map the HTTP port instead of the HTTPS port |
| Browser redirects to a local address or wrong port | Configure the app's external URL/reverse-proxy settings |
| Old mapping remains active | Restart the tunnel client |
| Page loads but live updates fail | Check whether the app depends on WebSockets |
To stop publishing, stop the package/container or remove the domain mapping.
About publishing the NAS administration interface
The main walkthrough publishes a web app. If you also expose DSM itself, use its configured HTTP port, normally 5000, and test its redirect settings: redirecting visitors to the NAS HTTPS port can break the public URL. Review account authentication and lockout behavior before using this as an everyday administration route. A public HTTPS address does not add a visitor access policy.