π Traefik Tunnel Expose
π A powerful Docker solution combining Traefik reverse proxy with Cloudflare Tunnel Expose your local services to the internet securely with automatic SSL and DNS management
π Table of Contents
- β¨ Features
- ποΈ Architecture
- π Quick Start
- βοΈ Service Configuration
- π Cloudflare Setup
- π§ Advanced Configuration
- π³ Docker Usage
- π€ Contributing
- π License
- π Acknowledgments
- π Support
β¨ Features
β‘ Core Features
|
π‘οΈ Security & Performance
|
ποΈ Architecture
graph TB
A[π Internet] --> B[βοΈ Cloudflare CDN]
B --> C[π Cloudflare Tunnel]
C --> D[π Traefik Proxy]
D --> E[π± Your Services]
F[π€ DNS API] --> G[π Auto DNS Records]
H[π Let's Encrypt] --> I[π SSL Certificates]
Flow Overview:
- π Internet Traffic β Cloudflare CDN for caching and protection
- π Secure Tunnel β Encrypted connection through Cloudflare Tunnel
- π Traefik Proxy β Intelligent routing to your services
- π€ Automatic SSL β Let's Encrypt certificates via DNS challenge
- π DNS Management β Auto-create subdomains for services
π Quick Start
π¦ Prerequisites
- π³ Docker & Docker Compose
- βοΈ Cloudflare account with domain
- π Cloudflare API tokens
1οΈβ£ Clone Repository
git clone https://github.com/zenkiet/traefik-tunnel-expose.git
cd traefik-tunnel-expose
2οΈβ£ Environment Setup
# Copy example environment file
cp env.example .env
# Edit configuration
nano .env # or your preferred editor
π§ Required Environment Variables
# User/Group Identifiers
# These help avoid permission issues between host and container
PUID=1000
PGID=1000
UMASK=022
# Container name prefix
CONTAINER_PREFIX=
# Paths for persistent data
CONFIG_PATH=/opt/appdata/config
DATA_PATH=/opt/appdata/data
# Container settings
TZ=Asia/Ho_Chi_Minh
RESTART_POLICY=unless-stopped
NETWORK_MODE=bridge
# ===== REQUIRED =====
HOST=127.0.0.1
BASE_DOMAIN=zenkiet.dev
TAG=latest
# =============================================================================
# AUTO UPDADTE
# =============================================================================
AUTO_UPDATE=TRUE
GOTIFY_URL=
GOFITY_TOKEN=
# =============================================================================
# CLOUDFLARE TUNNEL
# =============================================================================
CF_ENABLED=true
CLOUDFLARE_DNS_API_TOKEN=your_cloudflare_zone_api_token_here
CF_ZONE_ID=your_cloudflare_zone_id
CF_TUNNEL_ID=your_cloudflare_tunnel_id
CF_ACCOUNT_ID=your_cloudflare_account_id
CF_TUNNEL_SECRET=your_cloudflare_account_secret_id
[email protected]
ACME_CA_SERVER=https://acme-staging-v02.api.letsencrypt.org/directory
#! For production, use:
# ACME_CA_SERVER=https://acme-v02.api.letsencrypt.org/directory
3οΈβ£ Deploy services
# π Start services
make up
# π Check status
make status
4οΈβ£ Access Dashboard
- ποΈ Traefik Dashboard: http://127.0.0.1:8080
- π Your Services: https://service.yourdomain.com
βοΈ Service Configuration
π Adding New Services
Create configuration files in conf.d/ directory:
π Example: conf.d/myapp.yml
# π HTTP Router and Service Configuration
http:
routers:
myapp:
rule: 'Host(`myapp.yourdomain.com`)'
service: 'myapp-service'
entrypoints:
- websecure
tls:
certResolver: cloudflare
middlewares:
- default-headers
- rate-limit
services:
myapp-service:
loadBalancer:
servers:
- url: 'http://myapp-container:3000'
healthCheck:
path: '/health'
interval: '30s'
middlewares:
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
rate-limit:
rateLimit:
burst: 100
average: 50
π§ Advanced Service Configuration
π± Web Application with Authentication
http:
routers:
webapp-secure:
rule: 'Host(`webapp.yourdomain.com`)'
service: 'webapp'
entrypoints:
- websecure
tls:
certResolver: cloudflare
middlewares:
- auth
- secure-headers
services:
webapp:
loadBalancer:
servers:
- url: 'http://webapp:8080'
middlewares:
auth:
basicAuth:
users:
- 'admin:$2y$12$...' # Generated with htpasswd -nb admin <password>
secure-headers:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlAllowOriginList:
- https://yourdomain.com
accessControlMaxAge: 100
hostsProxyHeaders:
- 'X-Forwarded-Host'
ποΈ Database Service (Internal Only)
http:
routers:
db-admin:
rule: 'Host(`db.yourdomain.com`)'
service: 'database-admin'
entrypoints:
- websecure
tls:
certResolver: cloudflare
middlewares:
- ip-whitelist
- auth
services:
database-admin:
loadBalancer:
servers:
- url: 'http://adminer:8080'
middlewares:
ip-whitelist:
ipWhiteList:
sourceRange:
- '192.168.1.0/24'
- '10.0.0.0/8'
π Cloudflare Setup
1οΈβ£ API Token Creation
- π Navigate to Cloudflare API Tokens
- π§ Create Custom Token with permissions:
| Scope | Resource | Permission |
|---|---|---|
| Zone | Zone:Read | Specific zones |
| Zone | DNS:Edit | Specific zones |
| Account | Cloudflare Tunnel:Edit | Specific accounts |
- π Copy the generated token
2οΈβ£ Cloudflare Tunnel Setup
π₯οΈ Using cloudflared CLI (Recommended here)
# π₯ Install cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb
# π Authenticate with Cloudflare
cloudflared tunnel login
# π Create tunnel
cloudflared tunnel create my-tunnel
# π« Generate tunnel token
cloudflared tunnel token my-tunnel
# π Print tunnel info
cloudflared tunnel info my-tunnel
{
"Tunnel": "your-tunnel-id", # CF_TUNNEL_ID
"AccountTag": "your-account-tag", # CF_ACCOUNT_ID
"TunnelToken": "your-tunnel-token" # CF_TUNNEL_TOKEN
}
π Method 2: Using Cloudflare Dashboard
- Go to Zero Trust β Networks β Tunnels
- Create new tunnel
- Install connector and copy the token
3οΈβ£ Generate credentials file
cloudflared tunnel token --cred-file ./credentials.json <TUNNEL_ID>
{
"Tunnel": "your-tunnel-id", # CF_TUNNEL_ID
"AccountTag": "your-account-tag", # CF_ACCOUNT_ID
"TunnelToken": "your-tunnel-token" # CF_TUNNEL_TOKEN
}
4οΈβ£ DNS Configuration
The service automatically creates DNS records, but you can manually verify:
# π Check DNS records
dig myapp.yourdomain.com
nslookup myapp.yourdomain.com
π Management Commands
Using make help to see all commands or make <command> to run a specific command.
π§ Advanced Configuration
ποΈ Custom Traefik Configuration
β‘ Custom Traefik Configuration
Create config/traefik-dynamic.yml for advanced settings:
# π TLS Configuration
tls:
options:
default:
sslProtocols:
- 'TLSv1.2'
- 'TLSv1.3'
cipherSuites:
- 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'
- 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305'
- 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
# π Global Middlewares
http:
middlewares:
secure-headers:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
hostsProxyHeaders:
- 'X-Forwarded-Host'
referrerPolicy: 'same-origin'
π Performance Optimization
β‘ Performance Tuning
services:
traefik-tunnel:
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
healthcheck:
test: ['CMD', 'traefik', 'healthcheck']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
π³ Docker Usage
π₯ Pull from Docker Hub
# π― Latest version
docker pull zenkiet/traefik-tunnel-expose:latest
# π·οΈ Specific version
docker pull zenkiet/traefik-tunnel-expose:v1.0.0
# π Check image info
docker inspect zenkiet/traefik-tunnel-expose:latest
π Quick Run (Standalone)
docker run -d \
--name traefik-tunnel \
--restart unless-stopped \
-p 80:80 \
-p 443:443 \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ./data:/data \
-v ./config:/etc/traefik \
-e CF_API_TOKEN=your_token \
-e CF_ZONE_ID=your_zone_id \
zenkiet/traefik-tunnel-expose:latest
π€ Contributing
We welcome contributions! Here's how you can help:
π Bug Reports
- π Search existing issues
- π Create detailed bug report
- π·οΈ Use appropriate labels
β¨ Feature Requests
- π‘ Discuss in GitHub Discussions
- π Create feature request issue
- π Submit pull request
π οΈ Development Workflow
# π΄ Fork and clone
git clone https://github.com/your-username/traefik-tunnel-expose.git
cd traefik-tunnel-expose
# πΏ Create feature branch
git checkout -b feature/amazing-feature
# π§ Make changes and test
docker-compose up -d
# β
Commit changes
git commit -m "β¨ Add amazing feature"
# π Push and create PR
git push origin feature/amazing-feature
π Commit Convention
We use Conventional Commits:
β¨ feat:New featuresπ fix:Bug fixesπ docs:Documentationπ¨ style:Code formattingβ»οΈ refactor:Code restructuringβ‘ perf:Performance improvementsβ test:Testingπ§ chore:Maintenance
π License
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2025 ZenKiet
π Acknowledgments
This project wouldn't be possible without these amazing technologies:
|
Traefik Reverse Proxy |
Cloudflare Tunnel & Security |
Alpine Linux Lightweight OS |
Docker Containerization |
π― Special Thanks
π Support
β If this project helped you, please consider giving it a star! β
Made with β€οΈ by ZenKiet