In un'altra domanda, uccidi il processo figlio quando il genitore esce , ho ottenuto la risposta che mi ha aiutato a risolvere questo problema.
In questo modo, configuriamo l'applicazione in modo che registri su un file e continuamente tail -f
. Fortunatamente, tail
può accettare --pid PID
: uscirà quando termina il processo specificato. Mettiamo $$
lì: PID della shell corrente.
Come passaggio finale, l'applicazione avviata viene exec
"modificata", il che significa che la shell corrente viene completamente sostituita con tale applicazione.
Runner script, run.sh
sarà simile al seguente:
#! /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: usando tail -F
elenchiamo i nomi dei file, e li leggerà anche se compaiono in seguito!
Infine, il Dockerfile minimalista:
FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']
Nota: per ovviare a un tail -f
comportamento estremamente strano (che dice "è stato sostituito con un file remoto. Rinunciando a questo nome") ho provato un altro approccio: tutti i file di registro noti vengono creati e troncati all'avvio: in questo modo mi assicuro che esistano e solo allora - seguili:
#! /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