Series Part IV — Optimizing Nginx for Drupal 8.x and PHP 7.x
There are two main sources of truth here. Drupal.org doesn’t seem to have an “official” recommendation, which is kinda surprising.
- Nginx’s Recipe for Drupal 8: https://www.nginx.com/resources/wiki/start/topics/recipes/drupal/
- Optimizing Nginx for Drupal 8, by Pantheon’s own Greg Anderson (2015): https://pantheon.io/blog/update-your-nginx-config-drupal-8
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:
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:
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.
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
.
Doing a docker-compose exec nginx sh
into the container confirms that after reloading the Nginx service the config file is updated:
After reloading the update.php
page and hitting the continue button, I am presented with this:
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:
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.
- The listen directive
listen 8080
is on port 8080 because I am running Nginx as a non-root user usingsu-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.
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!