Комментарии 36
letsencrypt просит запускать обновления в случайное время, чтобы выровнять нагрузку серверов.
Посмотрите в сторону Traefik. Для локальной разработки генерация сертификатов через mkcert работает. Для прода прекрасно traefik и его резолвер letsencrypt работает.
Вот проблема "не системных администраторов" в том, что они описывают, а может и видят только часть картины.
А что насчёт DNS? Оно само себя настроит? Что насчёт доступа сервера наружу? И я молчу про то, что мы пихаем все в матрешку-докер.. для чего? Для однородности? Ну так обычно облачные проекты и так висят на одной версии Linux. Поставить nginx всегда можно и на локальную систему. Как и certbot прекрасно выдает серты по одной команде.
Верно, но уж про докер зря вы так. Это средство гигиены и мобильности в первую очередь.
А он тут зачем? Чтобы модно? В чем смысл этой инкапсуляции на сервере? Наоборот, оставить nginx "живым" куча преимуществ. Админить и перенастраивать его как минимум. Ну и минус накладные расходы контейнеров. Не беречь ресурсы системы - это новый тренд?
Админить и перенастраивать как раз проще докер + ансибл удалённо. Ей богу, в 2018ом всё уже перетёрли на эту тему, нет смысла в наше время копья ломать, когда технология стала мейнстримом.
Админить и перенастраивать как раз проще докер + ансибл удалённо
ансиблом в целом пофиг конфигурять софтину исполняющуюся в песочнице контейнера или на хосте, но я согласен с оратором выше что докер тут лишний оверинженеринг
недостатки в целом не очень большие: пара лишних мегобайт на диске, пара мегобайт памяти занято больше, на один лишний демон больше запущено в системе.. можно ими и пренебречь, но преимуществ то нет, ради чего?
Ну тут есть проблема только в том, что контейнер жив только когда запущен главный процесс. Это проблема инжиниринга инфры, где её можно обойти. По сути просто нужен другой подход. Тут нет ни плюсов, ни минусов.
Преимуществ масса, в первую очередь - мобильность и целостность подхода к инфраструктуре. Плюс контейнер - это самодокументация на уровне сборки. Ну серьёзно, сколько можно обсасывать одно и тоже. Всё уже проверено временем и живёт в проде годами во многих проектах.
Не надо путать тёплое с мягким. Когда у вас 100500 приложений с кучей связей требующие каждый своего рантайма конечно гораздо проще это дело контейнеризовать.
Но речь идёт про nginx и certbot. Нет смысла заморачиваться с контейнерами там где это не требуется.
И да, непонятно зачем это обсасывается рпз за разом.
Ну самый банальный пример это чтобы развернуть несколько проектов. Почему бы не поставить nginx локально на машину и закинуть куда необходимо контейнеров? В таком случае получится и прокси настраивать спокойно и контейнерами управлять. Понятное дело, что днс настраивать и в случае сброса (отключение серверов) все заново запускать, но зато не создавать конфликтов для приложений.
Именно что локально nginx.
Я не говорю, что докер не нужен. Я говорю, что он не нужен для этого применения с nginx. Сами приложения в контейнер то понятно.
чем смысл этой инкапсуляции на сервере?
Переносимость и повторяемость построенного лично вами стека практически на любом дистре (после "шлифования" сервера через Ansible, конечно). И это я не говорю про энтерпрайз, я говорю про пет-проекты.
Элементарно VPN на современных протоколах поднять лучше через Docker (ещё лучше - через Docker compose), потому что поднимать его ты будешь много раз не на одном сервере по мере роста клиентской базы и по мере развития местного "великого файрволла".
Читая статью я предполагал, что оно уже настроено и/или автор отдаёт эндпоинт не в интернеты, а специальным людям, которые уже работают с лоад балансерами, сертификатами, cloudflare/прочими cdn и т.д.. Использование сертификатов и внутреннего шифрования между серверами имеет смысл, если предполагаешь возможнось корпоративного шпионажа (у гугла были подобные инциденты например).
Не вижу проблем в докере - как команде удобнее работать - так она и делает (особенно, если это ни на что не влияет). Я бы тоже не стал выпихивалки в мир класть в докер, но управление бы оставил исключительно через систему управления конфигурациями, либо через отдельный репозиторий с линтером и прочими проверками (gitlab ci/cd например). Но опять же, нет никаких проблем с докером, если у него много согласованно работающих nginx. Про ресурсы я с вами не согласен, инфра с nginx'ами в кубе будет кушать значительно меньше (тем не менее на общем фоне эти цифры обычно несущественны).
Очень не понравилось решение из статьи.
1. Не тратим время и запускаем сертбот в стендэлон режиме, который сам будет веб сервером для проверки типа http-01
2. Не тратим время и не собираем мусор в наших системах, запускаем сертбота в энтрипоинте офф контейнера
5. Не дрочим в консоли 10 команд, а выполняем одну docker compose up -d
7. Не распыляемся на возможно отсутствующий сервис в системе и запускаем сертбот в контейнере с циклическим слипом.
Не прерываем обслуживание наших клиентов на замену ссл сертификата, а перечитываем конфиг нджинкса.
Ну и файл docker-compose.yaml, который всё это реализует:
---
version: "3"
services:
init-dhparams:
image: docker.io/certbot/certbot
restart: "no"
entrypoint: /bin/sh
command: -c 'test -f /etc/letsencrypt/ssl-dhparams.pem || openssl dhparam -out /etc/letsencrypt/ssl-dhparams.pem 4096'
volumes:
- cert_volume:/etc/letsencrypt:Z
certbot-oneshot:
image: docker.io/certbot/certbot
restart: "no"
entrypoint: /bin/sh
command: -c 'test -d /etc/letsencrypt/live/${STAND:-dev99}.${BASE_DOMAIN:-example.ru} || certbot certonly --standalone --register-unsafely-without-email -d "${STAND:-dev99}.${BASE_DOMAIN:-example.ru},sub1.${STAND:-dev99}.${BASE_DOMAIN:-example.ru}" --rsa-key-size ${rsa_key_size:-2048} --agree-tos --force-renewal'
ports:
- 80:80
volumes:
- cert_volume:/etc/letsencrypt:Z
nginx:
image: docker.io/library/nginx
entrypoint: /bin/sh
command: -c 'while :; do sleep 6h && wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'
configs:
- source: nginx-defaultserver
target: /etc/nginx/conf.d/default.conf
# deploy:
# replicas: 2
ports:
- 80:80
- 443:443
depends_on:
init-dhparams:
condition: service_completed_successfully
required: true
certbot-oneshot:
condition: service_completed_successfully
required: true
volumes:
- cert_volume:/etc/letsencrypt:Z
- acme_challenge:/usr/share/nginx/html/.well-known:Z
certbot:
image: docker.io/certbot/certbot
entrypoint: /bin/sh
command: -c 'trap exit TERM; while :; do certbot renew; sleep 24h && wait $${!}; done;'
depends_on:
nginx:
condition: service_started
required: true
volumes:
- cert_volume:/etc/letsencrypt:Z
- acme_challenge:/usr/share/nginx/html/.well-known:Z
volumes:
cert_volume: {}
acme_challenge: {}
configs:
nginx-defaultserver:
content: |
upstream back {
server back-api:8000;
resolver 127.0.0.11 valid=30s;
resolver_timeout 5s;
}
server {
server_name _ default_server;
listen 443 ssl http2;
# мы уже примонтировали сертификаты в Docker Compose
ssl_certificate /etc/letsencrypt/live/${STAND:-dev99}.${BASE_DOMAIN:-example.ru}/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/${STAND:-dev99}.${BASE_DOMAIN:-example.ru}/key.pem;
location / {
proxy_pass http://back;
}
}
server {
listen 80;
server_name _ default_server;
charset utf-8;
# max upload size
client_max_body_size 10M;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html =502;
}
error_page 500 502 503 504 /502.html;
location = /502.html {
root /usr/share/nginx/html;
internal;
}
# Django project's static files
location /static {
proxy_pass https://back;
expires max;
etag on;
}
# send REST API request to Django
location /api {
proxy_pass https://back;
proxy_pass_header X-CSRFToken;
proxy_pass_header X-RecaptchaResponse;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Заключение, статья мусор, больше половины выкинуть.
Что сказать... образцовый compose файл!
Один вопрос, а зачем мы там постоянно в sleep циклах ещё wait $${!}
делаем? Вроде фоновых процессов нет никаких
На самом деле есть, там бесконечный луп в фоне, это конструкция для периодического релоада конфига нджинкса. Это нужно для активации новых сертификатов и\или перечитывания конфига нджинкс, потому что не хотелось ipc неймспейс шарить между контейнером с сертботом и атомарно разделить возможность обновления контейнеров без потенциальных сайд эффектов.
да-да, это все понятно. я именно про инструкцию wait ${!}
которая после sleep ожидает завершения каких-то фоновых процессов. Но у нас там их нет. Тут я занудствую, потому что или я что-то не понимаю, или это просто осталось от похожего композа, где действительно были фоновые процессы.
Ну и добавлю свои 5 копеек: nginx -g "daemon off;"
лучше запускать exec nginx -g "daemon off;"
тогда он наследует PID 1 в контейнере и будет принимать на себя все сигналы.
Да, для нджинкс у меня другая конструкция, как вы описываете:entrypoint: /bin/sh
command: -c 'while :; do sleep 6h; nginx -s reload; done & exec nginx -g "daemon off;"'
Без wait ожидания и с корректным завершением работы контейнера по сигналу.
А вот для сертбота с ожиданием, и ожидает как раз событие перехвата сигнала завершения работы SIGTERM, для корректного завершения работы контейнера по команде.entrypoint: /bin/sh
command: -c 'trap -- "exit 0" SIGTERM ; while :; do certbot renew; sleep 24h & wait $${!}; done;'
спасибо за пример файла. Добавлю, что если в конфигурации сервера не определен путь корня
root /usr/share/nginx/html;
то его надо явно прописать в команду certbot renew:
command: -c 'trap exit TERM; while :; do certbot renew --webroot -w /usr/share/nginx/html; sleep 24h && wait $${!}; done;'
иначе получите ошибку Invalid response from .well-known/acme-challenge/... : 404
Да, для врача на RHEL 9.3 можно по полочкам так же разложить? Без докера.
Для автоматизации получения сертификатов использую это https://github.com/nginx-proxy/acme-companion и это https://github.com/nginx-proxy/nginx-proxy
Компаньон отвечает за получение и продление сертификатов, nginx-proxy генерирует конфиги.
много лет юзаю nginx-le.. https://hub.docker.com/r/umputun/nginx-le
ссыль на проект https://github.com/nginx-le/nginx-le
Выше писали про траефик и про проблему статьи, в части того, что она не решает внешний вопрос с днс. Траефик умеет и сертификаты и днс и крон.
1 Nginx Proxy Manager https://nginxproxymanager.com/
2 >Кстати, я разработал мониторинг сайтов. Если сайт упал, он шлёт уведомление в Telegram. И умеет заранее предупреждать об истечении SSL сертификата.
Есть ответ, для кого оно актуально! Для личинки девопса :) В моем лице, например. Пытаюсь простенький сайт на джанге задеплоить. Всё по описанным шагам, но... nginx | 2024/11/12 12:31:28 [emerg] 1#1: cannot load certificate "/etc/fullchain.pem": PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE)
nginx | nginx: [emerg] cannot load certificate "/etc/fullchain.pem": PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE) nginx exited with code 1
Таки оно умное и файл со словом temp внутри кушать не хочет.
Оставлю сообщение для тех, кто пришёл из Гугла.
В nginx, начиная с версии 1.25.3, в стандартной комплектации (за исключением *-slim образов), даже в nginx-alpine, идёт модуль njs (ngx_http_js_module). Это динамический модуль, добавляющий интерпретатор Javascript'а, называющийся QuickJS, от небезызвестного Фабриса Беллара, для конфигурации nginx.
На базе него есть официальный проект у nginx'а - https://github.com/nginx/njs-acme. Буквально строчкой в вашем Dockerfile и парой строчек в конфиге nginx'а Вы сможете реализовать получение сертификатов из ACME-совместимого источника.
Как выдавать бесплатные SSL сертификаты с помощью certbot, Nginx и Docker