Expose Your Home Lab Web Server Securely Without Port Forwarding (Cloudflare Tunnel + Docker)

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.