web-dev-qa-db-fra.com

docker-compose n'imprime pas stdout dans Python

Lorsque vous utilisez une instruction print() dans une application Python exécutée dans un conteneur Docker géré par Docker Compose, seule la sortie sys.stderr Est enregistrée. Vanilla print() les instructions ne sont pas vues, donc ceci:

print("Hello? Anyone there?")

... n'apparaît jamais dans les journaux réguliers:

enter image description here

(Vous pouvez voir d'autres journaux explicitement imprimés par d'autres bibliothèques dans mon application, mais aucun de mes propres appels.)

Comment puis-je éviter que mes appels print() soient ignorés?

16
Lee Benson

Par défaut, Python tamponne la sortie vers sys.stdout.

Il y a quelques options:

1. Appelez un flush explicite

Refactorisez l'instruction d'impression d'origine pour inclure un flush=True mot clé, comme:

print("Hello? Anyone there?", flush=True)

Remarque: Cela entraînera le vidage du tampon , et pas seulement le même appel d'impression. Donc, s'il y a des appels de fonction d'impression `` nus '' ailleurs (c'est-à-dire sans flush=True) qui n'étaient pas explicitement non tamponnés, ceux-ci seront toujours vidés également.

Vous pourriez réaliser la même chose avec:

import sys
sys.stdout.flush()

Cette option est utile si vous voulez avoir le plus de contrôle sur lorsque le rinçage se produira.

2. Débuffer l'application entière via le PYTHONUNBUFFERED env var

Déposez ce qui suit dans la section environment de votre docker-compose.yml fichier:

PYTHONUNBUFFERED: 1

Cela entraînera le vidage immédiat de toutes les sorties vers stdout.

3. Exécutez python avec -u

Comme l'option n ° 2 ci-dessus, cela entraînera Python à exécuter "sans tampon" sur toute la durée de vie de votre application. Exécutez simplement avec python -u <entrypoint.py> - pas besoin de la variable d'environnement.

21
Lee Benson

Si vous ajoutez l'option -u dans la ligne d'exécution du Dockerfile, il imprimera vos journaux:

CMD ['python', '-u', 'my_python_script.py']
10
Ignacio Peletier