Expose Your Home Lab Web Server Securely Without Port Forwarding (Cloudflare Tunnel + Docker)
One of the challenges of running services from a home lab is exposing applications to the internet safely. Traditionally, this meant opening ports on the router and forwarding traffic to internal servers. While that works, it also exposes your network directly to the public internet.
A better approach is to use Cloudflare Tunnel. Cloudflare Tunnel allows a server inside your network to create a secure outbound connection to Cloudflare. Once the connection is established, Cloudflare can route traffic from your public domain to services running inside your home lab without requiring any open inbound ports.
For this project, I set up a Cloudflare Tunnel running inside a Docker container to publish a Ghost website hosted in my lab.
How Cloudflare Tunnel Works
Cloudflare Tunnel uses a small connector application called cloudflared. Instead of waiting for inbound connections, the connector creates an outbound encrypted tunnel from your server to Cloudflare’s edge network.
Once the tunnel is active, Cloudflare associates a domain name with the internal service running on your server.
The traffic flow looks like this:
Internet
↓
Cloudflare
↓
Cloudflare Tunnel (cloudflared)
↓
Reverse Proxy (Nginx)
↓
Application (Ghost)
↓
Database (MariaDB)
Because the tunnel is outbound only, the home network remains protected behind the firewall.
Creating the Tunnel in Cloudflare
The first step is creating a tunnel in the Cloudflare Zero Trust dashboard.
Inside the Cloudflare dashboard:
1. Navigate to Zero Trust
2. Select Access → Tunnels
3. Create a new tunnel
4. Give the tunnel a name
5. Choose Docker as the connector environment
Cloudflare generates a tunnel token that allows the container to authenticate with the Cloudflare network.
Running cloudflared in Docker
Once the tunnel token is generated, the connector can be started in Docker.
Example container configuration:
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=YOUR_TUNNEL_TOKEN
When the container starts, it automatically connects to Cloudflare and registers the tunnel.
You can confirm the tunnel is active by checking the container logs.
Connecting the Tunnel to an Application
After the tunnel is running, Cloudflare needs to know which internal service it should route traffic to.
Inside the Cloudflare dashboard, create a public hostname that maps the domain to an internal service.
Domain: overlycomplicated.com
Service: http://nginx🕗
In this setup, the tunnel forwards requests to an Nginx reverse proxy container running on the Docker network.
The reverse proxy then passes requests to the Ghost application container.
Why Use a Reverse Proxy
Using Nginx between the tunnel and the application provides flexibility and control.
The reverse proxy can handle:
• application routing
• header forwarding
• caching
• security headers
• request logging
This keeps the application container simple while allowing the proxy layer to handle web server responsibilities.
Advantages of Cloudflare Tunnel
Running a Cloudflare Tunnel in a home lab has several advantages.
First, it eliminates the need to open ports on the router. This reduces the attack surface of the network.
Second, Cloudflare automatically provides HTTPS encryption for the public domain. TLS certificates are managed by Cloudflare and require no manual configuration on the home server.
Third, the tunnel integrates with other Cloudflare security features such as rate limiting, web application firewall rules, and access controls.
Finally, because the connector runs in a container, it can be easily restarted, updated, or moved to another host.
Final Thoughts
Using Cloudflare Tunnel together with Docker provides a clean and secure way to expose services from a home lab. The server initiates the connection to Cloudflare, the network stays protected behind the firewall, and applications can be published securely with minimal configuration.
For anyone running personal infrastructure at home, this approach offers a simple alternative to traditional port forwarding while adding an extra layer of protection through Cloudflare’s network.