1. Почему мой сервер останавливается при каждом деплое?
При работе над личными проектами нередко приходится补лять ограниченные ресурсы (микро‑инстансы GCP, Raspberry Pi и т.п.). Я управляю несколькими машинами: от мощных серверов для AI‑вычислений до скромных VM, едва поддерживающих DNS. Особенно мне нравится Raspberry Pi 5 — он работает круглосуточно без заметных расходов на электроэнергию и при этом достаточно производителен.
Но, как и любой «домашний питомец», если заставить его выполнять слишком много задач, появляются проблемы: при деплое процессор достигает 100 % из‑за Celery‑worker'ов. При одновременном запуске «синей» и «зелёной» групп количество воркеров удваивается, и система не справляется. Сократить их количество — значит замедлить обработку, а оставить как есть — риск полностью вывести сервер из строя.

Для решения этой задачи я создал кастомный скрипт Blue‑Green деплоя, который минимизирует расход ресурсов и сохраняет надёжность.
2. Стратегия: экономим ресурсы, повышаем стабильность
Обычный Blue‑Green деплой поднимает обе среды одновременно, но я внедрил несколько приёмов, чтобы снизить нагрузку на CPU:
- Предварительная остановка фоновых сервисов (Celery). Прежде чем запустить новый веб‑сервер, я останавливаю тяжёлые фоновые задачи (Worker, Beat) старой версии, освобождая процессор.
- Постепенный запуск. Сначала поднимаются только
Web + Redis, после чего проходит health‑check. - Human‑in‑the‑loop. После завершения автоматических шагов администратор проверяет состояние и только потом удаляет старую версию.
Проблема заключалась в том, что сразу после инициализации Celery‑worker'ы получали задачи и пытались их выполнить, что резко повышало нагрузку. Снижение параметра concurrency помогало, но замедляло асинхронную обработку, чего я не хотел.
Идея заключалась в том, чтобы на этапе пере‑деплоя временно остановить старых Celery‑друзей, освободив CPU, а затем запустить новый код без простоев.
3. Ключевые фрагменты кода
Полный проект доступен в моём GitHub‑репозитории. Ниже — несколько основных частей скрипта.
① Изоляция проектов с помощью Docker Compose
Опция docker compose -p позволяет создать отдельные проекты (namespace) blue и green даже при использовании одного и того же файла конфигурации.
dc() {
# Динамически задаём имя проекта (-p) для изоляции окружения
docker compose -f "$COMPOSE_FILE" "$@"
}
② Тщательная проверка состояния (Health Check)
Трафик переключается только после того, как новая версия полностью готова.
health_check() {
# Пытаемся получить 200 OK от указанного порта, максимум 10 попыток
if curl -fsSIL --max-time "$HEALTH_TIMEOUT" "$url"; then
ok "Health check passed"
return 0
fi
}
③ Откат в случае ошибки
Если новая версия падает, мы мгновенно восстанавливаем старые сервисы, чтобы пользователи не заметили проблем. Вместо полного rm -f для Celery‑worker'ов и beat я использую карты stop, позволяющие быстро освободить CPU и при необходимости быстро перезапустить их.
4. Практический совет: эстетика «удалять после проверки»
Последний шаг скрипта — не удалять старую версию автоматически, а вывести сообщение администратору:
"Деплой завершён успешно. Проверьте работу вручную, и если всё в порядке, скопируйте команду ниже для очистки старой версии."
Эта небольшая защита убирает 1 % ошибок, которые автоматизация могла бы пропустить.
5. Заключение
Скрипт отражает мои размышления о том, как достичь максимальной эффективности при ограниченных ресурсах. Хотя он прост, я использую его каждый день и уверен, что он будет полезен и другим разработчикам с небольшими серверами.
Полезные ссылки:
- Перейти к репозиторию на GitHub
- Система автоматического развертывания с использованием GitHub Webhook ⑤ Настройка Nginx, HTTPS и окончательная интеграция
- Пишите вопросы в комментариях или создавайте Issue в GitHub!
Комментариев нет.