Skip to main content
DevOpsbeginner

Where Are Nginx Logs Stored? Default Paths (Ubuntu, CentOS, Docker)

Find nginx access and error logs at /var/log/nginx/. Exact paths for Ubuntu, Debian, CentOS, Docker, and macOS, plus how to tail and rotate them.

8 min readUpdated June 2026

Want us to handle this for you?

Get expert help →

Nginx writes two logs by default: the access log at /var/log/nginx/access.log and the error log at /var/log/nginx/error.log. These paths are identical on Ubuntu, Debian, RHEL, CentOS, and Fedora when nginx is installed from the distro or official nginx package. The locations are controlled by the access_log and error_log directives in /etc/nginx/nginx.conf, and individual server {} blocks frequently override them with per-site files such as /var/log/nginx/example.com.access.log.

Quick Reference: Nginx Log File Paths

Platform / Install methodAccess logError log
Ubuntu / Debian (apt)/var/log/nginx/access.log/var/log/nginx/error.log
RHEL / CentOS / Fedora (yum/dnf)/var/log/nginx/access.log/var/log/nginx/error.log
nginx.org official repo/var/log/nginx/access.log/var/log/nginx/error.log
Source build (default prefix)/usr/local/nginx/logs/access.log/usr/local/nginx/logs/error.log
Homebrew (macOS, Intel)/usr/local/var/log/nginx/access.log/usr/local/var/log/nginx/error.log
Homebrew (macOS, Apple Silicon)/opt/homebrew/var/log/nginx/access.log/opt/homebrew/var/log/nginx/error.log
Docker (official image)stdout (docker logs)stderr (docker logs)
Per-site (common override)/var/log/nginx/<site>.access.log/var/log/nginx/<site>.error.log

The startup error log — written before nginx reads its config — is also compiled in at build time. Check it with nginx -V 2>&1 | tr ' ' '\n' | grep error-log.

How to View and Tail Nginx Logs

Follow the live access log:

sudo tail -f /var/log/nginx/access.log

Follow the error log and access log together:

sudo tail -f /var/log/nginx/error.log /var/log/nginx/access.log

Find the last 50 errors:

sudo tail -n 50 /var/log/nginx/error.log

Filter the access log for a specific status code (502 Bad Gateway here):

sudo grep ' 502 ' /var/log/nginx/access.log

Count requests per IP address (top 10 talkers):

sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

Inside Docker, logs go to the container's stdout/stderr:

docker logs -f <container>
docker logs --tail 100 <container>

Finding the Exact Path When It Varies

Never guess. Have nginx tell you the resolved paths:

sudo nginx -T 2>&1 | grep -E 'access_log|error_log'

nginx -T dumps the fully merged configuration including every included file, so you see every log directive across all server blocks. Lines reading access_log off; confirm logging is intentionally disabled for that scope.

Ubuntu / Debian Detail

The package ships a global error_log /var/log/nginx/error.log; and access_log /var/log/nginx/access.log; in /etc/nginx/nginx.conf. Site configs live in /etc/nginx/sites-available/ and typically add their own per-host log files. To change a path, edit the directive and reload:

sudo nano /etc/nginx/nginx.conf
sudo nginx -t && sudo systemctl reload nginx

RHEL / CentOS / Fedora Detail

Paths match Debian, but SELinux governs where nginx may write. If you move logs outside /var/log/nginx/, restore the correct context or nginx will be denied:

sudo semanage fcontext -a -t httpd_log_t "/data/logs(/.*)?"
sudo restorecon -Rv /data/logs

Config lives in /etc/nginx/nginx.conf with extra files under /etc/nginx/conf.d/.

Docker Detail

The Dockerfile for the official image contains ln -sf /dev/stdout /var/log/nginx/access.log and ln -sf /dev/stderr /var/log/nginx/error.log. That is why docker logs works out of the box and why there are no files to tail inside the container. To persist real files, mount a volume and replace the symlinks:

docker run -v /host/nginx-logs:/var/log/nginx mynginx

Confirm where a running container sends its logs:

docker inspect --format '{{.LogPath}}' <container>

Changing the Log Location and Format

Set a named log format and direct it to a custom file in nginx.conf or a server block:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" "$http_user_agent"';

access_log /var/log/nginx/custom.access.log main;
error_log  /var/log/nginx/custom.error.log warn;

The error log's second argument is the level: debug, info, notice, warn, error, crit, alert, or emerg. Lower levels produce more output.

Log Rotation

Logrotate handles nginx on package installs. The config is /etc/logrotate.d/nginx:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
    endscript
}

The postrotate USR1 signal tells nginx to reopen its log files after rotation so it keeps writing to the fresh file rather than the renamed one. Test rotation without waiting a day:

sudo logrotate -f /etc/logrotate.d/nginx

Common Errors You'll Find in Nginx Logs

  • connect() failed (111: Connection refused) while connecting to upstream — the backend (PHP-FPM, app server) is down or listening on a different port; surfaces to clients as 502.
  • upstream timed out (110: Connection timed out) — backend took longer than proxy_read_timeout; raise the timeout or fix the slow backend, results in 504.
  • open() "/var/www/html/x" failed (13: Permission denied) — nginx's worker user (www-data or nginx) cannot read the file; fix ownership or permissions.
  • directory index of "/var/www/html/" is forbidden — no index file and autoindex off; serves a 403.
  • SSL_do_handshake() failed — TLS negotiation problem, often a client using an unsupported protocol or a bad certificate chain.
  • worker_connections are not enough — the worker hit its connection limit; raise worker_connections in the events {} block.

Troubleshooting: Logs Missing or Empty

  • Logging disabledaccess_log off; in a server or location block silences requests served there. Confirm with nginx -T.
  • Wrong file — the request is matched by a different server block that writes to its own per-site log. Match the server_name and listen to find the right file.
  • Permissions — your user cannot read /var/log/nginx/. Use sudo, or add yourself to the adm group on Debian.
  • Errors before config load — syntax errors and startup failures go to the compiled-in default log or to the systemd journal: journalctl -u nginx.
  • Docker — there are no files inside the official image; use docker logs. Files only exist if you removed the stdout/stderr symlinks.
  • Not reloaded — after editing a path, run sudo nginx -t && sudo systemctl reload nginx; without a reload nginx keeps writing to the old file.
Stop tailing logs by hand

Get alerted when your logs go wrong

Alert24’s lightweight agent watches your log files where they live and alerts on error spikes, pattern matches, log floods, and sudden silence — no log shipping, no SIEM bill, no per-GB ingest pricing.

Try Alert24 log monitoring

Frequently Asked Questions

Find answers to common questions

On Debian and Ubuntu the default error log is /var/log/nginx/error.log. On RHEL, CentOS, and Fedora it is the same path, /var/log/nginx/error.log. The location is set by the error_log directive in /etc/nginx/nginx.conf and can be overridden per server block.

Run nginx -T to dump the full resolved configuration, then filter with nginx -T 2>&1 | grep -E 'access_log|error_log'. This shows every access_log and error_log directive across the main config and all included files, including paths defined inside individual server blocks.

The official nginx image symlinks /var/log/nginx/access.log to stdout and /var/log/nginx/error.log to stderr, so logs appear via docker logs rather than as files. To keep them as files, mount a volume to /var/log/nginx or remove the symlinks in a custom image.

An empty access.log usually means logging was disabled with access_log off; in the server or location block, requests are being served by a different server block with its own log file, or nginx was not reloaded after a config change. Run nginx -T to confirm which log file applies to the request you expect.

On Debian and Ubuntu, logrotate rotates nginx logs daily and keeps 14 compressed copies via /etc/logrotate.d/nginx. On RHEL the same file rotates daily with a shorter retention. Rotation sends nginx a USR1 signal so it reopens its log files without dropping connections.