В другом вопросе « Убить дочерний процесс при выходе из родительского процесса» я получил ответ, который помог разобраться в этом.
Таким образом, мы настраиваем приложение таким образом, чтобы оно регистрировалось в файл и непрерывно tail -f
его. К счастью, tail
может принять --pid PID
: он выйдет при выходе из указанного процесса. Мы помещаем $$
туда: PID текущей оболочки.
В качестве последнего шага запущенное приложение exec
редактируется, что означает, что текущая оболочка полностью заменена этим приложением.
Скрипт бегуна run.sh
, будет выглядеть так:
#! /usr/bin/env bash
set -eu
rm -rf /var/log/my-application.log
tail --pid $$ -F /var/log/my-application.log &
exec /path/to/my-application --logfile /var/log/my-application.log
ПРИМЕЧАНИЕ: используя tail -F
список имен файлов, он будет читать их, даже если они появятся позже!
Наконец, минималистичный Dockerfile:
FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']
Примечание: для работы с очень странным tail -f
поведением (которое говорит «был заменен удаленным файлом. Отказывается от этого имени»), я попробовал другой подход: все известные файлы журналов создаются и усекаются при запуске: таким образом, я гарантирую, что они существуют и только потом - хвост им:
#! /usr/bin/env bash
set -eu
LOGS=/var/log/myapp/
( umask 0 && truncate -s0 $LOGS/http.{access,error}.log )
tail --pid $$ -n0 -F $LOGS/* &
exec /usr/sbin/apache2 -DFOREGROUND