// Engineering Log

Proxy servers: Part 8 — Traefik

Published on 2026-09-22

// Fast route

This article belongs to the topic Deploy and reliability.

Traefik (pronounced “traffic”) is a reverse proxy and load balancer that takes routes not from a static file but from the environment: from Docker, Kubernetes, files, or service discovery systems. Start a container with the right labels — Traefik will create a route for it and obtain a certificate. Stop it — the route disappears.

The project is written in Go and distributed under the MIT license; the current version as of September 2026 is v3.7.13 (04.09.2026).

How Traefik is organized

Traefik configuration is split into two parts.

  • Static configuration is set at startup (via command-line flags, a file, or environment variables): which ports to accept traffic on (entry points), where to get routes from (providers), how to obtain certificates (certificate resolvers). To change it, Traefik must be restarted.
  • Dynamic configuration comes from providers and changes on the fly: routers with rules like Host(`app.example.ru`) or PathPrefix(`/api`), services — where to send the request, and middlewares — authentication, headers, redirects, rate limiting.

The chain is simple: a request arrives at an entry point, a matching router selects a service, and middlewares process it along the way.

Working example: Traefik and an app in Docker Compose

Below is a complete configuration: Traefik accepts HTTP and HTTPS, redirects HTTP to HTTPS, obtains a Let’s Encrypt certificate via HTTP-01 validation, and exposes the test application whoami at app.example.ru.

yaml
services:
  traefik:
    image: traefik:v3.7
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entryPoints.web.address=:80"
      - "--entryPoints.websecure.address=:443"
      - "--entryPoints.web.http.redirections.entryPoint.to=websecure"
      - "--entryPoints.web.http.redirections.entryPoint.scheme=https"
      - "--certificatesresolvers.le.acme.email=admin@example.ru"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    restart: unless-stopped

  app:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.ru`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=le"
      - "traefik.http.services.app.loadbalancer.server.port=80"

What’s important here:

  • exposedbydefault=false — Traefik exposes only containers with the label traefik.enable=true. Without this, all containers on the server, including databases with open ports, will be exposed.
  • Redirecting from web to websecure is compatible with HTTP-01 validation: according to Traefik documentation, validation requests go to port 80 and work with redirects enabled.
  • acme.json is the file where Traefik stores obtained certificates. It must be placed in a volume, otherwise after recreating the container certificates will be requested again.
  • loadbalancer.server.port specifies the port inside the application container. You don’t need to publish this port via ports: traffic goes over Docker’s internal network.

To add a second service, just describe it with the same labels and its own Host rule — you won’t need to touch Traefik’s configuration.

Middlewares: authentication, headers, rate limiting

Middlewares are attached via labels. Example — protect an internal service with a password:

yaml
    labels:
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."
      - "traefik.http.routers.admin.middlewares=auth"

The password hash is prepared with the htpasswd utility; dollar signs $ in docker-compose must be doubled, otherwise Compose will interpret them as variables. From the available middlewares you’ll most often use BasicAuth, Headers (security headers), RedirectScheme, StripPrefix and RateLimit.

Dashboard

Traefik shows current routes, services and errors in the web dashboard (--api.dashboard=true). You should expose it via a separate router with authentication and HTTPS. The --api.insecure=true mode exposes the dashboard without protection and is only suitable for local experiments.

Traefik in Kubernetes

In Kubernetes Traefik works as an ingress controller: it reads standard Ingress objects, its own IngressRoute resources, and the Gateway API. The logic is the same — routes appear alongside services, and certificates are issued by the same certificate resolvers mechanism.

Common mistakes

  • No exposedbydefault=false. Traefik exposes everything, including service containers.
  • Container in a different network. If the application and Traefik are not in the same Docker network, the route will appear but requests will fail with a 502. Keep them in one network or specify it in --providers.docker.network.
  • Port 80 closed. HTTP-01 validation runs on port 80; without it a certificate will not be issued.
  • Docker socket without restrictions. Access to /var/run/docker.sock is equivalent to root on the host. Mount it read-only, and in sensitive environments put a proxy in front of the socket that exposes a limited set of API methods.
  • Single $ in the password hash. Compose will substitute empty variables for them, and authentication will stop working.
  • Open dashboard. api.insecure=true on a public server is a direct exposure of your infrastructure layout.

When to choose Traefik

Traefik makes sense where services frequently appear and disappear: Docker hosts with dozens of containers, environments for branch deployments, Kubernetes. For a few static sites on a VPS it’s easier to use Caddy; for advanced load balancing and TCP — HAProxy. Traefik does not serve static files itself, so a site made of ordinary files still needs a separate web server. A comparison of all five servers is in the article Caddy vs. Traefik vs. HAProxy vs. Nginx vs. Apache.

// Similar task

If you are dealing with something similar

This article belongs to one of the main working topics. You can keep reading on the topic, go to the homepage to understand what I do, or open the service pages directly.

Article topic

Deploy and reliability

Docker, CI/CD, releases, monitoring, observability, and incident handling.

Typical tasks behind this topic

  • Set up deployment without manual chaos
  • Add monitoring, alerts, and baseline observability
  • Investigate incidents and stabilize production

// Next step

If you need help with this topic, not just another article, it is better to go straight to the service page. The homepage and topic collection stay available as secondary routes.

Open services

// Reviews

Related reviews

N_Konstantin

VPS setup, server setup

2025-10-10 · ★ 5/5

A settled customer

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply