En otra pregunta, Matar proceso infantil cuando el padre sale , obtuve la respuesta que ayudó a resolver esto.
De esta manera, configuramos la aplicación para que se registre en un archivo y continuamente tail -f
. Afortunadamente, tail
puede aceptar --pid PID
: saldrá cuando finalice el proceso especificado. Ponemos $$
allí: PID del shell actual.
Como paso final, la aplicación iniciada se exec
edita, lo que significa que el shell actual se reemplaza completamente con esa aplicación.
El script del corredor run.sh
, se verá así:
#! /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
NOTA: al usar tail -F
, enumeramos los nombres de los archivos, ¡y los leerá incluso si aparecen más tarde!
Finalmente, el minimalista Dockerfile:
FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']
Nota: para solucionar un tail -f
comportamiento extremadamente extraño (que dice "ha sido reemplazado por un archivo remoto. Renunciar a este nombre") probé otro enfoque: todos los archivos de registro conocidos se crean y truncan al inicio: de esta manera me aseguro de que existan , y solo entonces - seguirlos:
#! /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