How to properly test your NGINX rewrite rules

If you’re maintaining a website with over 1000 pages, redirect changes are likely something you’re having to do often. Having simple tests on your updates could save you a lot of sweat!

Potential issues

Having an untested NGINX configuration could replace all 1000 of your pages with this:

Unknown internal server error (500) YIKES!

I recently had the unholy experience of dealing with this.

Articles on how to safeguard changes to NGINX configuration files are few. This is because, in truth, safeguarding NGINX configurations can come down to one terminal command.

nginx -t

This command checks your default NGINX configuration file `/etc/nginx/nginx.conf`for syntax and then tries to open files referred to in the configuration. Adding the `-c` flag allows you to target a specific configuration file.

Our issue?

Our rewrite list, which looks something like the image below (except it’s about 9000 lines long), was hosted on an Amazon S3 bucket.

This was then copied onto an EC2 instance on every deploy. The file was then referenced by the `nginx.conf` file under the server block.

To update these rewrites, we would download them from the S3 bucket, make changes, and re-upload them — replacing the old one, after having created a backup. The deploy process would blindly copy the rewrites, and the `nginx.conf` would blindly include the rewrites — and that was that. Omit a semicolon, and fireworks would fly.

Old rewrite deploy process

The solution

Continuous integration (Test and deploy rewrite rules)

Our team decided to create a Git repository with continuous integration added to it. The benefits of this are:

  • Changes to the rewrites can be peer reviewed through pull requests
  • We can test every merge we make to the `dev` or `master` branch before deploying
  • Deploys to S3 and backups are now automatic (with diff views to see exactly what went wrong if it does)

How we did this

We used CircleCI for the continuous integration on the repository. Our workflow looks like this:

Rewrite deploy process

We begin by installing NGINX on the machine:

We then test the NGINX config:

You’ll notice that we test the `tester.conf` file. The reason we do this is that our rewrite list (previously referenced) is just a partial, inherited by the NGINX configuration file. The `tester.conf` file adds all the NGINX blocks required to make a full configuration file.

A failed test would prevent the deploy process with a descriptive message. For example:

nginx: [emerg] "server" directive is not allowed here in /root/g2a-redirects/tester.conf:1
nginx: configuration file /root/redirects/tester.conf test failed
Exited with code 1

If the test does succeed, the deploy process automatically begins. It’s described in the config below:

Note: You should have your AWS credentials kept in the settings of your CircleCI project for this step to work.

Last remarks

There is no excuse not to test. The tools are out there, and mostly free. Getting into the habit of testing every part of the process will save money, create user trust and allow you to rest easier on every deploy.

If you’d like to find out how the deployment of the Vue Nuxt build works, check this article out.