Welcome to this comprehensive guide on setting up a secure connection between Cloudflare Tunnel and Traefik using Docker, enabling wildcard domain access for your applications. This tutorial is tailored for users who want to expose their services (e.g., a web server or Traefik dashboard) behind a reverse proxy, leveraging Cloudflare’s zero-trust security. By the end, you’ll have a fully functional setup accessible via a wildcard domain (e.g., *.yourdomain.id). Let’s get started!
Prerequisites
Before diving in, ensure you have the following:
- A server with Docker and Docker Compose installed (e.g., Ubuntu 22.04).
- A domain registered with Cloudflare (e.g.,
yourdomain.id) with DNS management configured. - Basic knowledge of terminal commands and YAML configuration files.
- Access to Cloudflare Dashboard with appropriate permissions.
Step 1: Register a New Cloudflare Tunnel via Docker
Cloudflare Tunnel allows you to securely expose your local services to the internet without opening public ports. Here’s how to create a new tunnel using Docker.
- Log in to Cloudflare:
- Run the following command to authenticate with Cloudflare and download a certificate:
bash docker run --rm -it -v ~/.cloudflared:/home/nonroot/.cloudflared cloudflare/cloudflared:latest tunnel login - A browser window will open. Log in to your Cloudflare account and select your domain (
yourdomain.id). This will download acert.pemfile to~/.cloudflared/.
- Create a New Tunnel:
- Create a tunnel named
traefik-tunnel:bash docker run --rm -it -v ~/.cloudflared:/home/nonroot/.cloudflared cloudflare/cloudflared:latest tunnel create traefik-tunnel - Note the Tunnel ID (e.g.,
a1b2c3d4-e5f6-7890-abcd-ef1234567890) displayed in the output. This ID is unique to your tunnel.
- Move the Credentials File:
- The command generates a
tunnel-id.jsonfile (e.g.,a1b2c3d4-e5f6-7890-abcd-ef1234567890.json) in~/.cloudflared/. Move it to a secure location for your Docker container:bash sudo mkdir -p /etc/cloudflared sudo mv ~/.cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json /etc/cloudflared/ - Set secure permissions:
bash sudo chmod 600 /etc/cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json
Step 2: Configure Cloudflare Tunnel with Wildcard Domain
Now, set up the tunnel to route traffic for a wildcard domain (e.g., *.yourdomain.id) to your Traefik instance.
- Create
config.ymlfor Cloudflared:
- Create a file named
config.ymlin a directory (e.g.,~/cloudflared/):bash mkdir -p ~/cloudflared nano ~/cloudflared/config.yml - Add the following configuration:
tunnel: traefik-tunnel credentials-file: /etc/cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json ingress: - hostname: "*.yourdomain.id" service: http://traefik:80 - service: http_status:404 - Save and exit (
Ctrl+O,Enter,Ctrl+X).
- Create
docker-compose.ymlfor Cloudflared:
- In the same directory (
~/cloudflared/), create adocker-compose.yml:bash nano ~/cloudflared/docker-compose.yml - Add the following content:
yaml version: "3.9" # Note: This attribute is obsolete and can be removed in newer versions services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared restart: unless-stopped networks: - traefik-network volumes: - ./config.yml:/etc/cloudflared/config.yml - /etc/cloudflared:/etc/cloudflared command: tunnel --no-autoupdate run networks: traefik-network: external: true - Save and exit.
- Start the Cloudflared Container:
- Launch the container:
bash cd ~/cloudflared docker-compose up -d - Check the logs to ensure the tunnel is running:
bash docker logs cloudflared - Look for lines like
Registered tunnel connectionto confirm connectivity.
- Add DNS Record in Cloudflare:
- Go to Cloudflare Dashboard > DNS > Records.
- Add a new record:
- Type:
CNAME - Name:
* - Target:
a1b2c3d4-e5f6-7890-abcd-ef1234567890.cfargotunnel.com(replace with your Tunnel ID) - Proxied: Enabled
- Type:
- Save the record. This will enable wildcard subdomain access (e.g.,
traefik.yourdomain.id,nginx.yourdomain.id).
Step 3: Set Up Traefik with Docker
Traefik will act as your reverse proxy, routing traffic from Cloudflare Tunnel to your services.
- Create a Network:
- Create a custom Docker network for Traefik and other services:
bash docker network create traefik-network
- Create
docker-compose.ymlfor Traefik:
- In a new directory (e.g.,
~/traefik/), create adocker-compose.yml:bash mkdir -p ~/traefik nano ~/traefik/docker-compose.yml - Add the following content:
yaml version: "3.9" # Note: This can be removed to avoid warnings services: traefik: image: traefik:v3.0 container_name: traefik restart: unless-stopped networks: - traefik-network ports: - "80:80" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro labels: - "traefik.enable=true" - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.yourdomain.id`)" - "traefik.http.routers.traefik-dashboard.entrypoints=web" - "traefik.http.routers.traefik-dashboard.service=api@internal" - "traefik.http.routers.traefik-dashboard.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=admin:$$2y$$05$$Tgn5tPGcytErBYz6h.RoQOZaVgyUvazrmgFrHpUnFahYq0LlRInaW" # Replace with your hashed password networks: traefik-network: external: true - Note: Replace the
basicauth.usersvalue with a hashed password (generate usinghtpasswdor online tools). Example command to generate:bash htpasswd -nb admin yourpassword
- Start Traefik:
- Launch the Traefik container:
bash cd ~/traefik docker-compose up -d - Check the logs to ensure Traefik is running:
bash docker logs traefik
Step 4: Add a Test Service (e.g., Nginx)
Let’s add a simple Nginx service to test the wildcard domain setup.
- Create
docker-compose.ymlfor Nginx:
- In a new directory (e.g.,
~/nginx/), create adocker-compose.yml:bash mkdir -p ~/nginx nano ~/nginx/docker-compose.yml - Add the following content:
yaml version: "3.9" # Note: Can be removed services: nginx: image: nginx:alpine container_name: nginx-test restart: unless-stopped networks: - traefik-network volumes: - ./html:/usr/share/nginx/html:ro labels: - "traefik.enable=true" - "traefik.http.routers.nginx.rule=Host(`nginx.yourdomain.id`)" - "traefik.http.routers.nginx.entrypoints=web" - "traefik.http.routers.nginx.service=nginx-svc" - "traefik.http.services.nginx-svc.loadbalancer.server.port=80" networks: traefik-network: external: true - Create a simple HTML file:
bash mkdir -p ~/nginx/html echo "<h1>Welcome to Nginx via Cloudflare Tunnel!</h1>" > ~/nginx/html/index.html
- Start Nginx:
- Launch the Nginx container:
bash cd ~/nginx docker-compose up -d - Check the logs:
bash docker logs nginx-test
Step 5: Test the Connection
- Wait for DNS Propagation:
- After adding the
CNAMErecord, wait for DNS propagation (usually a few minutes, depending on TTL). You can check with:bash dig nginx.yourdomain.id - Look for a
CNAMErecord pointing to your Tunnel ID.
- Access the Services:
- Open a browser and visit:
https://traefik.yourdomain.id(enteradminand your password for the dashboard).https://nginx.yourdomain.id(should display the welcome message).
- Use
https://as Cloudflare Tunnel handles SSL.
Troubleshooting
- DNS Not Propagating: Clear local cache with
sudo systemctl restart networkingor usedig @8.8.8.8 nginx.yourdomain.id. - 502 Bad Gateway: Check Traefik and Cloudflared logs (
docker logs traefik,docker logs cloudflared) and ensure ports are open. - Access Denied: Verify
CNAMEis correctly set and proxied in Cloudflare.
Conclusion
Congratulations! You’ve successfully set up Cloudflare Tunnel and Traefik with Docker to handle wildcard domain access. This setup secures your services and allows easy scaling with additional subdomains. For further enhancements (e.g., multiple services or HTTPS in Traefik), feel free to explore the Cloudflare and Traefik documentation or reach out for more guidance.
Happy tunneling! 🚀
Let me know in the comments if you encounter issues or need help with advanced configurations!
Related: Cloudflare Implementation Roadmap: Key Dimensions, Priorities, and Step‑by‑Step .
Related: How to Install OpenClaw on Ubuntu Server: A Step-by-Step Guide.
Discover more from Susiloharjo
Subscribe to get the latest posts sent to your email.