Ultimate Guide: Setting Up Traefik as a Reverse Proxy in Docker (with Let’s Encrypt, Cloudflare, and Secure Services)

Introduction: Why a Reverse Proxy?

In modern self-hosted environments, you’re often running multiple services — like a photo gallery (e.g., Immich), media server (e.g., Jellyfin), and dashboards. If all these services expose themselves directly on different ports, things quickly get messy. Enter the reverse proxy.

A reverse proxy routes incoming HTTP/HTTPS traffic to the right container based on domain or path. It allows you to:

  • Use pretty domain names like photos.example.com
  • Enforce HTTPS with Let’s Encrypt
  • Route requests internally by hostname instead of IP and port
  • Apply access control, rate limits, or basic authentication centrally

And Traefik does all that, automatically, with minimal config.


🚀 Why Traefik Over Nginx?

While Nginx is popular and powerful, it’s static by default. Every new service requires you to edit config files and reload.

Traefik, on the other hand:

  • Automatically discovers Docker containers
  • Supports dynamic routing using Docker labels
  • Comes with built-in Let’s Encrypt integration
  • Has a web dashboard to visualize routes
  • Requires minimal config

Traefik was designed for containerized environments from the start.


⚙️ How Traefik Works Internally

Traefik is composed of three key concepts:

1. EntryPoints

These define which ports Traefik listens on (e.g., :80, :443). You can think of these as your public gateways.

2. Routers

Routers match incoming requests (host, path, method) and forward them to services. They also define TLS settings and middleware.

3. Services

These are the actual Docker containers (or upstream backends) that respond to the requests.

4. Middlewares (Optional)

These are like plugins: things that transform requests (e.g., strip path, redirect HTTP to HTTPS, basic auth, etc).


📦 Installing Traefik with Docker Compose

Let’s build a fully functional Traefik setup using Docker Compose.

docker-compose.yml
version: '3.9'

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    command:
      - --api.dashboard=true
      - --api.insecure=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --certificatesresolvers.cloudflare.acme.dnschallenge=true
      - --certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare
      - [email protected]
      - --certificatesresolvers.cloudflare.acme.storage=/letsencrypt/acme.json
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    environment:
      - [email protected]
      - CF_API_KEY=your_cloudflare_api_key
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=cloudflare"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$6yLkU..."
      - "traefik.http.routers.traefik.middlewares=traefik-auth"

You also need to create the directory ./letsencrypt and touch acme.json with permissions 600.

mkdir letsencrypt
chmod 600 letsencrypt/acme.json

🔐 Securing the Dashboard

Never expose the dashboard to the public without auth. Use basic auth like above or restrict access to specific IPs.

Alternative example:

- "traefik.http.routers.traefik.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.usersfile=/users.htpasswd"

Generate passwords with:

htpasswd -nb admin strongpassword

🌍 Deploying a Sample Service Behind Traefik

services:
  whoami:
    image: traefik/whoami
    container_name: whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=cloudflare"

Start both containers:

docker compose up -d

Now visit https://whoami.yourdomain.com — you’ll see the container response.


🔧 Additional Features to Explore

  • Middleware: redirect, stripPrefix, basicAuth
  • Rate-limiting
  • Retry and load balancing
  • Redirect HTTP to HTTPS automatically
  • Wildcard TLS certificates
  • Forward headers to preserve real IP

📘 Conclusion

Traefik makes deploying, securing, and managing multiple services in Docker easy and dynamic. With a few Docker labels and one compose file, you get:

  • Auto-routing by domain
  • HTTPS with Let’s Encrypt
  • Centralized auth and middleware
  • Visibility via dashboard

Traefik replaces hours of nginx tinkering with a declarative, scalable, and elegant solution.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *