Найти в Дзене
Linux | Network | DevOps

Использование Traefik в Docker Swarm с локальными SSL-сертификатами

Иногда необходимо настроить обратный прокси для сервисов в Docker Swarm без подключения к Let's Encrypt. Причины могут быть простые:
🔒 Свои сертификаты, выданные внутренним CA
🛡 Полная автономность (в том числе без доступа в интернет)
⚙️ Полный контроль над ротацией и валидностью Traefik работает как глобальный ingress на swarm и стартует как глобальная сервисная реплика (с --mode=global). Все сетевые входы идут через него. command: - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--providers.docker=true" - "--providers.docker.swarmMode=true" - "--providers.docker.exposedByDefault=false" - "--certificatesresolvers.default.acme.tlschallenge=false" # отключаем ACME - "--entrypoints.websecure.http.tls=true" - "--entrypoints.websecure.http.tls.certResolver=default" - "--certificatesResolvers.default.files.certificates=certs.yaml" Сертификаты (ключ + цепочка) заранее размещаются в volume и описываются в certs.yaml: tls: certif
Оглавление

Иногда необходимо настроить обратный прокси для сервисов в Docker Swarm без подключения к Let's Encrypt.

Причины могут быть простые:
🔒 Свои сертификаты, выданные внутренним CA
🛡 Полная автономность (в том числе без доступа в интернет)
⚙️ Полный контроль над ротацией и валидностью

🔧 Конфигурация Traefik:

Traefik работает как глобальный ingress на swarm и стартует как глобальная сервисная реплика (с --mode=global). Все сетевые входы идут через него.

command:
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.docker=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedByDefault=false"
- "--certificatesresolvers.default.acme.tlschallenge=false" # отключаем ACME
- "--entrypoints.websecure.http.tls=true"
- "--entrypoints.websecure.http.tls.certResolver=default"
- "--certificatesResolvers.default.files.certificates=certs.yaml"

📁 Хранение сертификатов:

Сертификаты (ключ + цепочка) заранее размещаются в volume и описываются в certs.yaml:

tls:
certificates:
- certFile: "/certs/fullchain.pem"
keyFile: "/certs/privkey.pem"

Сам том монтируется в Traefik:

volumes:
- source: traefik-certs
target: /certs
type: volume

Важно: certs.yaml можно смонтировать через конфиг или том, главное — Traefik должен видеть его как обычный файл внутри контейнера.

🔍 Особенности:

  • Сложнее масштабировать: если на каждый сервис разные сертификаты — нужно заранее прописывать каждый в certs.yaml. Это не динамично.
  • Обновление: чтобы ротация прошла, Traefik нужно перезапускать, иначе не "увидит" новые файлы.
  • Доверие: на клиентах (если это внутренняя сеть) нужно убедиться, что доверяют CA, иначе будут "варнинги".

✅ Плюсы:

  • Полный контроль над сертификатами
  • Нет зависимости от внешнего интернета
  • Удобно для закрытых сред и банковского сектора

❌ Минусы:

  • Нет автоматической ротации
  • Неудобно при большом количестве доменов
  • Больше ручной работы

📦 docker-compose.yml для Traefik в Swarm:

version: "3.8"
services:
traefik:
image: traefik:v2.11
command:
- "--api.dashboard=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.docker=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedByDefault=false"
- "--entrypoints.websecure.http.tls=true"
- "--entrypoints.websecure.http.tls.certificates=/certs/certs.yaml"
ports:
- "80:80"
- "443:443"
volumes:
- traefik-cert-volume:/certs
- /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
placement:
constraints:
- node.role == manager
mode: global
volumes:
traefik-cert-volume:
external: true
⚠️ Обрати внимание на --entrypoints.websecure.http.tls.certificates=/certs/certs.yaml — это путь к файлу с локальными сертификатами.

🗃 Пример certs.yaml

tls:
certificates:
- certFile: "/certs/example.com.crt"
keyFile: "/certs/example.com.key"
- certFile: "/certs/api.example.com.crt"
keyFile: "/certs/api.example.com.key"

Файлы .crt и .key должны быть заранее положены в volume traefik-cert-volume.

🧩 Пример backend-сервиса с маршрутизацией

version: "3.8"
services:
whoami:
image: traefik/whoami
networks: - traefik-net
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
traefik-net:
external: true

⚙️ Как всё подключить:

  1. Создать volume для сертификатов:

docker volume create traefik-cert-volume

  1. Поместить туда сертификаты:

docker run --rm -v traefik-cert-volume:/certs -v $(pwd)/certs:/local alpine \ cp /local/* /certs/

  1. Развернуть Traefik и сервисы:

docker stack deploy -c docker-compose.yml traefik docker stack deploy -c whoami.yml demo

Обсудить эту заметку можно в Телеграм канале: https://t.me/linautonet