Select Page

Lately my sites have been exhibiting very strange behaviour. Several times per week for every site, my uptime monitor notifies me that the site is inaccessible. When I visit the problem site, it’s clear that the uptime monitor is correct – the browser throws a ERR_TOO_MANY_REDIRECTS message.

This is happening for every site using the emcniece/docker-wordpress stack. Since these sites use the ngx_cache_purge module with Nginx FastCGI caching, the problem goes away when visiting the /purge/ URL… but I can’t do this by hand every time a site goes down. What gives?!

Well, let’s start at the top. The first entrypoint is the Nginx instance responsible for caching and serving data from the WordPress/FastCGI container. The Nginx logs themselves show nothing out of the ordinary. What about the cache?

# find /tmp/cache/ -type f

The Nginx cache appears to be working properly as there are files here. These files contain HTML output from the WordPress container – they’re created when users hit each page, and they’re stored until WordPress or myself deletes them. Is the content of these files being malformed somehow?

cat /tmp/cache/3/6d/da672f7754ff0aff5d0789abe44086d3

Status: 301 Moved Permanently
X-Powered-By: PHP/7.1.16
Content-Type: text/html; charset=UTF-8

WOAH! The Nginx FastCGI cache is… caching a 301? These sites are all supposed to be SSL terminated upstream, why is this catching stuff at http addresses?

# wp option get siteurl

Well, that would be it: the WordPress container is serving content up to the Nginx FastCGI cache as http pages, while the https SSL termination happens further upstream.

Normally (without Nginx-level caching) this kind of SSL termination and traffic proxying doesn’t matter to these sites; Nginx is free to pass traffic between terminators and proxies and balancers which convert to and from HTTP/HTTPS automatically. However when we look at a scenario like this the forwarding is problematic as the redirect gets cached and looped back to the HTTP endpoint, which goes around in circles.

Solution: Set the WordPress install to the correct HTTPS URL, and install a plugin to enforce SSL on all pages!

  1. wp option set siteurl
  2. wp plugin install --activate really-simple-ssl

After doing this for all problematic sites, no more downtime 😀