Traefik — reverse proxy, который сам находит контейнеры Docker и сам выпускает TLS-сертификаты, без ручной правки конфигов при каждом новом сайте. Вместо статичного файла с блоками server, как у nginx, Traefik читает labels прямо на контейнерах и перестраивает маршруты на лету. Разберём установку в Docker Compose, автоматический TLS через Let's Encrypt и типичные ошибки.
Что такое Traefik и чем он отличается от nginx
nginx требует отдельного конфиг-файла на каждый сайт и перезагрузки процесса при изменениях. Traefik подключается к Docker через сокет, видит все запущенные контейнеры и строит маршруты из их labels автоматически — без reload и без отдельных файлов конфигурации на каждый домен. Новый сайт добавляется одной строкой labels в docker-compose.yml, а не отдельным конфигом reverse proxy.
Обратная сторона: Traefik добавляет ещё один слой абстракции поверх привычного HTTP-сервера, и отладку маршрутов приходится вести через его собственный дашборд, а не через привычные логи nginx.
Установка Traefik в Docker Compose
Базовый сервис Traefik в docker-compose.yml с включённым Docker-провайдером:
services:
traefik:
image: traefik:v3.1
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
restart: unless-stopped
Флаг exposedbydefault=false обязателен: без него Traefik открывает наружу вообще все контейнеры на сервере, а не только те, что явно помечены labels.
Автоматический TLS через Let's Encrypt
Traefik сам запрашивает и продлевает сертификаты через протокол ACME, без cron-задачи и отдельного certbot. Для этого в команду сервиса добавляют resolver:
command:
- --certificatesresolvers.le.acme.email=admin@example.com
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
Файл acme.json обязан иметь права 600 — Let's Encrypt хранит в нём приватные ключи сертификатов, и при более открытых правах Traefik откажется его использовать.
Как Traefik находит контейнеры: labels на сервисах
Каждый контейнер, который должен получить маршрут, помечается labels прямо в описании сервиса:
services:
app:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=le"
- "traefik.http.services.app.loadbalancer.server.port=8080"
Traefik сам подхватывает контейнер после docker compose up -d: не нужно отдельно редактировать конфиг proxy и перезапускать его.
Несколько сайтов на одном сервере
Маршрутизация по доменам держится на правиле Host() в labels: разные контейнеры отвечают на разные домены через один и тот же порт 443 сервиса Traefik. Для каждого домена задаётся свой certresolver, и Traefik выпускает отдельный сертификат на каждый Host автоматически при первом запросе.
| Критерий | Traefik | Caddy |
|---|---|---|
| Обнаружение сервисов | Автоматически через Docker labels | Через статичный Caddyfile |
| Автоматический TLS | Да, через ACME resolver | Да, из коробки для любого домена |
| Перезагрузка при новом сайте | Не требуется | Требуется reload конфига |
Дашборд и наблюдение за маршрутами
Встроенный дашборд на порту 8080 показывает список роутеров, сервисов и middleware в реальном времени — удобно проверить, что labels распознаны правильно. В продакшене дашборд закрывают тем же механизмом labels с basic-auth middleware, а не оставляют открытым наружу.
- Включить дашборд флагом
--api.dashboard=trueтолько на этапе отладки - Закрыть путь
/dashboard/отдельным роутером с middleware авторизации - Смотреть логи access через
--accesslog=trueпри разборе проблем с маршрутизацией
Частые ошибки конфигурации
Первая ошибка — забытый exposedbydefault=false, из-за чего наружу открываются служебные контейнеры вроде баз данных. Вторая — неправильные права на acme.json, из-за которых Traefik тихо не может сохранить сертификат и перевыпускает его при каждом рестарте, упираясь в лимиты Let's Encrypt. Третья — отсутствие traefik.enable=true на нужном контейнере, из-за чего сервис остаётся недоступным, хотя все остальные labels выставлены верно.
Если сайтов на сервере много и нужен кластер из нескольких VDS, тот же Traefik работает и поверх Docker Swarm, читая labels уже из режима stack. Для сравнения с более простым по конфигурации reverse proxy смотрите статью про Caddy Server. Если инфраструктура уже перешла на полноценный Kubernetes, аналогичную роль там выполняет ingress-nginx.
Итог: чек-лист запуска Traefik
Traefik избавляет от ручного редактирования конфигов reverse proxy при каждом новом контейнере, если labels настроены аккуратно с самого начала.
- Флаг
exposedbydefault=falseв конфигурации Docker-провайдера - Права 600 на файл
acme.jsonс сертификатами traefik.enable=trueявно на каждом контейнере, который должен быть виден снаружи- Дашборд закрыт middleware авторизации, а не открыт на весь интернет