У меня есть докер-контейнер с установленным и настроенным ПО.
Нет никакой программы, которая должна запускаться / работать все время.
Что хочу - возможность запускать какую-то команду в зависимости от внешних событий. лайк:
docker exec mysupercont /path/to/mycommand -bla -for
и
docker exec mysupercont /path/to/myothercommand
Но "exec" невозможно, когда контейнер остановлен, а также у этого контейнера есть некоторые "рабочие" данные внутри, которые используются для этих команд, поэтому я не могу использовать
docker run ...
каждый раз, потому что он воссоздает контейнер из изображения и уничтожает мои данные.
Каков «правильный» и «лучший» способ поддерживать работу такого контейнера? Какую команду я могу запустить внутри?
Не нужно выполнять каждый раз docker run
.
docker run
фактически представляет собой последовательность из двух команд: «создать» и «запустить».
При запуске контейнера необходимо указать "-it
":
-i, --interactive = false Оставить STDIN открытым, даже если он не подключен
-t, --tty = false Назначить псевдо-TTY
Пример:
docker run -it debian:stable bash
После завершения работы команда указывается при запуске (в моем примере bash). Например, вы выполняете «выход». Контейнерные остановки:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1329c99a831b debian:stable "bash" 51 seconds ago Exited (0) 1 seconds ago goofy_bardeen
Теперь ты можешь начать снова
docker start 1329c99a831b
Контейнер запускается и снова выполняет команду «bash».
Подключитесь к этому сеансу "bash" с помощью команды
docker attach 1329c99a831b
Подводить итоги: вы должны понимать разницу между run
и start
контейнер.
Кроме того, посмотрите на документация на роль параметров "-i t
" и "-d
"для" Бега "
Весь этот вопрос о том, можете ли вы запустить остановленный контейнер, зависит от того, как контейнер был первоначально создан, т.е. запущен. Если вы выполнили команду, которая завершилась, или вы вышли из интерактивной команды, например bash, вы не можете запустить, перезапустить или выполнить остановленный контейнер. Все, что вы можете сделать, это удалить его. Это мусор.
Но последний комментарий Таранаки, использование '-itd', похоже, является тем, что заказал докер.
Контейнер продолжает работать, и вы можете выполнять все, что хотите, а также останавливать, запускать или перезапускать контейнер. Конечно, это лишь предварительная находка, основанная на альпийском снимке. Обратите внимание: если вы прикрепитесь к контейнеру, он остановится при выходе, но вы можете запустить его снова.
Поскольку вы упомянули периодические задачи и, вероятно, используете что-то вроде cron из-за того, как вы хотите использовать docker exec
, У меня есть только лекарство для тебя. По крайней мере, я сделал что-то подобное.
Dockerfile
FROM <some base>
CMD tail -f /dev/null
Беги как обычно docker run -d ....
(Я использовал docker-compose
)
Настройте crontab на хост-машинах, например:
* * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
* * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
Я считаю это решение хорошим, поскольку мы можем полагаться на древний и проверенный crontab в довольно стандартной среде Linux, в то время как Docker обрабатывает более экзотические зависимости и переменные среды вашей бизнес-логики. Вы также можете установить некоторые ограничения, если ваши периодические задачи застревают и имеют утечки памяти или что-то еще.
Tail будет время от времени вызывать некоторые файловые операции.
Вот мое решение уснуть вечно без каких-либо побочных эффектов.
# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!
Как это устроено
while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $! # stop the background process of doing nothing
wait $! # wait forever, because doing nothing process is stopped