Three Signs You Need an Update to Your Nginx Config in Drupal 8

Greg Anderson, Open Source Contributor Reading estimate: 5 minutes

If you are still using the same Nginx configuration that you have been for Drupal 7 on your new Drupal 8 install, most things will continue to work; however, depending on the exact directives and expressions you are using, you might notice a few operational problems here and there that cause some minor difficulties.  The good news is that the Drupal configuration recipe in the Nginx documentation has been updated to work with Drupal 8, so if you have a very basic Nginx setup, you can just grab that and you’ll be good to go.  If your configuration file is a little complicated, and you do not want to just start over, the advice presented below might be helpful when fixing up any defects you may have inadvertently inherited.

[Related] Hard Things are Possible: Configuration in Drupal 8 

Here are three signs that your Nginx configuration needs some fine-tuning to work with Drupal 8:

1. Can’t Run Update.php

In Drupal 8, the update.php script now displays an instructional dialog with a “Continue” button. Clicking “Continue” will bring the user to the URL update.php/selection, which runs the actual database update operation.

Expected Result:

Clicking the “Continue” button from the update.php script should run the update operation, and then display another dialog for the user.

Symptom:

Clicking the “Continue” button from the update.php script will bring the user to the URL update.php/selection, but the user is presented with a “Page not found” error, and the update operation does not run.

Cause:

The URL update.php/selection is a little unusual, being a little bit like a clean URL, and a little bit like a mixed php-script with query parameters, except that /selection is used instead of query parameters. Some of the Nginx configuration examples were not written with these patterns in mind, so some location directives will fail to match them.

Nginx Configuration Fix:

Confirm that your location directives are not written to require that the .php extension appear on the end of the URL.

INCORRECT

location ~ \.php$ {

SUGGESTED

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

Note: The suggested URL is fairly strict, and only allows the unusual Drupal-8-style paths for the update.php front controller. Being very strict about which paths are matched allows us to continue route paths such as blog/index.php/title through Drupal, for sites that may need to maintain legacy URLs from a previous implementation. If your site does not need to route URLs that contain .php, then you might prefer to use a laxer location rule, such as:

          location ~ \.php(/|$) {

The benefit of using a less restrictive rule is that you will not need to update your Nginx configuration in the future, should a new version of Drupal start using this style of URL with front controlers other than update.php.

2. Can’t Install Modules from the Admin Interface

Drupal 7 introduced the feature that allows site administrators to install new modules from the Admin interface, simply by supplying the URL to a module download link, or by uploading a module using their web browser. This process relies on a script that determines whether the user has access rights to install modules. Under Drupal 8, this script is located at core/authorize.php; however, a bug in Drupal results in the URL core/authorize.php/core/authorize.php being used instead.

Expected Result:

When working correctly, installing a module through the admin interface will bring up a progress bar that installs the module onto the site.

Symptom:

If Nginx is not configured correctly for Drupal 8, then instead of the progress dialog, the user will see an Ajax error dialog that reports that core/authorize.php/core/authorize.php could not be found.

Cause:

When the URL core/authorize.php/core/authorize.php  is accessed on an Apache web server, it will find the authorize.php script in the correct relative location once it processes the first part of the path; the second core/authorize.php is then passed into the script as the SCRIPT_PATH, which Drupal ignores. Using some recommended configuration settings will cause Nginx to attempt to process the entirety of core/authorize.php/core/authorize.php as a single route, which it will not be able to find, causing the error.

Nginx Configuration Fix:

Change the regular expression used to partition the SCRIPT_PATH and PATH_INFO to use a non-greedy wildcard match, so that only the portion of the URL up to the first authorize.php will be included in the SCRIPT_PATH.

INCORRECT

fastcgi_split_path_info ^(.+\.php)(.*)$;

SUGGESTED

fastcgi_split_path_info ^(.+?\.php)(|/.*)$;

By default, Nginx uses a greedy match.  +? is the non-greedy variant.

3. Some Navigation Elements are Missing CSS Styling

Drupal 8 uses JavaScript to apply the class is-active to navigation elements on the that correspond to the current page that is being viewed.  This allows themers to apply CSS styles to highlight the active menu items, and so on.

Expected Result:

The styling used will vary based on the theme being used. In Classy, the default theme, if you move the main navigation menu to a side bar, then the menu item link that corresponds to the current page should be colored black instead of blue.

Symptom:

If your Nginx configuration is not correct, then the active menu item link will be styled exactly the same as all of the other menu items.

Cause:

Drupal includes attributes in the navigation page elements that indicate which pages those elements should be considered to be active. Drupal’s JavaScript in turn builds a selection expression based on the current path and query string from the current page URL. A misconfigured Nginx configuration file can cause the query string to be altered in such a way as to prevent the selection expression from matching the page elements that should have the is-active class added.

Nginx Configuration Fix:

INCORRECT

location / {
   try_files $uri @rewrite;
}

SUGGESTED

location / {
   try_files $uri /index.php?$query_string;
}

This is less likely to be encountered, because the configuration that works with Drupal 8 is the same as the one that is also recommended for Drupal 7. You will only have trouble if you use the older configuration that was recommended for Drupal 6, or some variant thereof. Of course, there is a very large variation in the kinds of configuration files that can be created with Nginx, and not all of these will look exactly like the examples shown above. Hopefully, though, these explanations will go a long way towards explaining how to correct the configuration directives you have, should you encounter any problems similar to these.

Acknowledgements

I am endebted to Damien Tournoud and Michelle Krejci, who were instrumental in analyzing these configuration issues. I would also like to thank Jingsheng Wang, who first published the update.php fix.

Topics

Share

Discover More

Safely Publish to Web from Google Docs with Pantheon Content Publisher

7 min read
Read More

Unifying Content and Code: Inside Pantheon’s Vision for Content Operations

5 min read
Read More

Where Did All the Drupal 7 Sites Go? They Moved to WordPress

6 min read
Read More

Try Pantheon for Free

Join thousands of developers, marketers, and agencies creating magical digital experiences with Pantheon.