2016-01-06 13 views
23

Chcę wykonać proste logowanie do mojego serwera, który jest małą aplikacją Flask działającą w kontenerze Docker.Przekierowywanie danych wyjściowych polecenia w docker

Oto Dockerfile

# Dockerfile 
FROM dreen/flask 
MAINTAINER dreen 
WORKDIR /srv 

# Get source 
RUN mkdir -p /srv 
COPY perfektimprezy.tar.gz /srv/perfektimprezy.tar.gz 
RUN tar x -f perfektimprezy.tar.gz 
RUN rm perfektimprezy.tar.gz 

# Run server 
EXPOSE 80 
CMD ["python", "index.py", "1>server.log", "2>server.log"] 

Jak widać w ostatnim wierszu przekierować stderr i stdout do pliku. Teraz biegnę opakowanie i powłoki do niego

docker run -d -p 80:80 perfektimprezy 
docker exec -it "... id of container ..." bash 

i obserwować następujące rzeczy:

Serwer jest uruchomiony i na stronie internetowej pracuje

Nie ma /srv/server.log

ps aux | grep python plony:

root   1 1.6 3.2 54172 16240 ?  Ss 13:43 0:00 python index.py 1>server.log 2>server.log 
root  12 1.9 3.3 130388 16740 ?  Sl 13:43 0:00 /usr/bin/python index.py 1>server.log 2>server.log 
root  32 0.0 0.0 8860 388 ?  R+ 13:43 0:00 grep --color=auto python 

Ale nie ma e bez dzienników ... JEDNAKŻE, jeśli I docker attach do kontenera, widzę aplikację generującą dane wyjściowe w konsoli.

Jak poprawnie przekierować standardowe wyjście/err do pliku podczas korzystania z Docker?

Odpowiedz

23

Po określeniu listy JSON jako CMD w Dockerfile, nie zostanie wykonana w powłoce, więc zwykłe funkcje powłoki, takie jak standardowe przekierowanie stdout i stderr, nie będą działać.

Z documentation:

Formularz Exec jest analizowany jako tablicy JSON, co oznacza, że ​​trzeba użyć cudzysłowia (") wokół słowa nie apostrofy (').

W przeciwieństwie do formularza powłoki, formularz exec nie wywołuje powłoki poleceń. Oznacza to, że normalne przetwarzanie powłoki nie ma miejsca. Na przykład CMD [ "echo", "$HOME" ] nie dokona substytucji zmiennych na $HOME. Jeśli chcesz przetworzyć powłokę, użyj formularza powłoki lub uruchom powłokę bezpośrednio, na przykład: CMD [ "sh", "-c", "echo", "$HOME" ].

Co twoja komenda faktycznie robi to wykonywania skryptu index.py i przechodzącej sznurki "1>server.log" i "2>server.log" jako argumenty wiersza polecenia do tego skryptu Pythona.

Użyj jednej z następujących zamiast (oba powinny działać):

  1. CMD "python index.py > server.log 2>&1"
  2. CMD ["/bin/sh", "-c", "python index.py > server.log 2>&1"]
+0

zobacz także https://github.com/docker/docker/issues/7440 – user2915097

+2

[dokumentacja] (https: //docs.docker.com/engine/reference/builder/# shell-form-entrypoint-example) zaleca użycie wbudowanej powłoki 'exec', aby pojemniki honorowały sygnały OS i' docker stop'. Tak więc pierwsze polecenie staje się: 'CMD exec python index.py> server.log 2> & 1' – lucian

4

tylko uzupełnieniem, podczas korzystania docker-komponować, można też spróbować:

command: bash -c "script_or_command > /path/to/log/command.log 2>&1"

+0

Spróbowałeś? To ma dla mnie sens i nie działa! Jak dotąd całkowicie przekierowałem stderr do stdout, gdy używam dyrektywy 'command' w dockerze. Stdout przechodzi dobrze. –

+0

Tak, to działało idealnie dla mnie. –

+0

Ach, moim problemem okazało się, że muszę ustawić zmienną środowiskową 'PYTHONUNBUFFERED' lub uruchomić pythona z flagą' -u', co wyjaśnia: http://stackoverflow.com/a/24183941/562883 –

Powiązane problemy