Skip to content

Cloudflare Tunnel with Docker — Quick Setup

DodaTech 4 min read

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

  1. Why should you use the restart: unless-stopped policy when running cloudflared in Docker?
  2. What is the advantage of using tunnel tokens over credentials files for Docker deployments?
  3. 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

Does the Docker tunnel image auto-update?

The Cloudflare/cloudflared Docker image is updated regularly, but the container does not auto-update by default. You must pull the new image and recreate the container. Use a CI/CD pipeline or a tool like Watchtower to automate this if needed. Pin to a specific version tag in production to avoid unexpected changes.

Can I run multiple tunnel containers on the same host?

Yes. Each tunnel container needs a unique name and its own credentials directory or token. You can run multiple tunnels on the same host to separate traffic for different environments or applications. Each tunnel maintains its own set of connections to Cloudflare's edge.


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