Здравствуйте. Есть у меня контейнер, в котором работает долгоживущее приложение (игровой бот). Это приложение ни в коем случае нельзя прибивать посреди работы (т.к. теряются данные о состоянии игры и коннект к игровому серверу). Периодически я выкатываю новые версии этого приложения и в эти моменты его нужно перезапустить, дождавшись завершения текущей работы. Т.е. перезапускать не обязательно в ту же секунду, можно подождать несколько минут или даже часов.
Использовать docker-compose stop game-bot не удалось, т.к. после SIGTERM он через 10 секунд (вроде как настраивается, но мне не удалось подождать больше 10 минут) посылает SIGKILL и контейнер жестко останавливается. К тому же я не знаю точно сколько времени ещё продлится игра.
Есть ли какое-нибудь альтернативное решение? Спасибо.
Очевидно, надо чтобы само приложение (бот), работающее в контейнере, умело реагировать на сигналы извне, форсируя своё завершение.
Например, всякие nginx и postgres отключают приём новых соединений, дорабатывает текущие, уже поступившие запросы, закрывают все соединения, файлы, сбрасывают буфера и т.д и т.п., после чего с чистой совестью завершаются.
Anton Kuzmichev: спасибо за ответ. Я так и делаю сейчас (висит обработчик, который отключается от очереди и вешает коллбэк на завершение игры), но это слишком много ручной работы (нужно постоянно следить, когда завершится приложение), хотелось бы полностью автоматизировать.
Плюс ко всему, у меня запущено несколько инстансов (docker-compose up --scale 3 game-bot) и нельзя (или я просто не знаю как) перезапустить их по отдельности.
Павел Килин: наткнулся, кстати, на параметр в docker-compose - stop_grace_period, по дефолту как раз 10 секунд. Если ваш бот требует для мягкого завершения более 10 секунд, то можно подкрутить.
В целом, докер тут вовсе не при чём, так как вопрос мягкого завершения полностью лежит на приложении.
Только что перезапустил с помощью docker-compose restart -t 3600 game-bot, он честно подождал час и только потом прислал SIGKILL. Хотя сам docker-клиент отвалился по таймауту Read timed out. (read timeout=60), но это мелочь. Думаю, придётся использовать этот способ и хорошенько обмазать скриптами, которые будут следить за состоянием и запускать новую версию.
Большое спасибо за ответы.