Back to articles
Technology Insight

Mastering Traefik v3: Automated Docker Reverse Proxy & Let's Encrypt SSL Configuration

June 3, 2026

Introduction to Modern Ingress Management with Traefik v3

In the era of microservices and containerization, managing network traffic efficiently is a foundational requirement for any robust infrastructure. Traditional reverse proxies often require manual configuration updates and service restarts whenever a new container is deployed. Traefik v3 revolutionizes this workflow by acting as an cloud-native, edge router that integrates natively with Docker.

Unlike legacy systems, Traefik constantly listens to the Docker daemon provider API. When a container is spun up or torn down, Traefik dynamically updates its routing rules in real-time without any downtime or manual intervention. Combined with built-in, automated ACME TLS certificate management via Let's Encrypt, Traefik v3 provides an elegant, hands-off solution for securing and routing your containerized business applications. This guide walks you through setting up a production-ready Traefik v3 architecture from scratch.

Core Concepts: EntryPoints, Routers, Middlewares, and Services

Before diving into configuration files, it is vital to understand the foundational architecture of Traefik v3. Traefik processes requests using a clearly defined, modular pipeline:

  • EntryPoints: These define the network ports that Traefik listens on (e.g., port 80 for HTTP and port 443 for HTTPS).
  • Routers: Routers analyze incoming requests reaching an EntryPoint and determine if they match specific rules, such as hostnames (Host(`app.example.com`)) or path prefixes.
  • Middlewares: Components that can tweak a request or response before or after it reaches the backend. Examples include security headers, basic authentication, or automatic HTTP-to-HTTPS redirection.
  • Services: These configure how to reach the actual backend containers that will handle the incoming requests. Traefik automatically manages load balancing across multiple replicas of a service.
Note: Traefik v3 introduces significant performance improvements, native support for HTTP/3, and updated syntax for routing definitions compared to older v2 deployments.

Step 1: Setting Up the Directory Structure and Network

To ensure a clean deployment, create a dedicated directory structure on your host machine. This separation keeps configuration files isolated and persistent storage well-defined.

mkdir -p /opt/traefik/data
touch /opt/traefik/data/traefik.yml
touch /opt/traefik/data/acme.json
chmod 600 /opt/traefik/data/acme.json

CRITICAL SECURITY NOTE: The acme.json file will store your private SSL keys generated by Let's Encrypt. Docker will refuse to use it, or Let's Encrypt validation will fail, if the file permissions are too open. Setting it to chmod 600 ensures that only the file owner can read and write to it.

Next, create a dedicated Docker network. This allows Traefik to communicate securely with other containers while isolating them from the public host network interface.

docker network create traefik-public

Step 2: Crafting the Static Configuration (traefik.yml)

The static configuration defines the core settings of Traefik that do not change frequently, such as entrypoints, provider APIs, and SSL certificate providers. Save the following content into /opt/traefik/data/traefik.yml:

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

providers:
  docker:
    exposedByDefault: false
    network: traefik-public

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /acme.json
      httpChallenge:
        entryPoint: web

In this setup, we have configured a seamless global HTTP-to-HTTPS redirection on the web entrypoint. Any traffic hitting port 80 is immediately upgraded to encrypted port 443. We also declared our certificate resolver using the httpChallenge validation method, which requires port 80 to be publicly accessible from the internet.

Step 3: Deploying Traefik v3 via Docker Compose

With our static configuration in place, we can now launch Traefik using Docker Compose. Create a docker-compose.yml file inside the /opt/traefik/ directory:

version: "3.8"

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /opt/traefik/data/traefik.yml:/traefik.yml:ro
      - /opt/traefik/data/acme.json:/acme.json
    networks:
      - traefik-public
    labels:
      - "traefik.enable=true"
      # Dashboard routing configuration
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.middlewares=auth"
      # Simple HTTP Basic Auth for Dashboard Security (admin:password_hash)
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$uo7rDe0a$$9R7b8Y7Fj2vW/WUkpM1X1."

networks:
  traefik-public:
    external: true

Note the use of /var/run/docker.sock:/var/run/docker.sock:ro. Mounting the Docker socket as read-only (ro) is an essential security practice that limits Traefik's permissions, preventing malicious internal actors from manipulating the host machine's Docker daemon maliciously.

Step 4: Verifying Automated Container Discovery

Now, let's deploy a business application container to see automated discovery and SSL configuration in action. We will spin up a lightweight Nginx web application. Notice that this container does not need ports exposed directly to the host machine; everything routes internally via the traefik-public network.

version: "3.8"

services:
  webapp:
    image: nginx:alpine
    container_name: demo-web-app
    restart: always
    networks:
      - traefik-public
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.services.webapp.loadbalancer.server.port=80"

networks:
  traefik-public:
    external: true

Once you execute docker compose up -d on this stack, Traefik immediately catches the lifecycle event emitted by Docker. It reviews the labels, constructs a routing rule for app.example.com, signals Let's Encrypt to complete the HTTP challenge, provisions an SSL certificate, and initiates secure routing—all within seconds.

Best Practices for Production Environments

To ensure a resilient engineering deployment, always keep the following production-grade practices in mind:

  1. Log Management: Configure proper access logging and error logging parameters within traefik.yml to export logs to structured JSON files, easing parsing via ELK or Grafana Loki stacks.
  2. Rate Limiting: Protect your upstream application services against DDoS vectors or brute-force requests by enabling Traefik's native RateLimit middleware.
  3. Strict Security Headers: Use a customized headers middleware to enforce HTTP Strict Transport Security (HSTS), X-Frame-Options, and X-Content-Type-Options across all routed microservices.

Conclusion

Traefik v3 provides modern engineering teams with a dynamic, self-healing, and maintenance-free approach to traffic management. By replacing tedious manual configuration scripts with explicit, infrastructure-as-code Docker labels, systems engineers save hours of manual onboarding time. Implementing automatic dynamic discovery and seamless automated SSL certificates allows you to focus on developing functionality rather than maintaining infrastructure plumbing.