$ docker ps Container Status ... myapp up 4 minutes ...
Attach также ничего не отображает:
$ docker attach --sig-proxy=false myapp (working, no output)
Есть идеи, что происходит не так? "Print" ведет себя по-другому при запуске в фоновом режиме?
Версия для Docker:
Client version: 1.5.0 Client API version: 1.17 Go version (client): go1.4.2 Git commit (client): a8a31ef OS/Arch (client): linux/arm Server version: 1.5.0 Server API version: 1.17 Go version (server): go1.4.2 Git commit (server): a8a31ef
Переведено автоматически
Ответ 1
Наконец-то я нашел решение, позволяющее видеть вывод Python при запуске daemonized в Docker, благодаря @ahmetalpbalkan на GitHub. Отвечаю на него здесь сам для дальнейшей справки. :
Использование небуферизованного вывода с
CMD ["python","-u","main.py"]
вместо
CMD ["python","main.py"]
решает проблему; теперь вы можете видеть выходные данные (как stderr, так и stdout) через
- printis indeed buffered and docker logs will eventually give you that output, just after enough of it will have piled up - executing the same script with python -u gives instant output as said above - import logging + logging.warning("text") gives the expected result even without -u
что это означает под python -u ref. > python --help | grep -- -u
-u : force the stdout and stderr streams to be unbuffered;
Ответ 2
В моем случае запуск Python с -u ничего не изменил. Однако хитрость заключалась в том, чтобы установить PYTHONUNBUFFERED=1 в качестве переменной окружения:
docker run --name=myapp -e PYTHONUNBUFFERED=1 -d myappimage
[Редактировать]: Обновлено PYTHONUNBUFFERED=0 до PYTHONUNBUFFERED=1 после комментария Ларса. Это не меняет поведение и добавляет ясности.
Ответ 3
Если вы хотите добавить выходные данные для печати в выходные данные Flask при запуске docker-compose up, добавьте следующее в свой файл docker compose.
Смотрите Эту статью, в которой подробно объясняется причина такого поведения:
Обычно существует три режима буферизации:
Если дескриптор файла не буферизован, то буферизация вообще не происходит, и вызовы функций для чтения или записи данных происходят немедленно (и блокируются).
Если файловый дескриптор полностью буферизован, то используется буфер фиксированного размера, и вызовы read или write просто считывают или записывают данные из буфера. Буфер не очищается до тех пор, пока он не заполнится.
Если файловый дескриптор буферизован по строкам, то буферизация ожидает появления символа перевода строки. Таким образом, данные будут буферизоваться до тех пор, пока не будет видно \n, а затем все данные, которые были буферизованы, будут сброшены в этот момент времени. На самом деле обычно существует максимальный размер буфера (как и в случае с полной буферизацией), поэтому правило на самом деле больше похоже на “буфер до появления символа новой строки или 4096 байт данных, в зависимости от того, что произойдет раньше”.
А GNU libc (glibc) использует следующие правила для буферизации:
Stream Type Behavior stdin input line-buffered stdout (TTY) output line-buffered stdout (not a TTY) output fully-buffered stderr output unbuffered
Итак, если использовать -t из документа docker, оно выделит псевдо-tty, затем stdout становитсяline-buffered, таким образом, docker run --name=myapp -it myappimage можно увидеть однострочный вывод.
И, если просто использовать -d, не был выделен tty, то, stdout is fully-buffered, одна строка App started наверняка не сможет очистить буфер.
Тогда используйте -dt to make stdout line buffered или добавьте -u в python к flush the buffer - это способ исправить это.