Fork me on GitHub

Summary: Seravo.com heavily utilizes Nginx in both our WordPress environment and routing layer. Here’s a short description of our Nginx use

Background

Traditionally, most hosting sites have been using Apache bundled with PHP as their web server of choice. However, during the last few years many have migrated from Apache to Nginx due to performance benefits and increased flexibility.

Default settings

Nginx comes pre-configured to use with WordPress in the Seravo setup. There is no need to peruse any guides online on how to set up Nginx with WordPress.

Our default Nginx configuration includes:

  • Strong HTTPS settings (see example)
  • A Let’s Encrypt certificate for your public domains
  • HTTP cache with stale cache configured
  • Automatic expiration headers for static content
  • The Pagespeed module
  • User configurable API
  • Gzip
  • And lots more…

Configuration

In most generic Apache hosting platforms, you have the ability to use .htaccess files to add custom rules to your web server. There are multiple reasons why this is not optimal, one being the inherently slower execution time for all page loads on the site.

Instead, we give our users access to their nginx configuration through a directory that contains the .conf filesm which will be read by Nginx on startup. These configuration files can be found in /data/wordpress/nginx/*.conf.

Note: Under the hood, your custom Nginx configuration is included like this:

server {
  listen 80 default_server;
  server_name your-site.com;
  ...

  include /data/wordpress/nginx/*.conf;

  ...
}

How to create your own rules

The file /data/wordpress/nginx/examples.conf includes a few examples for you to start with, all disabled by comments. We recommend that you do not edit this file directly. Leave it as a reference instead and create your own custom.conf file from scratch.

$ cd /data/wordpress/nginx
$ nano custom.conf

To get started with your configuration you can copy stuff from examples.conf. Remove the comments from the beginning of the line and edit the rules to match the specific needs of your site.

Restarting Nginx

After you’ve made changes to your nginx configuration, please reload the configuration by running

wp-restart-nginx

If there should be any errors wp-restart-nginx will warn you about them and refuse to restart before the issue is fixed.

Examples

Forcing HTTPS

To force all your users to connect via https, you may redirect them to the https side with a Nginx configuration.

The preferred method to force HTTPS is with a custom variable.

# Force redirect http -> https
set $force_https 1;

Making exceptions to the default X-Frame-Options rule

Due to security reasons, X-Frame-Options is set for all customers of Seravo by default. Customers can set their own X-Frame-Options and thus override the default values, but it cannot be removed altogether.

This can as easily be emitted from PHP code as well with a simple header("X-Frame-Options: ALLOWALL");. To have this emitted for a section of the WordPress site, the functions.php could include something like this, for example:

if ( strpos($_SERVER['REQUEST_URI'], '/widget/') !== false ) {
  header("X-Frame-Options: ALLOWALL");
}

If a single page or a section of the site without PHP functionality needs to have a more relaxed rule to allow arbitrary access, it can be done with a rule like this:

location /widget/ {
  add_header X-Frame-Options ALLOWALL;
}

Note that ALLOWALL is not an official keyword, but most browsers support it anyway. In the future the whole X-Frame-Options header will be superseded by a new system called frame ancestors. If a site emits any frame-ancestors headers, the browser will follow those rules and ignore whatever was set in the X-Frame-Options headers.

Redirects

Basic redirects

Redirects from http://your-site.com/original -> https://example.com/new/url/

rewrite ^/original(.*)$ https://example.com/new/url$1 permanent;

Rewrite all old *.html files to WordPress pages with pretty URLS:

rewrite ^/([0-9a-z-]+)\.html /$1/ permanent;

Please use something like Rexexpal to test your regular expressions and be sure to use curl -IL to test your redirects without having to hassle with the cache of a regular browser.

Redirecting domains

If you have multiple domains for your site and want to only use one of them:

if ($host ~ "old-subdomain.your-old-site.com") {
  return 301 https://your-site.com$request_uri;
}

Serve two different sites from the same domain

Sometimes it makes sense to have two separate sites served from the same domain, as it will contribute to a better user experience and improve the search engine ranking for the content of the sites, when compared to having the site split to separate domains or subdomains. For example, the majority of the site example.com could be hosted on WordPress, but the section example.com/store might be on Magento.

This can be achieved using Nginx proxying. For example, create a file called /data/wordpress/nginx/store-proxy.conf with the contents:

location /store/ {
  proxy_ssl_server_name on;
  proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  proxy_pass https://store.example.com/;
}

The PageSpeed module

PageSpeed sniffs through your html documents and rewrites them to be faster. This process is very site specific, so make sure that you test everything carefully before enabling PageSpeed in production. You can find more about all the filters available in Google documentation.

Turn pagespeed on

pagespeed on;

Add some PageSpeed filters

# This does a lot so test which of these you really need
pagespeed EnableFilters rewrite_css,sprite_images,combine_css,inline_css,flatten_css_imports,inline_javascript,combine_javascript,inline_google_font_css,canonicalize_javascript_libraries,rewrite_images,recompress_images;

Note that with the introduction of HTTP/2, many of the techniques used by PageSpeed have become obsolete. Currently very few of our customers use PageSpeed because of the limited benefits it brings.