При обновлении приложения через Docker Compose между остановкой старого контейнера и запуском нового возникает окно недоступности. Автор эксперимента сравнил три способа обновления — обычное пересоздание контейнера, пересоздание с healthcheck и флагом —wait, а также blue-green — на 36 прогонах и 43 200 клиентских запросах.
Лаборатория состояла из Caddy, HTTP/1.1-приложения на Python двух версий и генератора нагрузки. Приложение три секунды после запуска отвечает HTTP 503, а при SIGTERM перестаёт принимать новые запросы и до 12 секунд завершает уже принятые. Генератор проверял не только статус, но и полноту тела, согласованность версии и идентификатор запроса.
Blue-green показал лучший результат: ни одного полностью полученного ответа HTTP 502 или 503 на 14 400 попыток. Однако 11 запросов завершились транспортной ошибкой. Клиент отправлял их через уже существовавшее простаивающее соединение: в одном из прогонов две такие ошибки возникли примерно через 0,206 и 0,305 секунды после начала перезагрузки конфигурации Caddy.
Процесс Caddy при blue-green не перезапускался, но это не сохраняет каждое клиентское соединение. В отдельной проверке клиент получил корректный ответ от старой версии, следующий запрос через прежнее соединение завершился RemoteDisconnected, а новый запрос через новое соединение получил ответ от новой версии.
Уже выполнявшиеся запросы при blue-green не обрывались: шестисекундный запрос, начатый до переключения, клиент полностью получил от старой версии. При SIGTERM принятый шестисекундный запрос также завершился корректно. Автор подчёркивает разницу между сохранением активного запроса и сохранением простаивающего соединения для следующего.
Обычное пересоздание контейнера дало заметное число ошибок, а healthcheck с —wait уменьшил их, но не устранил. Флаг —wait лишь определяет момент завершения команды Compose и не создаёт резервный backend, поэтому Caddy может отправлять запросы на ещё не готовое приложение. По словам автора, главный вывод — в различии между формулировками «proxy не вернул ни одного 502» и «все клиентские запросы завершились успешно».