Modular approach to Nginx/Openresty configuration

This tries to instill the idea that using Nginx or openresty is not that complicated. Quite the contrary: I find it much easier to configure than Apache! So this configuration tries to be as less intrusive as possible. For a more complete configuration, refers to the Nginx webserver configuration by @chillu.

Firstly, let’s create a configuration for running generic PHP scripts:

# snippets/php7.conf

# Regex to split $uri to $fastcgi_script_name and $fastcgi_path
# XXX: the matching is greedy, so `/slug.php/script.php/other/params`
# is handled properly but `/slug/script.php/other/params.php` is not!
fastcgi_split_path_info ^(.+\.php)(/.*)?$;

# Bypass the fact that try_files resets $fastcgi_path_info
# https://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

# `fastcgi_params` is provided directly by Nginx
include fastcgi_params;

# Use $realpath_root instead of $document_root
# https://deployer.org/docs/7.x/avoid-php-fpm-reloading
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

# Using a different PHP version just requires a change to the following line
fastcgi_pass unix:/run/php/php7.2-fpm.sock;

Then, a basic configuration for Silverstripe4:

# snippets/silverstripe4-php7.conf

error_page 404 /assets/error-404.html;
error_page 500 /assets/error-500.html;

# Defend against SS-2015-013
# http://www.silverstripe.org/software/download/security-releases/ss-2015-013
if ($http_x_forwarded_host) {
    return 400;
}

# Entry point: no other PHP files must be present in the webroot
# (otherwise they are sent as plain text to the client)
location = /index.php {
    include snippets/php7.conf;
}

# Assume anything accessible by default: this is correct **only** if
# `public` webroot folder is used (Silverstripe >= 4.1)
location / {
    try_files $uri /index.php?$args;
}

# Protected assets support
location /assets/.protected/ {
    return 403;
}

# Silverstripe insists in creating this file
location = /assets/.htaccess {
    return 404;
}

With that in place, creating new virtual hosts is quite easy:

server {
    listen 80
    server_name mysite1;
    root /path/to/mysite1/public;
    include snippets/silverstripe4-php7.conf;
}

server {
    listen 80
    server_name mysite2;
    root /path/to/mysite2/public;
    include snippets/silverstripe4-php7.conf;
}

server {
    listen 443 ssl;
    server_name myencryptedsite;
    root /path/to/myencryptedsite/public;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    include /path/to/generic/encrypt/configuration.conf;
    include snippets/silverstripe4-php7.conf;
}
2 Likes