docker run, docker exec and logs

10,379

When you docker exec you can see you have several process

/ # ps -ef
PID   USER     TIME   COMMAND
    1 root       0:00 nginx: master process nginx -g daemon off;
    6 nginx      0:00 nginx: worker process
    7 root       0:00 /bin/sh
   17 root       0:00 ps -ef
/ # 

and in Linux, each process has its own stdin, stdout, stderr (and other file descriptors), in /proc/pid/fd

and so, with your docker exec (pid 7) you display something in

/proc/7/fd/1

If you do ls -ltr /proc/7/fd/1, it displays something like /proc/4608/fd/1 -> /dev/pts/2 which means output is being sent to terminal

while your nginx process (pid 1) displays his output in

/proc/1/fd/1

If you do ls -ltr /proc/1/fd/1, it displays something like /proc/1/fd/1 -> pipe:[184442508] which means output is being sent to docker logging driver

Share:
10,379

Related videos on Youtube

Tristan
Author by

Tristan

Updated on September 15, 2022

Comments

  • Tristan
    Tristan over 1 year

    If I do :

    docker run --name nginx -d nginx:alpine /bin/sh -c 'echo "Hello stdout" > /dev/stdout'
    

    I can see "Hello stdout" when I do :

    docker logs nginx
    

    But when the container is running (docker run --name nginx -d nginx:alpine) and I do :

    docker exec nginx /bin/sh -c 'echo "Hello stdout" > /dev/stdout'
    

    or when I attach the container with :

    docker exec -it nginx /bin/sh
    

    and then :

    echo "Hello stdout" > /dev/stdout
    

    I can't see anything in docker logs. And since my Nginx access logs are redirected to /dev/stdout, I can't see them as well.

    What is happening here with this stdout ?

  • Tristan
    Tristan about 7 years
    I'm trying to understand, but : 1. the problem is reproductible with a simple "alpine" image 2. there is only one /dev/stdout, so I guess he has to chose to which /proc/xxx/fd/1 he refers, am I wrong ?
  • Tristan
    Tristan about 7 years
    Also, are you saying these instructions from the official Nginx image will never work ? # forward request and error logs to docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log
  • Tristan
    Tristan about 7 years
    Ok, I'll answer my own questions : 1. I guess docker exec will create a shell which is not the main process 2. No, there is not only one /dev/stdout, it's a dynamic device linked to the current process 3. The instructions actually work if you don't try to display the files from inside the container, but only use "docker logs nginx" which will show both access logs and error logs. If you need persistent logs, just use volumes.
  • user3789553
    user3789553 about 3 years
    Thanks, that's a great explanation. Do you know if there is any way to force docker exec to send output to the Docker logging driver rather than back out to the calling script?
  • Mark Rajcok
    Mark Rajcok about 2 years
    @user3789553, try $ echo hello >> /proc/1/fc/1 inside the docker exec shell.