Настройка Traefik + Mantrae: удобное управление обратным прокси через GUI

Решил поделиться своим опытом настройки связки Traefik и Mantrae.

В чем проблема?
Traefik — отличный инструмент, но он требует работы с двумя типами конфигурации: статической (запуск самого Traefik) и динамической (описание роутеров и сервисов). Каждый раз открывать файл динамической конфигурации, чтобы добавить новый сервис, — не всегда удобно.

Решение
Здесь на помощь приходит mantrae. Он предоставляет удобный веб-интерфейс (похожий по логике на Nginx Proxy Manager) и формирует динамическую конфигурацию для Traefik автоматически.

Вот как выглядит процесс настройки нового сервиса:

А вот так выглядит общий список моих сервисов:

Ниже привожу свою конфигурацию.


1. Docker Compose

Traefik и Mantrae у меня живут в одном compose.yaml файле.
Обратите внимание: я использую разделение на LAN (порты 80/443) и WAN (порты 90/450), а также Cloudflare для получения wildcard-сертификатов.

services:
  traefik:
    image: traefik:v3.6.7
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443
      - 90:90
      - 450:450
    environment:
      - TZ=Europe/Kyiv
      - CLOUDFLARE_DNS_API_TOKEN=${CLOUDFLARE_DNS_API_TOKEN}
      - MAIN_DOMAIN=${MAIN_DOMAIN}
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.yaml:/traefik.yaml:ro
      - ./traefik/acme.json:/acme.json
      - ./traefik/logs:/var/log/traefik
    labels:
      - traefik.enable=true
      - traefik.http.routers.traefik-secure.service=api@internal
      - traefik.http.routers.traefik-secure.rule=Host(`traefik-dashboard.${MAIN_DOMAIN}`)
      - traefik.http.routers.traefik-secure.entrypoints=https-lan
      - traefik.http.routers.traefik-secure.tls=true
      - traefik.http.routers.traefik-secure.tls.certresolver=cloudflare
      - traefik.http.routers.traefik-secure.tls.domains[0].main=${MAIN_DOMAIN}
      - traefik.http.routers.traefik-secure.tls.domains[0].sans=*.${MAIN_DOMAIN}
      - traefik.http.routers.traefik-secure.middlewares=voidauth@docker
    networks:
      default:
      proxy:

  mantrae:
    image: ghcr.io/mizuchilabs/mantrae:latest
    container_name: mantrae
    restart: unless-stopped
    environment:
      - SECRET=${MANTRAE_SECRET}
      - ADMIN_PASSWORD=${MANTRAE_ADMIN_PASSWORD}
      - LOG_LEVEL=info
      - LOG_FORMAT=text
    volumes:
      - ./mantrae:/data
    labels:
      - traefik.enable=true
      - traefik.http.routers.mantrae.rule=Host(`mantrae.${MAIN_DOMAIN}`)
      - traefik.http.routers.mantrae.entrypoints=https-lan
      - traefik.http.routers.mantrae.tls.certresolver=cloudflare
      - traefik.http.services.mantrae.loadbalancer.server.port=3000
    networks:
      default:

networks:
  default:
  proxy:
    external: true

2. Переменные окружения (.env)

Рядом с compose.yaml создаем файл .env:

MAIN_DOMAIN=основной домен
CLOUDFLARE_DNS_API_TOKEN=токен для получения https сертификата

# Секрет генерируется командой: openssl rand -hex 32
MANTRAE_SECRET=секрет_hex_32
MANTRAE_ADMIN_PASSWORD=пароль для подключения к панели управления

Подробнее про настройку HTTPS-сертификатов через Cloudflare рекомендую посмотреть отличное видео от ProHomelab: https://youtu.be/1mTbILjtOo0?si=xznDsVFWYsS7ayrX

3. Статическая конфигурация Traefik

Файл traefik.yaml. Здесь мы описываем точки входа (entryPoints) и подключаем провайдеры.
Самое важное — блок providers.http, через который Traefik будет “стучаться” в Mantrae за конфигурацией.

api:
  dashboard: true
  debug: true
entryPoints:
  http-lan:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https-lan
          scheme: https
          permanent: true
    observability:
      accessLogs: false
      metrics: false
      tracing: false
  https-lan:
    address: ":443"
    http3: {}
    # этот блок необходим для стабильной работы immich (загрузка больших файлов)
    transport:
      respondingTimeouts:
        readTimeout: 600s
        idleTimeout: 600s
        writeTimeout: 600s

  http-wan:
    address: ":90"
    http:
      redirections:
        entryPoint:
            to: https-wan
            scheme: https
            permanent: true
  https-wan:
    address: ":450"
    http3: {}
    # этот блок необходим для стабильной работы immich
    transport:
      respondingTimeouts:
        readTimeout: 600s
        idleTimeout: 600s
        writeTimeout: 600s

serversTransport:
  insecureSkipVerify: true

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  # Интеграция с Mantrae
  http:
    # Токен нужно будет вставить сюда после первого запуска Mantrae
    endpoint: "http://mantrae:3000/api/traefik-default?token=ВАШ_ТОКЕН"
    pollInterval: "5s"

certificatesResolvers:
  cloudflare:
    acme:
      email: моя почта
      storage: acme.json
      dnsChallenge:
        provider: cloudflare        
        delayBeforeCheck: 30
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

log:
  level: "INFO"
  filePath: "/var/log/traefik/traefik.log"
accessLog:
  filePath: "/var/log/traefik/access.log"

4. Как это запустить и связать?

По сути, Mantrae по HTTP передаёт тот же самый файл динамической конфигурации для Traefik.
Чтобы получить нужную ссылку с токеном:

  1. Запускаем контейнеры.
  2. Открываем веб-интерфейс Mantrae.
  3. Копируем ссылку в интерфейсе:
  4. Вставляем её в файл traefik.yaml (в поле endpoint) и перезапускаем контейнер Traefik.

Так как оба контейнера находятся в одной docker-сети, я обращаюсь по имени контейнера (http://mantrae:3000...) вместо IP.

Важный момент:
Не забудьте продублировать entryPoints из файла статической конфигурации (traefik.yaml) в веб-интерфейс Mantrae, чтобы они совпадали:

Добавление сервисов

То же самое и с сервисами. Я добавляю их в сеть proxy, порты наружу в compose файле сервиса не открываю. А при добавлении в Mantrae указываю имя контейнера и его внутренний порт:

6 лайков

Интересная штука, выгядит функционаьно, для тех, кто хочет перейти с NPM на Traefik

С другой стороны, переход на traefik у меня был в том числе ради этого

“Added new domain” это формируется скриптом, который в режиме диалога получает данные от пользователя и формирует нужные файлы, после чего коммитит их в репозиторий

Вообще тема веб админок для traefik поднималась в ТГ группе, но там и осталась, на форуме отражения не получила, за что Вам благодарность от сообщества.

3 лайка