How to setup WordPress with NGINX on Debian testing

NGINX is a powerful web server and I wanted to give it a try for some time now.

Its setup is rather simple and pretty straight forward in my humble opinion.

The current settings are for PHP 7.0 using php7.0-fpm under GNU / Debian testing 64-bit.

The first thing to look for is whether cgi.fix_pathinfo is 0 or not inside our /etc/php/7.0/fpm/php.ini.

If it's not, give it the value 0 as it has been a subject of multiple discussions around security. I think it has been resolved for a quite a while now, but it would not harm to turn it off.

Next thing we do is to create our own WordPress virtual host server settings:

server {
    listen 80;
    listen [::]:80;


    root /var/www/html/wordpress;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm;

    server_name wpdebian.cy;
    server_tokens off; # removes NGINX version

    try_files $uri $uri/ /index.php?$args;

    # deny access to files like .htaccess
    location ~ /\.ht {
        deny all;
    }

    location / {

        try_files $uri $uri/ /index.php?q=$uri&$args;

        # Show "Not Found" 404 errors in place of "Forbidden" 403 errors
        error_page 403 =404;

        location ~ ^/(.+\.php)$ {
            include /etc/nginx/snippets/stefanos.conf;
        }

        # Secure the following files from getting accessed
        location = /xmlrpc.php { deny all; }
        location = /license.txt { deny all; }
        location = /readme.html { deny all; }
        location = /wp-config.php { deny all; }
        location = /wp-admin/install.php { deny all; }

    }
}

The code above I have saved it in a file named wpdebian.cy and is located in /etc/nginx/sites-available/ directory; you can name it anything you want that could represent you or your project.

If you haven't noticed already, I have included a custom snippet file named stefanos.conf which is located in /etc/nginx/snippets/ directory.

The reason I have done so is because the same code snippet is used elsewhere, in a different server {} and I wanted to avoid unnecessary duplication.

Here's the code snippet:

try_files $uri =404;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;

Save the code inside the aforementioned inclusion path: /etc/nginx/snippets/stefanos.conf

Of course, change the snippet name accordingly.

Now, let's see how my default server {} setup looks like:

# Default server configuration

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    server_name _;
    server_tokens off;


    location / {
        index index.php index.html index.htm;
        try_files $uri $uri/ =404;
        autoindex on; # enabling directory listing
    }

    location ~ ^/(.+\.php)$ {
        include /etc/nginx/snippets/stefanos.conf;
    }

    location /phpmyadmin {
        root /usr/share/;
        index index.php index.html index.htm;

        # set client body size to 3M
        client_max_body_size 3M;

        location ~ ^/phpmyadmin/(.+\.php)$ {
            root /usr/share/;

            include /etc/nginx/snippets/stefanos.conf;
        }
        location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
            root /usr/share/;
        }
    }

    location /phpMyAdmin {
        rewrite ^/* /phpmyadmin last;
    }

}

These settings are inside /etc/nginx/sites-enabled/default, which by the way, this file is a symlink located in /etc/nginx/sites-available/default.

Basically what this setup does is to be used as our standard localhost setup; this way we are able to run http://localhost/phpmyadmin/ or http://localhost/foo-file.php...you get the idea.

Now, about symlinking, we are going to do the same thing to our wpdebian.cy file so we can enable it.

Here is the command:

sudo ln -s /etc/nginx/sites-available/wpdebian.cy /etc/nginx/sites-enabled/

Next thing we do is to add our domain name inside our /etc/hosts file and associate it with the IP it represents our local user; in my case it's 192.168.2.3.

So your /etc/hosts should look something like this:

...
...
...
192.168.2.3 wpdebian.cy

By the way, the dots used above are used as an indication that other existing settings that reside inside the file remain as is.

In order to apply the domain name changes, we need to restart our networking service.

sudo systemctl restart networking.service

Logically, it should take a couple of seconds to apply the changes and should not complain about anything. If it does, it means you have messed up with something while typing it; most probably you forgot to add a space between the IP address and the domain name or something else you need to resolve yourself via trial and error.

Lastly, we run a test command for NGINX so it can report back to us whether it liked our settings or not and if everything looks OK and behave as expected, we are going to restart our server and start using our website.

sudo nginx -t

If everything went well, run this command.

sudo systemctl restart nginx.service

That's it folks. We have successfully created our standard default setup and our custom WordPress virtual host server.

If anyone is facing any kind of problem around these settings, feel free to comment below so we can investigate it together.