238 lines
6.3 KiB
Markdown
238 lines
6.3 KiB
Markdown
# Nginx + Certbot Ingress
|
||
|
||
Этот каталог содержит автономный ingress-модуль в одном контейнере:
|
||
|
||
- `nginx` как reverse proxy
|
||
- `certbot` для выпуска и обновления сертификатов Let's Encrypt
|
||
- `cron` внутри контейнера для автообновления сертификатов
|
||
|
||
## Структура
|
||
|
||
```text
|
||
.
|
||
├── docker-compose.yml
|
||
├── Dockerfile
|
||
├── docker-entrypoint.sh
|
||
├── renew.sh
|
||
├── nginx.conf
|
||
├── conf.d/
|
||
│ └── registry.lesha.spb.ru.conf
|
||
└── certbot/
|
||
├── letsencrypt/
|
||
└── www/
|
||
```
|
||
|
||
## Что делает контейнер
|
||
|
||
После старта контейнер:
|
||
|
||
1. запускает `cron`
|
||
2. запускает `nginx` в foreground
|
||
3. два раза в день вызывает `renew.sh`
|
||
|
||
Скрипт [renew.sh](/Users/alex/Dev_projects_v2/apps/ingress/renew.sh) выполняет:
|
||
|
||
```bash
|
||
certbot renew --webroot -w /var/www/certbot --quiet
|
||
nginx -s reload
|
||
```
|
||
|
||
## Первый запуск
|
||
|
||
Перейти в каталог:
|
||
|
||
```bash
|
||
cd /opt/apps/nginx
|
||
```
|
||
|
||
Локально в этом репозитории аналогичный путь:
|
||
|
||
```bash
|
||
cd /Users/alex/Dev_projects_v2/apps/ingress
|
||
```
|
||
|
||
Собрать и запустить контейнер:
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Проверить, что `nginx` поднялся:
|
||
|
||
```bash
|
||
docker compose ps
|
||
docker logs nginx
|
||
```
|
||
|
||
После первого старта `nginx` уже отвечает на `80` и обслуживает путь:
|
||
|
||
```text
|
||
/.well-known/acme-challenge/
|
||
```
|
||
|
||
Это нужно для выпуска сертификата через `webroot`.
|
||
|
||
## Выпуск сертификата для существующего домена
|
||
|
||
Текущий конфиг домена лежит в [conf.d/registry.lesha.spb.ru.conf](/Users/alex/Dev_projects_v2/apps/ingress/conf.d/registry.lesha.spb.ru.conf).
|
||
|
||
Выпуск сертификата:
|
||
|
||
```bash
|
||
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
|
||
```
|
||
|
||
Сертификаты будут сохранены в:
|
||
|
||
```text
|
||
./certbot/letsencrypt
|
||
```
|
||
|
||
Они переживают рестарты контейнера, потому что каталог подключён как volume.
|
||
|
||
## Включение HTTPS после выпуска сертификата
|
||
|
||
В файле [conf.d/registry.lesha.spb.ru.conf](/Users/alex/Dev_projects_v2/apps/ingress/conf.d/registry.lesha.spb.ru.conf) уже есть готовый HTTPS-блок в комментарии.
|
||
|
||
Нужно:
|
||
|
||
1. раскомментировать блок `server { listen 443 ssl; ... }`
|
||
2. при необходимости включить редирект с HTTP на HTTPS
|
||
3. перезагрузить `nginx`
|
||
|
||
Перезагрузка:
|
||
|
||
```bash
|
||
docker exec nginx nginx -s reload
|
||
```
|
||
|
||
## Автообновление сертификатов
|
||
|
||
Cron создаётся в контейнере автоматически при старте.
|
||
|
||
Расписание по умолчанию:
|
||
|
||
- `03:17`
|
||
- `15:17`
|
||
|
||
Проверить cron-задачу внутри контейнера:
|
||
|
||
```bash
|
||
docker exec nginx cat /etc/cron.d/certbot-renew
|
||
```
|
||
|
||
Проверить ручной запуск renewal:
|
||
|
||
```bash
|
||
docker exec nginx /usr/local/bin/renew.sh
|
||
```
|
||
|
||
## Добавление нового домена
|
||
|
||
Для нового домена нужно создать отдельный файл в `conf.d`.
|
||
|
||
Пример для `example.com`:
|
||
|
||
```nginx
|
||
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;
|
||
# }
|
||
# }
|
||
```
|
||
|
||
Дальше порядок такой:
|
||
|
||
1. создать новый конфиг в `conf.d/<domain>.conf`
|
||
2. проверить имя upstream, например `app:8080`
|
||
3. перезагрузить `nginx`
|
||
4. выпустить сертификат через `certbot certonly --webroot`
|
||
5. включить HTTPS-блок
|
||
6. снова перезагрузить `nginx`
|
||
|
||
Команда выпуска сертификата для нового домена:
|
||
|
||
```bash
|
||
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 сейчас задан так:
|
||
|
||
```nginx
|
||
proxy_pass http://registry:5000;
|
||
```
|
||
|
||
Если backend доступен по другому имени контейнера, DNS-алиасу или порту, измените это значение в [conf.d/registry.lesha.spb.ru.conf](/Users/alex/Dev_projects_v2/apps/ingress/conf.d/registry.lesha.spb.ru.conf).
|
||
|
||
## Полезные команды
|
||
|
||
Проверка итогового compose:
|
||
|
||
```bash
|
||
docker compose config
|
||
```
|
||
|
||
Просмотр логов:
|
||
|
||
```bash
|
||
docker logs nginx
|
||
```
|
||
|
||
Проверка конфига `nginx`:
|
||
|
||
```bash
|
||
docker exec nginx nginx -t
|
||
```
|
||
|
||
Перезапуск контейнера:
|
||
|
||
```bash
|
||
docker compose restart
|
||
```
|
||
|
||
## Важные замечания
|
||
|
||
- Модуль использует один контейнер, без отдельного `certbot`-сервиса.
|
||
- Выпуск сертификатов выполняется только через `webroot`.
|
||
- Путь `/var/www/certbot` должен совпадать в `nginx`, `certbot` и `renew.sh`.
|
||
- На первом старте HTTPS не включён специально, чтобы `nginx` не падал без сертификата.
|