Обычно я для проксирования сервисов на docker-compose или stack применял nginx. Но у него есть очень неприятный недостаток - нет поддержки Letsencrypt из коробки.

Если standalone nginx еще норм дружит с certbot, который сам после обновления сертификата перезагружает сервер, то с docker все сложней.

Так как Nginx не может без перезагрузки применить новый сертификат, то приходится либо руками перезагружать контейнер, либо писать хуки для контейнера с certbot. Плюс нужно подкладывать фейковый сертификат в конфиг nginx на первый запуск, чтобы он вообще запустился. В общем те еще танцы с бубном. Плюс бывает что certbot подкидывает проблем, например не может авторизоваться.

Так получилось, что в последнее время мне пришлось поднимать много хостов и сервисов для нашего нового сервиса видео звонков для проведения интервью в Huntica.

Изрядно повоевав с Nginx, я решил посмотреть в сторону Traefik, с которым уже имел позитивный опыт использования. С ним конечно тоже есть свои нюансы, которые я опишу далее.

Для начала простой пример использования:

version: "3.7"

services:
  traefik:
    image: "traefik:v2.5"
    container_name: "traefik"
    command:
      - "--log.level=ERROR"
      - "--api.insecure=true"
      - "--providers.docker=true"
			- "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "[email protected]"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    ports:
      - "443:443"
      - "8080:8080"

  # тестовый сервер 
	server:
	    image: traefik/whoami
	    restart: always
	    hostname: client
	    ports:
	      - "80"
	    labels:
	      - "traefik.enable=true"
	      - "traefik.http.routers.server.rule=Host(`server.your.host`)"
	      - "traefik.http.routers.server.entrypoints=websecure"
	      - "traefik.http.routers.server.tls.certresolver=myresolver"
	      - "traefik.http.services.server.loadbalancer.server.port=80"

Что тут происходит?

  1. Подключаем провайдер docker, и отключаем exposedbydefault, чтобы traefik не обрабатывал все сервисы
      - "--providers.docker=true"
			- "--providers.docker.exposedbydefault=false"
  1. Создаем entrypoint для ssl трафика
- "--entrypoints.websecure.address=:443"
  1. Создаем резолвер для сертификатов
 - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
 - "[email protected]"
 - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"