Этот репозиторий — готовый шаблон для развертывания production-ready reverse-proxy на Nginx. Он включает надежный процесс получения и автоматического обновления SSL-сертификатов от Let's Encrypt и CI/CD пайплайн для безопасного деплоя через self-hosted runner GitHub Actions.
У вас есть один сервер, и вы хотите:
- Запускать на нем несколько сайтов или сервисов.
- Обеспечить безопасное HTTPS-соединение для всех доменов без ручной настройки.
- Автоматизировать выкат изменений конфигурации Nginx простым
git push. - Не беспокоиться о лимитах Let's Encrypt и случайных сбоях при обновлении сертификатов.
Этот шаблон предоставляет централизованное, стабильное и автоматизированное решение для этих задач.
- Динамический Reverse Proxy: Конфигурация Nginx генерируется "на лету" из шаблона, используя переменные окружения.
- Надежное управление SSL: Однократное получение сертификата и автоматическое обновление через cron, что исключает проблемы с лимитами Let's Encrypt.
- CI/CD "из коробки": Готовый пайплайн на GitHub Actions, который при пуше в
masterобновляет только Nginx. - Безопасность: Никаких секретов и приватных данных в коде. Все управляется через GitHub Secrets.
- Разделяемая архитектура: Легко подключайте любые внешние приложения к прокси через общую Docker-сеть.
Система разделяет прокси-сервисы и ваши приложения. Они взаимодействуют через внешнюю Docker-сеть net.
- Прокси-сервис (этот репозиторий):
nginx: При старте генерирует свой конфиг изnginx.conf.template. Обрабатывает трафик, терминирует SSL и проксирует запросы.certbot: Не запускается автоматически. Используется как инструмент для ручного получения и автоматического обновления сертификатов через cron.
- Бэкенд-сервис (
your-app): Ваше приложение, подключенное к сетиnet.
- Сервер с публичным IP.
- Доменное имя, A-запись которого указывает на IP сервера.
- Установленные Docker и Docker Compose.
- Настроенный self-hosted runner GitHub Actions на сервере с доступом к Docker.
В вашем репозитории на GitHub перейдите в Settings > Secrets and variables > Actions и создайте два секрета:
DOMAIN: Ваше доменное имя (например,cloud.contributor.pw).EMAIL: Ваш email для уведомлений от Let's Encrypt.
Эту команду нужно выполнить на сервере один раз:
sudo docker network create netСделайте первый коммит и пуш в master. GitHub Actions запустит деплой. Этот первый деплой, скорее всего, завершится неудачей, так как у Nginx еще нет SSL-сертификатов. Это нормально и ожидаемо. Нам нужен запущенный Nginx, чтобы Certbot мог подтвердить владение доменом.
Теперь, когда Nginx запущен (пусть и с ошибками), выполните на сервере один раз вручную следующую команду, чтобы получить сертификаты.
Замените ВАШ_EMAIL и ВАШ_ДОМЕН вашими реальными данными в команде ниже:
sudo docker compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot --email ВАШ_EMAIL -d ВАШ_ДОМЕН --agree-tos --no-eff-emailПосле успешного выполнения этой команды, перезапустите пайплайн в GitHub Actions или сделайте еще один коммит. Теперь Nginx найдет сертификаты и запустится корректно.
Добавьте задачу в cron на вашем сервере, чтобы сертификаты обновлялись автоматически. Команды cron лучше запускать от имени root, так как docker требует sudo.
Откройте crontab для root:
sudo crontab -eИ добавьте следующую строку, заменив /path/to/your/project/ на реальный путь к вашему проекту на сервере (например, /opt/actions-runner/apps/relaxy):
30 4 * * * cd /path/to/your/project/ && docker compose run --rm certbot renew && docker compose exec nginx nginx -s reload >> /var/log/cron-cert-renew.log 2>&1Эта задача будет выполняться каждый день в 4:30 утра. Она делает три вещи:
- Пытается обновить сертификат (
certbot renew). - После попытки обновления всегда выполняет команду
nginx -s reload, чтобы применить изменения, если они были. - Записывает результат в лог-файл для отладки.
Примечание об автоматической перезагрузке Nginx: Хотя Certbot предлагает флаг
--deploy-hookдля выполнения команд только после успешного обновления, его использование в этом Docker-окружении затруднено. Команда хука выполняется внутри контейнераcertbot, у которого нет доступа кdocker composeдля перезагрузкиnginx.Подход с
&&проще и надежнее в данном контексте. Командаnginx -s reloadочень "легкая", и ее безопасный запуск (даже когда сертификат не обновлялся) не создает проблем и является прагматичным решением.
Иногда нужно проверить статус сертификатов или запустить обновление вручную. Все команды выполняются на сервере в директории проекта.
# Запускаем обновление
sudo docker compose run --rm certbot renew
# Применяем новый сертификат в Nginx
sudo docker compose exec nginx nginx -s reload1. Изнутри контейнера (проверка файла на диске)
Замените <ваш_домен> на ваш домен:
sudo docker compose exec nginx openssl x509 -in /etc/letsencrypt/live/ВАШ_ДОМЕН/fullchain.pem -noout -dates2. Снаружи (проверка того, что отдает сервер)
Эту команду можно выполнить с любого компьютера. Замените <ваш_домен> на ваш домен:
openssl s_client -connect ВАШ_ДОМЕН:443 -servername ВАШ_ДОМЕН 2>/dev/null | openssl x509 -noout -dates
#### Проверка логов Certbot
После добавления тома для логов Certbot в `docker-compose.yml`, вы можете просматривать детальные логи Certbot на хост-системе.
1. **Перейдите в директорию логов Certbot на хосте:**
```bash
cd /path/to/your/project/data/certbot/logs
```
(Замените `/path/to/your/project/` на реальный путь к вашему проекту).
2. **Просмотрите файл лога:**
```bash
tail -f letsencrypt.log
```
или
```bash
less letsencrypt.log
```
### Шаг 6: Обычный режим работы
Все готово! Теперь при каждом `git push` в `master` GitHub Actions будет автоматически и безопасно обновлять только конфигурацию Nginx.
## ➕ Как добавить новый сервис для проксирования
1. **Настройте ваше приложение**: В `docker-compose.yml` вашего приложения подключите его к сети `net`.
2. **Добавьте location в Nginx**: Откройте `nginx.conf.template` и добавьте новый `location`.
3. **Сделайте `git push`**. GitHub Actions автоматически применит новую конфигурацию Nginx.