Series Part IV — Optimizing Nginx for Drupal 8.x and PHP 7.x

Callback Insanity
5 min readJan 4, 2020
Photo by Daniel von Appen on Unsplash

There are two main sources of truth here. Drupal.org doesn’t seem to have an “official” recommendation, which is kinda surprising.

There is a Github repo by perusio mentioned around Drupal.org that contains some advanced configuration for Nginx, but this D.O. post flags the configuration on that repository as over-engineered I am going to heed that advice. However I still mention it because it might be interesting to peruse for advanced edge-case scenarios.

So far the Nginx configuration I copied and pasted from I-don’t-remember-where is mostly working. While installing the experimental Unami Food Magazine profile, I did run into some styling issues, which usually suggest one of or two things: 1) Missing file permissions (this would be inside the PHP container, in this case PHP-FPM), or; 2) Missing web server configuration — which would be Apache, Nginx, etc.

On the last story I wrote I chose to install the “standard” Drupal profile, which comes with a relatively-minimal set of Drupal modules installed — instead of going for the Unami profile.

After perusing the error logs post-install, I did not notice any style errors, there was however this:

core/install.php/path not found

And that brings us to today’s story. In today’s story I’m going to verifying Nginx’s configuration using Greg Anderson’s 2018 post for reference.

Check access to update.php

First bring up my local Docker stack:

Then visit localhost/update.php in the browser:

Everything looks good …

Then as advertised on Greg’s post, localhost/update.php/selection kindly reminds us that the Nginx configs are not quite set up for Drupal 8.

update.php/selection request forwarded to Drupal by Nginx, but Drupal serves it’s 404

I swtich my Nginx config from

location ~ \.php$ {

to

location ~ '\.php$|^\/update.php' {

then do a restart of Nginx so it loads the new config, which is mounted into /etc/nginx/conf.d/default.conf .

maybe, maybe … maybe?

Doing a docker-compose exec nginx sh into the container confirms that after reloading the Nginx service the config file is updated:

Logging to an existing service
Changes are reflected inside the container

After reloading the update.php page and hitting the continue button, I am presented with this:

success !!

The Official Nginx Template Doesn’t Work

If this is the case for you, good news: it did not work for me out of the box either.

This is the line that was preventing update.php/selection from working using the unadulterated Nginx template:

# Ensure the php file exists. Mitigates CVE-2019-11043
try_files $uri =404;

When that line is enabled, instead of being redirected to Drupal’s 404 page, I get Nginx’s 404 page instead:

Nginx 404 page is different from Drupal 404 page.

After deleting or commenting out that line, I was able to visit update.php/selection .

Below is the final nginx config that I am using:

Here are some notable difference from the Nginx template are.

  1. The listen directive listen 8080 is on port 8080 because I am running Nginx as a non-root user using su-exec , and non-root users don’t have access to ports below 1000 by default:
exec su-exec nobody /usr/sbin/nginx -g "daemon off;"

2. I removed the following 404 line from the template:

# try_files $uri =404;

3. My fastcgi_pass instruction does not use a unix socket. A socket would be used if Nginx was running in the same host as PHP-FPM was. But here in containerland Nginx and PHP-FPM run in different containers, so they talk over the local Docker host network using Docker Compose service names.

The PHP-FPM container is run by the name of php-fpm service in Docker Compose, and so it’s reachable at that DNS name php-fpm. The php-fpm service also exposes port 9010 for PHP requests, and so my Nginx directive ends up being:

fastcgi_pass php-fpm:9010;# where it's
fastcgi_pass [ip address or dns name]:[port where php-fpm listens]

Instead of:

# PHP 5 socket location.
#fastcgi_pass unix:/var/run/php5-fpm.sock;

Certifying Image Styles work in Drupal 8

To verify that image styles are working and that Nginx is not giving any issues due to configuration, I head to image styles configuration page under config, media: http://localhost/admin/config/media/image-styles.

There’s a selection of styles shown there you can use for testing or you can create your own. I did both.

Select Edit Style
Click on the derived image test to the right, not the original
You should be able to see this page

If Drupal has any issues generating styles due to files permissions (that would be the inside the PHP-FPM container), or because of Nginx directives — it would show here.

Luckily for me the rest of the directives on the default Nginx template for Drupal 8 seem to work well for Image Styles and so with that I conclude this story about optimizing Nginx for use with Drupal 8 and Docker.

On the next part of this Docker series I’ll write how to optimize the size of my Docker images for Composer and Drush.

Until next time!

--

--

Callback Insanity

Organic, fair-sourced DevOps and Full-Stack things. This is a BYOB Establishment — Bring Your Own hipster Beard.