Skip to content

zenkiet/traefik-tunnel-expose

Repository files navigation

🚀 Traefik Tunnel Expose

Icon

Docker Image Docker Pulls Docker Image Version GitHub Workflow Status License GitHub stars

🌐 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

🐳 Docker Hub🚀 Quick Start💬 Discussions


📋 Table of Contents


✨ Features

Core Features

  • 🔄 Traefik v3 - Modern reverse proxy with service discovery
  • ☁️ Cloudflare Tunnel - Secure tunneling without port forwarding
  • 🔒 Auto SSL - Let's Encrypt certificates with DNS challenge
  • 🤖 DNS Management - Automatic subdomain creation
  • 🔧 Hot Reload - Zero-downtime configuration updates
  • 📱 Gotify Notification - Send notifications to your phone
  • 📦 Multi-architecture - Build for multiple platforms
  • 🔄 Auto Update - Update latest version automatically

🛡️ Security & Performance

  • 📊 Real-time Dashboard - Monitor services and metrics
  • 🔐 End-to-end Encryption - Secure tunnel connection
  • 🚫 No Port Opening - Firewall-friendly architecture
  • Load Balancing - Distribute traffic efficiently
  • 🎯 Middleware Support - Rate limiting, headers, auth
  • 📝 Comprehensive Logging - Access and error logs
  • 🐳 Lightweight - Alpine Linux based container

🏗️ 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]
Loading

Flow Overview:

  1. 🌍 Internet Traffic → Cloudflare CDN for caching and protection
  2. 🔒 Secure Tunnel → Encrypted connection through Cloudflare Tunnel
  3. 🚀 Traefik Proxy → Intelligent routing to your services
  4. 🤖 Automatic SSL → Let's Encrypt certificates via DNS challenge
  5. 📝 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


⚙️ 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

  1. 🌐 Navigate to Cloudflare API Tokens
  2. 🔧 Create Custom Token with permissions:
Scope Resource Permission
Zone Zone:Read Specific zones
Zone DNS:Edit Specific zones
Account Cloudflare Tunnel:Edit Specific accounts
  1. 📋 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

  1. Go to Zero TrustNetworksTunnels
  2. Create new tunnel
  3. 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

  1. 🔍 Search existing issues
  2. 📝 Create detailed bug report
  3. 🏷️ Use appropriate labels

✨ Feature Requests

  1. 💡 Discuss in GitHub Discussions
  2. 📋 Create feature request issue
  3. 🚀 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
Traefik
Reverse Proxy
Cloudflare
Cloudflare
Tunnel & Security
Alpine
Alpine Linux
Lightweight OS
Docker
Docker
Containerization

🎯 Special Thanks

  • Proxmox - For excellent virtualization platform
  • chatgpt - For best research
  • Open Source Community

📞 Support

🤝 Get Help & Connect

Email GitHub Issues Discussions Docker Hub

📊 Project Stats

GitHub contributors GitHub last commit GitHub repo size


⭐ If this project helped you, please consider giving it a star! ⭐

Made with ❤️ by ZenKiet