docker run, docker exec and logs
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
Related videos on Youtube
Tristan
Updated on September 15, 2022Comments
-
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 about 7 yearsI'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 about 7 yearsAlso, 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 about 7 yearsOk, 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 about 3 yearsThanks, 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 about 2 years@user3789553, try
$ echo hello >> /proc/1/fc/1
inside the docker exec shell.