add: Nginx и Certboot в Docker (4)

This commit is contained in:
Sergei Erjemin 2025-02-14 02:26:33 +03:00
parent 6470803172
commit 2b9a7e7c7c

View File

@ -23,8 +23,6 @@ Nginx с SSL-сертификатами Let's Encrypt в контейнерах
mkdir -p /home/web/docker-data/portainer mkdir -p /home/web/docker-data/portainer
``` ```
## Nginx в контейнере Docker
Теперь создадим каталог для хранения конфигурационных файлов Nginx. Сам Nginx будет сидеть в контейнере, но Теперь создадим каталог для хранения конфигурационных файлов Nginx. Сам Nginx будет сидеть в контейнере, но
конфигурационные файлы, которые он будет использовать, находятся на хосте в каталоге `/home/web/docker-data/nginx/conf.d`: конфигурационные файлы, которые он будет использовать, находятся на хосте в каталоге `/home/web/docker-data/nginx/conf.d`:
```bash ```bash
@ -140,7 +138,7 @@ docker-compose up -d
После того как контейнеры запустятся, можно зайти в веб-интерфейс Portainer по адресу `http://portainer.you.domain.name`. После того как контейнеры запустятся, можно зайти в веб-интерфейс Portainer по адресу `http://portainer.you.domain.name`.
## Let's Encrypt в контейнере Docker ## Добавляем контейнер Let's Encrypt
Создадим каталог для хранения ключей сертификатов Let's Encrypt и временных файлов для проверки владения доменом: Создадим каталог для хранения ключей сертификатов Let's Encrypt и временных файлов для проверки владения доменом:
```bash ```bash
@ -192,10 +190,9 @@ mkdir -p /home/web/docker-data/letsencrypt/_ownership_check
- `trap exit TERM;` — устанавливаем обработчик сигнала `TERM`, чтобы контейнер certbot корректно завершал работу; - `trap exit TERM;` — устанавливаем обработчик сигнала `TERM`, чтобы контейнер certbot корректно завершал работу;
- `while :; do sleep 12h & wait $${!}; certbot renew --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh; done` - `while :; do sleep 12h & wait $${!}; certbot renew --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/restart-nginx.sh; done`
— это скрипт, который запускается при старте контейнера certbot. Он запускает certbot в режиме `renew` каждые 12 часов. — это скрипт, который запускается при старте контейнера certbot. Он запускает certbot в режиме `renew` каждые 12 часов.
Таким образом, сертификаты будут автоматически обновляться каждые 12 часов. Таким образом, сертификаты будут автоматически провереться каждые 12 часов и обновляться, если это необходимо.
Также нам нужно добавить маппинг тома для сертификатов Let's Encrypt в контейнере `nginx`. Теперь описание этого контейнера
Также нам нужно добавить маппинг тома для сертификатов Let's Encrypt в контейнере nginx. Теперь описание этого контейнера
в `docker-compose.yml` будет выглядеть так: в `docker-compose.yml` будет выглядеть так:
```yaml ```yaml
nginx: nginx:
@ -213,7 +210,7 @@ mkdir -p /home/web/docker-data/letsencrypt/_ownership_check
- web - web
``` ```
*Тут теперь происходит очень похожий маппинг тома для сертификатов Let's Encrypt и временных файлов для проверки *Тут происходит очень похожий маппинг тома для сертификатов Let's Encrypt и временных файлов для проверки
владения, но теперь для контейнера nginx*: владения, но теперь для контейнера nginx*:
- `volumes: ...`: - `volumes: ...`:
@ -224,7 +221,7 @@ mkdir -p /home/web/docker-data/letsencrypt/_ownership_check
Сохраняем файл `docker-compose.yml`. Сохраняем файл `docker-compose.yml`.
Теперь нам нужно настроить nginx, чтобы он мог отдавать временные файлы Certbot. Для этого временно изменим конфигурационный файл Теперь нам нужно настроить nginx, чтобы он мог отдавать временные файлы Certbot. Для этого изменим конфигурационный файл
`/home/web/docker-data/nginx/conf.d/portainer.conf` на следующий: `/home/web/docker-data/nginx/conf.d/portainer.conf` на следующий:
```nginx configuration ```nginx configuration
server { server {
@ -248,12 +245,13 @@ server {
} }
``` ```
Как видно, мы добавили новый `location` блок, который отдает временные файлы Certbot из каталога `/var/www/letsencrypt/` Как видно, мы добавили новый *location*-блок, который отдает временные файлы Certbot из каталога `/var/www/letsencrypt/`
(а это каталог контейнера nginx, который мы ранее замаппили в каталог хоста `/home/web/docker-data/letsencrypt/_ownership_check`). (а это каталог контейнера `nginx`, который мы ранее замаппили в каталог хоста `/home/web/docker-data/letsencrypt/_ownership_check`).
Он явно указывает, что запросы к `/.well-known/acme-challenge/` не должны идти через прокси, а должны обслуживаться локально. Он явно указывает, что запросы к `/.well-known/acme-challenge/` не должны идти в прокси, а должны обслуживаться локально.
Используя директиву `location ^~` — она приоритетнее `location /` и так location будет работать даже при включённом proxy_pass. Используем директиву `location ^~` — она приоритетнее `location /` и такой *location* будет срабатывать даже при
включённом proxy_pass.
**Важно!** После того как сертификаты Let's Encrypt будут получены, не надо удалять этот `location` блок из конфигурации! **Важно!** После того как сертификаты Let's Encrypt будут получены, не надо удалять этот `location ^~` из конфигурации!
Он нужен для автоматического обновления сертификатов. При обновлении сертификатов certbot будет снова создавать Он нужен для автоматического обновления сертификатов. При обновлении сертификатов certbot будет снова создавать
временные файлы в каталоге `/var/www/letsencrypt/` а Let's Encrypt проверять их доступность. Если nginx не сможет отдать временные файлы в каталоге `/var/www/letsencrypt/` а Let's Encrypt проверять их доступность. Если nginx не сможет отдать
эти файлы, то обновление сертификатов не произойдет. эти файлы, то обновление сертификатов не произойдет.
@ -277,7 +275,7 @@ docker run --rm --name letsencrypt-certbot \
--agree-tos --no-eff-email --force-renewal --agree-tos --no-eff-email --force-renewal
``` ```
Если все пройдет успешно (должно пройти успешно) мы увидим примерно такой вывод: Если все пройдет успешно (должно пройти) мы увидим примерно такой вывод:
```text ```text
certbot certonly --webroot -w /var/www/html -d portainer.you.domain.name --email email@you.domain.name --agree-tos --no-eff-email --force-renewal certbot certonly --webroot -w /var/www/html -d portainer.you.domain.name --email email@you.domain.name --agree-tos --no-eff-email --force-renewal
Saving debug log to /var/log/letsencrypt/letsencrypt.log Saving debug log to /var/log/letsencrypt/letsencrypt.log
@ -298,10 +296,10 @@ If you like Certbot, please consider supporting our work by:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
``` ```
Если у вас что-то пойдёт не так, то скорее всего вы что-то напутали в маппингах томов, или в конфигурации nginx. И еще Если у вас что-то пойдёт не так, то скорее всего что-то напутано в маппингах томов, или в конфигурации nginx. Вы можете
вы можете посмотреть логи certbot (вам придется змапить каталог для логов из контейнера certbot на хост). посмотреть логи certbot (возможно вам придется замаппить каталог логов из контейнера certbot на хост).
Уже хочется проверить, что все работает? Рано! Теперь нам нужно добавить в конфигурацию nginx SSL-сертификаты и настроить Уже хочется проверить, что все работает? Рано! Нам нужно добавить в конфигурацию nginx SSL-сертификаты и настроить
перенаправление с HTTP на HTTPS. Отредактируем конфиг nginx, теперь он будет выглядеть так: перенаправление с HTTP на HTTPS. Отредактируем конфиг nginx, теперь он будет выглядеть так:
```nginx configuration ```nginx configuration
server { server {
@ -362,7 +360,6 @@ docker-compose up -d
Теперь можно проверить, что все работает, и зайдите в веб-интерфейс Portainer по адресу `https://portainer.you.domain.name`. Теперь можно проверить, что все работает, и зайдите в веб-интерфейс Portainer по адресу `https://portainer.you.domain.name`.
Осталось проверить, что перевыпуск сертификатов будет происходить и мы всё ещё ничего не сломали в мапингах: Осталось проверить, что перевыпуск сертификатов будет происходить и мы всё ещё ничего не сломали в мапингах:
```bash ```bash
docker exec -it letsencrypt-certbot certbot renew --dry-run -v docker exec -it letsencrypt-certbot certbot renew --dry-run -v