В другом вопросе « Убить дочерний процесс при выходе из родительского процесса» я получил ответ, который помог разобраться в этом.
Таким образом, мы настраиваем приложение таким образом, чтобы оно регистрировалось в файл и непрерывно 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