Все руководства по развёртыванию Развёртывание

Как установить пользовательский SSL-сертификат в Traefik (v3)

Traefik известен тем, что автоматически выпускает сертификаты через ACME. Но иногда вам нужно использовать собственный сертификат — выданный сервисом GetHTTPS, корпоративным/внутренним CA или wildcard-сертификат, которым вы управляете в другом месте. Это руководство покажет, как именно это сделать в Traefik v3.

Главное, что нужно понять сразу: вы не можете подключить файл сертификата через метку Docker. Метки Traefik управляют маршрутизацией и включают TLS, но сам сертификат должен поступать от файлового провайдера в виде динамической конфигурации. На этом спотыкается почти каждый в первый раз. Мы сделаем всё правильно.

Если у вас ещё нет сертификата, получите его бесплатно за 5 минут.

Когда это использовать (вместо автоматического ACME в Traefik)

Автоматический ACME (Let’s Encrypt)Собственный сертификат (это руководство)
Публичный сайт, доступный из интернетаВнутренний сервис/интранет (без публичного DNS)
Стандартного DV-сертификата достаточноНужен конкретный CA, wildcard или сертификат OV/EV
Traefik может пройти HTTP/DNS-проверкуИзолированный или закрытый файрволом хост
Вы хотите нулевое управление сертификатамиУ вас уже есть сертификат от GetHTTPS или из другого источника

Если автоматический ACME вам подходит, то certificatesResolvers в Traefik проще. Это руководство для случая «у меня уже есть fullchain.pem + privkey.pem, и нужно, чтобы Traefik их обслуживал».

Предварительные требования

  • Traefik v3, запущенный как контейнер Docker (в конфигурации ниже используется Docker, но часть с динамической конфигурацией применима к любой установке)
  • Файлы вашего сертификата — их два:
    • fullchain.pem — ваш сертификат + промежуточная цепочка
    • privkey.pem — ваш приватный ключ
  • Домен, указывающий на хост (или локальная запись в hosts-файле для внутреннего использования)

Какие файлы нужны Traefik? Traefik ожидает полную цепочку в certFile и ключ в keyFile. Если вы используете cert.pem только с конечным сертификатом, клиенты получат ошибки «неполная цепочка» — Traefik не добавляет промежуточные сертификаты автоматически для сертификатов файлового провайдера. Используйте fullchain.pem. Форматы сертификатов объяснены →

Как разделена конфигурация Traefik

В Traefik есть два вида конфигурации, и сертификаты находятся во втором из них:

  • Статическая конфигурация — задаётся при запуске (entrypoints, провайдеры). Её изменение требует перезапуска. Она прописывается в traefik.yml или в командных флагах контейнера.
  • Динамическая конфигурация — перезагружается на лету без перезапуска (routers, сервисы, TLS-сертификаты). Именно её читает файловый провайдер.

Ваш сертификат — это динамическая конфигурация. Вот почему метка не может его нести: метки читаются из провайдера Docker, а tls.certificates — это концепция файлового провайдера.

Шаг 1: Разместите файлы сертификата

Поместите файлы в каталог, который вы смонтируете в контейнер:

mkdir -p ./traefik/certs
cp fullchain.pem ./traefik/certs/
cp privkey.pem   ./traefik/certs/

# Ограничьте доступ к приватному ключу
chmod 600 ./traefik/certs/privkey.pem
chmod 644 ./traefik/certs/fullchain.pem

Шаг 2: Напишите динамическую конфигурацию

Создайте ./traefik/dynamic/certs.yml. Именно здесь вы объявляете свой сертификат:

# ./traefik/dynamic/certs.yml  (динамическая конфигурация — файловый провайдер)
tls:
  certificates:
    - certFile: /certs/fullchain.pem
      keyFile: /certs/privkey.pem

  # Необязательно: сделать этот сертификат сертификатом по умолчанию для любого хоста,
  # который не соответствует более конкретному сертификату (например, wildcard или внутренний CA).
  stores:
    default:
      defaultCertificate:
        certFile: /certs/fullchain.pem
        keyFile: /certs/privkey.pem

Пути (/certs/...) — это пути внутри контейнера, мы смонтируем их на следующем шаге. Traefik выбирает нужный сертификат для каждого запроса с помощью SNI, сопоставляя SAN сертификата с запрашиваемым именем хоста. defaultCertificate — это запасной вариант, когда ничего другого не подходит.

Шаг 3: Настройте Traefik (статическая конфигурация + монтирование)

Вот полный docker-compose.yml. Entrypoints и файловый провайдер — это статическая конфигурация (передаётся в виде командных флагов); сертификат загружается из динамического файла, который вы только что написали.

services:
  traefik:
    image: traefik:v3.3
    container_name: traefik
    restart: unless-stopped
    command:
      # ─── Entrypoints ───────────────────────────────
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Перенаправлять весь HTTP → HTTPS на уровне entrypoint
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      # ─── Providers ─────────────────────────────────
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      # Файловый провайдер следит за каталогом динамической конфигурации
      - "--providers.file.directory=/dynamic"
      - "--providers.file.watch=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik/certs:/certs:ro"
      - "./traefik/dynamic:/dynamic:ro"

  # ─── Пример бэкенд-сервиса ──────────────────────
  whoami:
    image: traefik/whoami
    container_name: whoami
    labels:
      - "traefik.enable=true"
      # Router: сопоставить хост, обслуживать на HTTPS-entrypoint
      - "traefik.http.routers.whoami.rule=Host(`example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      # Включить TLS на этом router — сертификат берётся из
      # динамической конфигурации, а НЕ из метки.
      - "traefik.http.routers.whoami.tls=true"

Критически важная строка — traefik.http.routers.whoami.tls=true. Она сообщает Traefik «обслуживать этот router по TLS». Затем Traefik выбирает подходящий сертификат из хранилища файлового провайдера по SNI. Нет метки вроде tls.certfile — для routers она не существует.

Шаг 4: Запуск и проверка

docker compose up -d
docker compose logs -f traefik

Следите за загрузкой вашего сертификата файловым провайдером. Вы не должны видеть ошибок TLS. Затем проверьте:

Проверка в браузере

Откройте https://example.com. Нажмите на значок замка:

  • Кем выдан — ваш CA (Let’s Encrypt для GetHTTPS или ваш внутренний CA)
  • Действителен — даты начала и окончания
  • Домен — соответствует URL

Проверка из командной строки

# Убедитесь, что Traefik обслуживает ВАШ сертификат, а не свой самоподписанный по умолчанию
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

Если вы видите CN=TRAEFIK DEFAULT CERT, значит Traefik вернулся к своей встроенной заглушке — ваш сертификат не был загружен. Смотрите раздел Устранение неполадок ниже.

Шаг 5 (необязательно): Усиление TLS

Чтобы управлять версиями протоколов и шифрами, добавьте блок параметров TLS в вашу динамическую конфигурацию и сошлитесь на него из router. Добавьте в certs.yml:

tls:
  options:
    modern:
      minVersion: VersionTLS12
      sniStrict: true

Затем в метке router:

- "traefik.http.routers.whoami.tls.options=modern@file"

Суффикс @file сообщает Traefik, что этот набор параметров берётся из файлового провайдера. Это ограничивает вас TLS 1.2 и 1.3 и отклоняет соединения без подходящего SNI.

HSTS: Добавьте заголовок Strict-Transport-Security через middleware headers в Traefik, когда убедитесь, что HTTPS работает везде. Руководство по HSTS →

Как обновить сертификат

Traefik не обновляет автоматически сертификаты, которые вы предоставляете сами, — это плата за использование собственного сертификата. Когда срок действия вашего сертификата подходит к концу (60-й день из 90 для Let’s Encrypt):

  1. Получите новый сертификат от GetHTTPS (или с помощью вашего инструмента обновления).
  2. Перезапишите файлы на месте:
    cp new-fullchain.pem ./traefik/certs/fullchain.pem
    cp new-privkey.pem   ./traefik/certs/privkey.pem
  3. Больше ничего. Поскольку установлен --providers.file.watch=true, Traefik обнаруживает изменение файла и горячо перезагружает сертификат — без перезапуска, без простоя. Это одно из самых приятных свойств Traefik для пользовательских сертификатов.

Полное руководство по обновлению →

Устранение неполадок

Traefik обслуживает «TRAEFIK DEFAULT CERT» вместо моего сертификата

Причина: Traefik не смог загрузить ваш сертификат, поэтому вернулся к своей самоподписанной заглушке. Почти всегда это проблема с путём или монтированием.

Решение:

# 1. Убедитесь, что файлы существуют ВНУТРИ контейнера по ожидаемому пути
docker compose exec traefik ls -l /certs

# 2. Убедитесь, что динамический файл смонтирован и доступен для чтения
docker compose exec traefik cat /dynamic/certs.yml

# 3. Проверьте логи на наличие реальной причины
docker compose logs traefik | grep -i "certificate\|tls\|error"

Пути certFile/keyFile в certs.yml должны соответствовать путям внутри контейнера (/certs/...), а не путям на вашем хосте.

«unable to find certificate for domain» / обслуживается неправильный сертификат

Причина: Ни один SAN сертификата не соответствует запрашиваемому имени хоста, и не задан defaultCertificate.

Решение: Либо добавьте имя хоста в ваш сертификат, либо задайте defaultCertificate в блоке stores.default (Шаг 2), чтобы у Traefik был запасной вариант.

Router возвращает 404, сертификат даже не проверяется

Причина: Правило router не совпадает, или сервис не открыт. TLS не имеет значения, пока маршрутизация не совпадёт.

Решение:

# Убедитесь, что router существует и включён
docker compose exec traefik wget -qO- http://localhost:8080/api/http/routers 2>/dev/null | grep whoami

Убедитесь, что traefik.enable=true указан на бэкенд-контейнере и правило Host() соответствует тестируемому домену.

Изменения в certs.yml не вступают в силу

Причина: Файловый провайдер не следит за изменениями, или вы отредактировали статическую конфигурацию (которая требует перезапуска).

Решение: Убедитесь, что --providers.file.watch=true присутствует в статической конфигурации. Помните: entrypoints/провайдеры — это статика (требуется перезапуск); routers и tls.certificates — это динамика (горячая перезагрузка).

«x509: certificate signed by unknown authority» от клиентов

Причина: Неполная цепочка — вы использовали cert.pem только с конечным сертификатом в certFile вместо fullchain.pem.

Решение: Укажите в certFile полную цепочку. Если у вас есть только отдельные файлы, объедините их (сначала конечный, затем промежуточные):

cat cert.pem intermediate.pem > fullchain.pem

Часто задаваемые вопросы

Можно ли указать файл сертификата через метку Docker?

Нет. Это заблуждение №1. Метки задают traefik.http.routers.<name>.tls=true, чтобы включить TLS, но файлы сертификата должны быть объявлены в динамической конфигурации через файловый провайдер (tls.certificates). Нет метки router, которая указывала бы на файл .pem.

Нужен ли tls=true на router, если у меня есть сертификат?

Да. Объявление сертификата в tls.certificates делает его доступным, но каждому router всё равно нужен tls=true (или прослушивание entrypoint с включённым TLS), чтобы реально обслуживать запросы по HTTPS. Само по себе определение сертификата не переключает router на TLS.

Можно ли совмещать автоматический ACME и пользовательские сертификаты?

Да. Traefik может использовать certificatesResolver для одних routers и сертификаты файлового провайдера для других. Для каждого запроса явное совпадение tls.certificates по SNI имеет приоритет над ACME для этого имени хоста.

Куда помещаются сертификаты в Kubernetes?

Не в файловый провайдер — в Kubernetes вы предоставляете сертификаты как TLS Secrets и ссылаетесь на них из IngressRoute/Ingress. Подход с файловым провайдером из этого руководства предназначен для Docker и автономных (не-K8s) установок.

Обновляет ли Traefik мой пользовательский сертификат автоматически?

Нет. Автоматическое обновление применяется только к сертификатам, которые Traefik выпускает сам через ACME. Для ваших собственных сертификатов вы заменяете файлы — но благодаря --providers.file.watch=true Traefik горячо перезагружает их без простоя, как описано в разделе Как обновить сертификат выше.

Работает ли это с сертификатами ECDSA/ECC?

Да. Traefik обслуживает сертификаты ECDSA точно так же, как RSA, — с той же конфигурацией certFile/keyFile. GetHTTPS по умолчанию выпускает ECDSA P-256 для меньших по размеру и более быстрых рукопожатий.

Похожие статьи

Развёртывание 2026-05-08
SSL-сертификаты с Docker и обратными прокси
Настройка HTTPS для Docker-контейнеров с помощью обратного прокси Nginx, Traefik с автоматическим Let's Encrypt или ручного монтирования сертификатов.
Начало работы 2026-05-08
Как получить бесплатный SSL-сертификат (пошаговое руководство)
Получите бесплатный SSL-сертификат от Let's Encrypt за 5 минут --- без установки программ, без создания аккаунта. Полное руководство: 4 метода, оба типа проверки, установка на 6 платформах и устранение неполадок.
Развёртывание 2026-05-08
Как установить SSL-сертификат на Nginx
Пошаговое руководство по установке SSL-сертификата на Nginx. Охватывает загрузку файлов, полную конфигурацию серверного блока, лучшие практики TLS, HTTP/2, HSTS, настройку редиректов, тестирование и устранение 6 распространённых ошибок.
SSL и сертификаты 2026-05-07
Форматы SSL-сертификатов: PEM, PFX, DER -- подробное объяснение
Разберитесь в форматах сертификатов PEM, PFX/PKCS#12 и DER. Узнайте, какой формат нужен вашему серверу и как конвертировать между ними с помощью OpenSSL.
Получите бесплатный SSL-сертификат в браузере
Без установки, без аккаунта. Ваш приватный ключ никогда не покидает устройство.
Получить сертификат