Greg Anderson, Open Source Contributor Reading estimate: 5 minutes
Three Signs You Need an Update to Your Nginx Config in Drupal 8
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
Discover More
Safely Publish to Web from Google Docs with Pantheon Content Publisher
Roland Benedetti (Senior Director, Product) and Zack Rosen (Co-Founder)
Reading estimate: 7 minutes
Unifying Content and Code: Inside Pantheon’s Vision for Content Operations
Chris Yates
Reading estimate: 5 minutes
Where Did All the Drupal 7 Sites Go? They Moved to WordPress
Josh Koenig
Reading estimate: 6 minutes