Rotating Nginx log files via Cron

A tutorial on how you can set up a simple Cron job to run a bash script that will rotate and compress Nginx log files for you automatically each day.

Nginx is a great web server, however a default install will not rotate log files for you. This is a problem especially on busy sites, as the access log can eat up disc space quite quickly.

In this tutorial, I will show you how you can set up a simple Cron job to run a bash script that will rotate and compress these log files for you automatically each day.

The bash script

First we need to create the new bash script that will do the log rotation (this is based off the example from the Nginx wiki 1):

nano /usr/local/sbin/
chmod 770 /usr/local/sbin/

The second command will make it executable. You can place this script anywhere you want, but I like to use /usr/local/sbin/ as it is on the path for most users.

Here are the contents of the script:

DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

The script makes copies of the access and error logs to new files appended with the current date and time. These new files are then compressed to save disc space. For example access.log becomes access.log.2013-02-15-0100.gz when this script is ran at 1:00 on 2013-02-15.

The "kill -USR1..." command requires a little explanation. It does not actually kill the Nginx process (which has it's process ID or "PID" stored in /var/run/ on my machine, hence the cat), but instead it takes an action defined by that particular application when this SIGUSR1 signal is received. In the case of Nginx, it will re-open its logs. The "sleep 1" adds some delay afterwards before we attempt to compress the rotated logs.

Running the script via Cron

As root (or other user with appropriate permissions):

crontab -e

Now add:

00 01 * * * /usr/local/sbin/ > dev/null 2>&1

The new script will now run at 1:00AM each day, adjust as required. For an explanation of what the > dev/null 2>&1 commands do, please see Suppressing Cron Job Email Notifications.


John Collins

I have been writing about web technology and software development since 2001. I am the developer of the Alpha Framework for PHP, and the personal productivity app. I love open source, technology, and economics.