Traefik - Configuring a Secure Docker Proxy

tags

Treafik is a powerful, modern reverse proxy and load balancer that makes routing traffic to Docker containers remarkably straightforward. In this guide, we’ll explore how to set up Traefik with automatic SSL certificate generation and secure routing configurations.

Understanding Traefik’s Role

Before diving into the configuration, it’s important to understand what Traefik does. Think of Traefik as a smart doorman for your applications. When requests come to your server, Traefik examines them and directs them to the appropriate service based on rules you define. It can automatically handle SSL certificates, load balancing, and service discovery, making it an excellent choice for Docker environments.

Initial Setup

Let’s start by creating the basic Traefik configuration using Docker Compose. Create a docker-compose.yml file with the following configuration:

services:
  traefik:
    container_name: traefik
    image: traefik:v3
    ports:
      - "80:80"      # HTTP
      - "443:443"    # HTTPS
      - "8080:8080"  # Dashboard (should be secured)
    environment:
      - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./config/traefik.yaml:/etc/traefik/traefik.yaml:ro
      - ./config/certs:/var/traefik/certs:rw
    networks:
      - traefik
    restart: unless-stopped
 
networks:
  traefik:
    external: true

This configuration sets up three essential components:

  1. Port mappings for HTTP (80), HTTPS (443), and the admin dashboard (8080)
  2. Access to the Docker socket for container discovery
  3. Volume mounts for configuration and SSL certificates

Note: don’t forget to create the docker network via docker network create traefik

Traefik Configuration

Next, create a traefik.yaml file in your config directory. This file defines how Traefik handles routing, SSL certificates, and security:

################################################################
# Global Configuration
################################################################
global:
  checkNewVersion: true
  sendAnonymousUsage: true
 
################################################################
# EntryPoints Configuration
################################################################
entryPoints:
  http:
    address: :80
  https:
    address: :443
  minecraft:
    address: ':25565/tcp'
 
################################################################
# Logging Configuration
################################################################
log:
  level: DEBUG  # Consider changing to INFO in production
 
################################################################
# API and Dashboard Configuration
################################################################
api:
  insecure: true  # Consider securing this in production
  dashboard: true
 
################################################################
# Docker Provider Configuration
################################################################
providers:
  docker:
    endpoint: unix:///var/run/docker.sock
    exposedByDefault: false  # Security: Opt-in approach for container exposure
 
################################################################
# SSL/TLS Configuration with Let's Encrypt
################################################################
certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]  # Replace with your email
      storage: /var/traefik/certs/cloudflare-acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

Let’s break down the key security features in this configuration:

  • exposedByDefault: false ensures containers must explicitly opt-in to be exposed through Traefik
  • The ACME (Let’s Encrypt) configuration automatically handles SSL certificate generation and renewal
  • DNS challenge using Cloudflare provides a secure way to validate domain ownership

Configuring Services

To expose a service through Traefik, you’ll need to add specific labels to your container configuration. Here’s an example using a simple web service:

services:
  whoami:
    container_name: whoami
    image: traefik/whoami
    labels:
      - traefik.enable=true
      # HTTP Configuration
      - traefik.http.routers.whoami-http.rule=Host(`whoami.yourdomain.com`)
      - traefik.http.routers.whoami-http.entrypoints=http
      # HTTPS Configuration
      - traefik.http.routers.whoami-https.rule=Host(`whoami.yourdomain.com`)
      - traefik.http.routers.whoami-https.entrypoints=https
      - traefik.http.routers.whoami-https.tls=true
      - traefik.http.routers.whoami-https.tls.certresolver=cloudflare
    networks:
      - traefik
    restart: unless-stopped
 
networks:
  traefik:
    external: true

The labels configure:

  • Domain routing through the Host rule
  • Automatic HTTPS redirection
  • SSL certificate generation using the Cloudflare resolver

Security Best Practices

When deploying Traefik in production, consider these additional security measures:

  1. Secure the dashboard by either:

    • Disabling it completely
    • Implementing basic authentication
    • Placing it behind a VPN or firewall
  2. Use specific versions for Docker images instead of the latest tag

  3. Regularly update Traefik to get the latest security patches

  4. Consider implementing rate limiting for your services

Monitoring and Management

Once everything is set up, you can monitor your services through Traefik’s dashboard at http://localhost:8080 (assuming you haven’t disabled it). The dashboard shows:

  • Active routers and services
  • Health status
  • TLS certificate information
  • Real-time metrics

Remember to secure the dashboard in production environments, as it provides detailed information about your infrastructure.