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