Docker Community Forums

Share and learn in the Docker community.

Nginx-Log in docker-log AND in Volume possible?

Hi!
Is it possible that one can view the logs of nginx in docker-log AND at the same time pack them into a volume that is in a folder on the host?
Example:

Nginx forwards the logs from / var / logs / nginx / to stdout and stderr. This makes the logs visible in docker-logs.
As soon as I create a volume for / var / logs / nginx, the logs are only visible in the volume, but nothing is displayed in docker-logs …

Update: the text and the examples do not match?

I addressed the example:

Actualy It should be already working like this.

The Dockerfile of the image has symlinks that point to /dev/stdout and /dev/stderr:

...
  && ln -sf /dev/stdout /var/log/nginx/access.log \
  && ln -sf /dev/stderr /var/log/nginx/error.log \
...

If a volume is mounted into /var/log/nginx, the original content from the image will be invisible, and whatever is in the volume will replace the content of the folder.

If nginx complains about those missing files, you can add a custom script into /docker-entrypoint.d that can create the files for you.

If the example was just to argue that the current behavior is different, then yes you are right and it can not be changed by configuration.

You could create and put a custom script into the /docker-entrypoint.d directory, which checks if /var/log/nginx is a mountpoint and if so creates the empty files (if not existing) and then “tail” them as a background process to the console. Though, this is a rather unclean solution and will probably result in zombi porcesses when the container is finished. At this point it seems more reliable to introduce a process supervisor like s6-overlay to handle this cleanly.

Ignore the blurred content… it is possible to create a custom image that’s able to do so.

According http://nginx.org/en/docs/http/ngx_http_log_module.html:

Several logs can be specified on the same configuration level.

Thus, you could add a custom script in /docker-entrypoint.d that either modifies the nginx.conf based on /var/log/nginx beeing mounted or not. Declare two access_log declarations (the default to /var/log/nginx/access.log and the other to /dev/stdout), then use sed in your custom script to comment out the access_log /dev/stdout one if /var/log/nginx is not mounted, as in this case the default one will already send the output to /dev/stdout.

@meyay Thank you for your answer.
Can you give me please a example for the custom script in /docker-entrypoint.d ?

If you tell me which exact tag of the nginx image you use, I can see what I can come up.
But, I am not sure if I’ll be able to find time before the weekend.

Thank you for your help! I use the nginx debian latest image :slight_smile:

I was sick and then forget about your query. I had It prepared already and stumbled about a snippet when I opened visual studio code.

Something like this can be used to a) detect that /var/log/nginx is not part of the / filesystems (as in something is mounted there) and b) tail the output of /var/log/nginx/*.log:

#!/bin/bash
# set key=value result of findmnt as variable in script scope
eval $(findmnt --target /var/log/nginx --output TARGET --pairs)
if [ "$TARGET" != "/" ];then
    echo "volume mounted, tailing the output"
    tail -n1 -f /var/log/nginx/*.log &
else
    echo "no volume mounted"
fi

Thus said: the tail -f command will be prone to become a zombie-process when the container is stopped as it will be a child process of the this bash script, which will be closed when the next bash script is started and then finaly gets replaced when nginx is started with exec nginx from the entrypoint script. Also there is no way to prevent double entries in the console, if you cycle the nginx container and you already have existing logs.

Generaly: the whole idea does not realy make sense to me (which I would have pointed out earlier If I wouldn’t have been dimmed down from a flu).

You can already access the log-file from the host side without modying anything: either from the host side of a volume-mount-bind, a remote-share (if the volume points to one) or from /var/lib/docker/containers//-json.log.