mirror of
https://github.com/zenkiet/traefik-tunnel-expose.git
synced 2025-12-08 06:48:28 +07:00
Exposing internal services securely via Traefik Proxy & Cloudflare Tunnel
https://hub.docker.com/r/zenkiet/traefik-tunnel-expose
| .github/workflows | ||
| assets/images | ||
| conf.d | ||
| config | ||
| scripts | ||
| ssl | ||
| .dockerignore | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| env.example | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
🚀 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
CF_ZONE_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
CF_API_EMAIL=kietgolx65234@gmail.com
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