W innym pytaniu: Zabij proces potomny, gdy rodzic wyjdzie , otrzymałem odpowiedź, która pomogła rozwiązać ten problem.
W ten sposób konfigurujemy aplikację, aby logowała się do pliku i ciągle tail -fgo zapisywała . Na szczęście tailmoże zaakceptować --pid PID: zakończy działanie po zakończeniu określonego procesu. Umieszczamy $$tam: PID bieżącej powłoki.
Ostatnim krokiem jest uruchomienie uruchomionej aplikacji exec, co oznacza, że bieżąca powłoka została całkowicie zastąpiona przez tę aplikację.
Skrypt runner run.shbędzie wyglądał następująco:
#! /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
UWAGA: korzystając z tail -Flisty nazw plików, odczytamy je, nawet jeśli pojawią się później!
Wreszcie minimalistyczny plik Docker:
FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']
Uwaga: aby obejść bardzo dziwne tail -fzachowanie (które mówi „został zastąpiony plikiem zdalnym. Rezygnacja z tej nazwy”) wypróbowałem inne podejście: wszystkie znane pliki dziennika są tworzone i obcinane przy uruchamianiu: w ten sposób upewniam się, że istnieją i tylko wtedy - ogonić je:
#! /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