Nginx + Certbot Ingress
Этот каталог содержит автономный ingress-модуль в одном контейнере:
nginxкак reverse proxycertbotдля выпуска и обновления сертификатов Let's Encryptcronвнутри контейнера для автообновления сертификатов
Структура
.
├── docker-compose.yml
├── Dockerfile
├── docker-entrypoint.sh
├── renew.sh
├── nginx.conf
├── conf.d/
│ └── registry.lesha.spb.ru.conf
└── certbot/
├── letsencrypt/
└── www/
Что делает контейнер
После старта контейнер:
- запускает
cron - запускает
nginxв foreground - два раза в день вызывает
renew.sh
Скрипт renew.sh выполняет:
certbot renew --webroot -w /var/www/certbot --quiet
nginx -s reload
Первый запуск
Перейти в каталог:
cd /opt/apps/nginx
Локально в этом репозитории аналогичный путь:
cd /Users/alex/Dev_projects_v2/apps/ingress
Собрать и запустить контейнер:
docker compose up -d --build
Проверить, что nginx поднялся:
docker compose ps
docker logs nginx
После первого старта nginx уже отвечает на 80 и обслуживает путь:
/.well-known/acme-challenge/
Это нужно для выпуска сертификата через webroot.
Выпуск сертификата для существующего домена
Текущий конфиг домена лежит в conf.d/registry.lesha.spb.ru.conf.
Выпуск сертификата:
docker exec -it nginx certbot certonly \
--webroot -w /var/www/certbot \
-d registry.lesha.spb.ru \
--email you@example.com \
--agree-tos \
--no-eff-email
Сертификаты будут сохранены в:
./certbot/letsencrypt
Они переживают рестарты контейнера, потому что каталог подключён как volume.
Включение HTTPS после выпуска сертификата
В файле conf.d/registry.lesha.spb.ru.conf уже есть готовый HTTPS-блок в комментарии.
Нужно:
- раскомментировать блок
server { listen 443 ssl; ... } - при необходимости включить редирект с HTTP на HTTPS
- перезагрузить
nginx
Перезагрузка:
docker exec nginx nginx -s reload
Автообновление сертификатов
Cron создаётся в контейнере автоматически при старте.
Расписание по умолчанию:
03:1715:17
Проверить cron-задачу внутри контейнера:
docker exec nginx cat /etc/cron.d/certbot-renew
Проверить ручной запуск renewal:
docker exec nginx /usr/local/bin/renew.sh
Добавление нового домена
Для нового домена нужно создать отдельный файл в conf.d.
Пример для example.com:
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
auth_basic off;
try_files $uri =404;
}
location / {
return 404;
}
}
# После выпуска сертификата:
# server {
# listen 443 ssl;
# http2 on;
# server_name example.com;
#
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
#
# location / {
# proxy_pass http://app:8080;
# proxy_set_header Host $http_host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto https;
# }
# }
Дальше порядок такой:
- создать новый конфиг в
conf.d/<domain>.conf - проверить имя upstream, например
app:8080 - перезагрузить
nginx - выпустить сертификат через
certbot certonly --webroot - включить HTTPS-блок
- снова перезагрузить
nginx
Команда выпуска сертификата для нового домена:
docker exec -it nginx certbot certonly \
--webroot -w /var/www/certbot \
-d example.com \
--email you@example.com \
--agree-tos \
--no-eff-email
Где менять backend
Для registry.lesha.spb.ru upstream сейчас задан так:
proxy_pass http://registry:5000;
Если backend доступен по другому имени контейнера, DNS-алиасу или порту, измените это значение в conf.d/registry.lesha.spb.ru.conf.
Полезные команды
Проверка итогового compose:
docker compose config
Просмотр логов:
docker logs nginx
Проверка конфига nginx:
docker exec nginx nginx -t
Перезапуск контейнера:
docker compose restart
Важные замечания
- Модуль использует один контейнер, без отдельного
certbot-сервиса. - Выпуск сертификатов выполняется только через
webroot. - Путь
/var/www/certbotдолжен совпадать вnginx,certbotиrenew.sh. - На первом старте HTTPS не включён специально, чтобы
nginxне падал без сертификата.