web-dev-qa-db-fra.com

Redirection du résultat de la commande dans le menu fixe

Je souhaite effectuer une journalisation simple pour mon serveur, qui est une petite Flask exécutée dans un conteneur Docker.

Voici le 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"]

Comme vous pouvez le voir sur la dernière ligne, je redirige stderr et stdout vers un fichier. Maintenant, je lance ce conteneur et Shell dedans

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

Et observez les choses suivantes:

Le serveur est en marche et le site Web fonctionne

Il n'y a pas /srv/server.log

ps aux | grep python donne:

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

Mais il n'y a pas de journaux ... CEPENDANT, si je docker attach au conteneur, je peux voir l’application générer une sortie dans la console.

Comment rediriger correctement stdout/err vers un fichier lorsque Docker est utilisé?

44
Dreen

Lorsque vous spécifiez une liste JSON sous la forme CMD dans un Dockerfile, elle ne sera pas exécutée dans un shell. Par conséquent, les fonctions habituelles du shell, telles que la redirection stdout et stderr, ne fonctionneront pas.

De la documentation :

Le formulaire exec est analysé comme un tableau JSON, ce qui signifie que vous devez utiliser des guillemets doubles (") autour de mots autres que des guillemets simples (').

Contrairement au formulaire Shell, le formulaire exec n'invoque pas de commande Shell. Cela signifie que le traitement Shell normal ne se produit pas. Par exemple, CMD [ "echo", "$HOME" ] ne fera pas de substitution de variable sur $HOME. Si vous souhaitez un traitement Shell, utilisez le formulaire Shell ou exécutez-le directement, par exemple: CMD [ "sh", "-c", "echo", "$HOME" ].

Ce que fait réellement votre commande, c'est en exécutant votre index.py script et transmission des chaînes "1>server.log" et "2>server.log" comme arguments de ligne de commande dans ce python script .

Utilisez plutôt l'un des éléments suivants (les deux devraient fonctionner):

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

Juste un complément, en utilisant docker-compose, vous pouvez également essayer:

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

8
Jing Li

Utiliser docker run dans un pipeline Shell ou sous une redirection Shell, pour que run accepte stdin et affiche les sorties stdout et stderr de manière appropriée, utilisez cette incantation:

docker run -i --log-driver=none -a stdin -a stdout -a stderr ...

par exemple. pour exécuter l'image Alpine et exécuter la commande UNIX cat dans l'environnement contenu:

echo "This was piped into docker" |
  docker run -i --log-driver=none -a stdin -a stdout -a stderr \
    Alpine cat - |
  xargs echo This is coming out of docker: 

émet:

This is coming out of docker: This was piped into docker
7