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 -f
go zapisywała . Na szczęście tail
moż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.sh
bę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 -F
listy 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 -f
zachowanie (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