Cloudflare Tunnel with Docker — Quick Setup
In this tutorial, you'll learn about Cloudflare Tunnel with Docker. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Cloudflare Tunnel with Docker lets you run the cloudflared client inside a container, keeping your host system clean and making tunnel deployment as simple as a single docker run command.
What You Will Learn
You will learn how to run Cloudflare Tunnel as a Docker container, configure it using environment variables and config files, and deploy multi-service tunnels using Docker Compose.
Why It Matters
Running cloudflared inside Docker isolates the tunnel process from your host system, simplifies updates through container image tags, and integrates naturally with containerised application stacks.
Real-World Use Case
A development team running a Microservices Architecture on a single Docker host deployed Cloudflare Tunnel as a sidecar container. Each microservice got its own tunnel container, allowing the team to expose development versions of services without modifying firewall rules or DNS configuration manually.
Tunnel Architecture with Docker
Cloudflared runs in a container alongside your application, routing traffic from Cloudflare's edge to your containerised services.
flowchart LR A[Internet] -->|HTTPS| B[Cloudflare Edge] B -->|Tunnel| C[cloudflared Container] C -->|localhost:8080| D[App Container 1] C -->|localhost:3000| E[App Container 2] C -->|localhost:80| F[App Container 3]
Quick Start with Docker Run
Run cloudflared as a standalone Docker container with a single command.
# Authenticate first to get the tunnel token
docker run cloudflare/cloudflared tunnel login
# Run the tunnel using the credentials file
docker run -d \
--name cloudflare-tunnel \
-v $HOME/.cloudflared:/etc/cloudflared \
cloudflare/cloudflared tunnel run my-tunnel
Expected output (docker ps):
CONTAINER ID IMAGE COMMAND STATUS NAMES
a1b2c3d4e5f6 cloudflare/cloudflared "cloudflared tunnel..." Up 2 minutes cloudflare-tunnel
Docker Compose Setup
Use Docker Compose to define your tunnel alongside your application containers.
version: "3.8"
services:
tunnel:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel run
volumes:
- ./cloudflared:/etc/cloudflared
networks:
- app-network
web:
image: nginx:alpine
ports:
- "8080:80"
networks:
- app-network
networks:
app-network:
driver: bridge
# Start the stack
docker-compose up -d
# Check tunnel logs
docker-compose logs tunnel
Expected output:
tunnel_1 | 2025-06-23T10:00:00Z INF Starting tunnel tunnelID=abc-123
tunnel_1 | 2025-06-23T10:00:01Z INF Connection established
web_1 | 2025/06/23 10:00:01 [notice] 1#1: start worker processes
Using Tunnel Tokens for Kubernetes-Style Config
Cloudflare Tunnel supports token-based authentication, ideal for ephemeral containers.
# Create a tunnel and get its token
cloudflared tunnel create docker-tunnel
cloudflared tunnel token docker-tunnel > tunnel-token.txt
# Run with token instead of credentials file
docker run -d \
--name cf-tunnel \
cloudflare/cloudflared tunnel --no-autoupdate run --token $(cat tunnel-token.txt)
Expected output:
2025-06-23T10:00:00Z INF Starting tunnel with token
2025-06-23T10:00:01Z INF Connection established connIndex=0
Common Mistakes
| Mistake | Consequence |
|---|---|
| Not persisting credentials volume | Tunnel credentials lost on container restart |
| Forgetting the restart policy | Tunnel stops after host reboot |
| Using latest tag without pinning | Unexpected breaking changes on update |
| Exposing tunnel token in environment variables | Anyone with container access can read the token |
| Running without --no-autoupdate inside Docker | Autoupdate fails due to filesystem permissions |
Practice Questions
- Why should you use the restart: unless-stopped policy when running cloudflared in Docker?
- What is the advantage of using tunnel tokens over credentials files for Docker deployments?
- Why should the cloudflared container share a Docker network with application containers?
Challenge
Create a Docker Compose file that runs three services: a Node.js app on port 3000, a PostgreSQL database, and a Cloudflare Tunnel that exposes only the Node.js app. Use a dedicated Docker network and ensure the database is not accessible through the tunnel. Start the stack and verify the tunnel connects.
Real-World Task
Your team manages a Docker-based staging environment on a single VPS. Deploy Cloudflare Tunnel as a Docker container that routes traffic to three different staging services. Use a single tunnel with multiple ingress rules in a mounted config file. Set up automatic container restart and verify the tunnel survives a Docker daemon restart.
FAQ
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro — security-first tools for the modern web.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro