Have nginx access_log and error_log log to STDOUT and STDERR of master process


Solution 1

Edit: it seems nginx now supports error_log stderr; as mentioned in Anon's answer.

You can send the logs to /dev/stdout. In nginx.conf:

daemon off;
error_log /dev/stdout info;

http {
  access_log /dev/stdout;

edit: May need to run ln -sf /proc/self/fd /dev/ if using running certain docker containers, then use /dev/fd/1 or /dev/fd/2

Solution 2

If the question is docker related... the official nginx docker images do this by making softlinks towards stdout/stderr

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

REF: https://microbadger.com/images/nginx

Solution 3

Syntax: error_log file | stderr | syslog:server=address[,parameter=value] | memory:size [debug | info | notice | warn | error | crit | alert | emerg];
error_log logs/error.log error;
Context:    main, http, stream, server, location


Don't use: /dev/stderr This will break your setup if you're going to use systemd-nspawn.

Solution 4

For a debug purpose:

/usr/sbin/nginx -g "daemon off;error_log /dev/stdout debug;"

For a classic purpose

/usr/sbin/nginx -g "daemon off;error_log /dev/stdout info;"


Under the server bracket on the config file

access_log /dev/stdout;

Solution 5

When running Nginx in a Docker container, be aware that a volume mounted over the log dir defeats the purpose of creating a softlink between the log files and stdout/stderr in your Dockerfile, as described in @Boeboe 's answer.

In that case you can either create the softlink in your entrypoint (executed after volumes are mounted) or not use a volume at all (e.g. when logs are already collected by a central logging system).


Related videos on Youtube

Author by


Hi, I run a web application development consultancy in New York City. Check us out here: http://honeyco.nyc/

Updated on July 14, 2022


  • quinn
    quinn over 1 year

    Is there a way to have the master process log to STDOUT STDERR instead of to a file?

    It seems that you can only pass a filepath to the access_log directive:

    access_log  /var/log/nginx/access.log

    And the same goes for error_log:

    error_log /var/log/nginx/error.log

    I understand that this simply may not be a feature of nginx, I'd be interested in a concise solution that uses tail, for example. It is preferable though that it comes from the master process though because I am running nginx in the foreground.

    • czerasz
      czerasz almost 8 years
      Using Nginx inside a Docker container? Checkout this answer.
    • Farshid T
      Farshid T over 5 years
      The accepted answer (Patrick's) works for official Nginx Docker images (hub.docker.com/_/nginx).
  • Jon Tirsen
    Jon Tirsen over 9 years
    When I try to do this I get the following error: 2014/07/29 10:19:09 [emerg] 13742#0: open() "/dev/stdout" failed (13: Permission denied)
  • Patrick
    Patrick over 9 years
    Jon, what system are you on? On my system, /dev/stdout is world-readable symlink to /dev/fd/1 which is owned and read+writeable by my user.
  • Jon Tirsen
    Jon Tirsen about 9 years
    Ubuntu 12.04. It seems the problem was that I was using runit chpst to change the user. This means stdout is owned by root and then changed to run as the nginx user.
  • Charles Duffy
    Charles Duffy about 9 years
    I'm seeing this fail with ENXIO when stdout is open to a socket rather than a file. There's an upstream kernel ticket indicating that this is deliberate and by intent: bugzilla.kernel.org/show_bug.cgi?id=1360 -- thus, while this answer is sufficient in some cases, it doesn't fully cover the range of possible failures.
  • Ivan Kleshnin
    Ivan Kleshnin over 8 years
    Lost a few hours on this without any success. Tried to change everything (daemon modes, users, nginx versions etc). It just does not work for me. """open() "/dev/stderr" failed (6: No such device or address)""" (same issues with stdout, but nginx should output to stderr according to docs)
  • kondor
    kondor over 8 years
    I've done this in my dockerfile but it's doesn't work RUN ln -sf /proc/self/fd /dev/ RUN sed -i 's/access_log.*/access_log \/dev\/fd\/1;/g' /etc/nginx/nginx.conf && sed -i 's/error_log.*/error_log \/dev\/fd\/2 info;/g' /etc/nginx/nginx.conf
  • Dobes Vandermeer
    Dobes Vandermeer about 8 years
    Inside a docker you may get permission denied if your process doesn't run as root in the container. There's a fix coming for this in the next version.
  • jonashackt
    jonashackt over 5 years
    This answer is mostly correct, but sadly not for the alpine images (see github.com/nginxinc/docker-nginx/blob/master/stable/alpine/…‌​), only for the others like jessie do use this statement. If you´re an alpine user, just create your own Dockerfile with FROM nginx:alpine RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log CMD ["nginx-debug", "-g", "daemon off;"]
  • Farshid T
    Farshid T over 5 years
    Patrick's answer works for official nginx images (hub.docker.com/_/nginx), both debian (latest) and alpine bases.
  • peedee
    peedee almost 5 years
    Your REF link appears to be dead.
  • peedee
    peedee almost 5 years
    I have an nginx container that doesn't run as root, and this answer does not solve that case. Still looking for solution.
  • Qiulang
    Qiulang over 4 years
    @jonashackt I used alpine images and I found it also logged to stdout
  • samayo
    samayo about 4 years
    did anyone find a solution. my nginx server desider not to run without any edits, it just decided to shut down .. wtf
  • qräbnö
    qräbnö almost 4 years
    Click on a version (hub.docker.com/_/nginx) to see the docker file with the aforementioned line (somewhere before line 100).
  • ErikE
    ErikE about 3 years
    Do not use /dev/sdtout or /dev/stderr. Use stdout or stderr.
  • ch271828n
    ch271828n almost 3 years
    @jonashackt New versions of alpine do work now github.com/nginxinc/docker-nginx/blob/master/stable/alpine/…