Install and Configure WordPress on LEMP stack (Debian, Nginx, MySQL, PHP-FPM)

By November 29, 2014 Tutorial No Comments

To be able to follow this tutorial you will need to have a server (VPS or Dedicated hosting) with a LEMP stack installed and configured. To do so I recommend the following tutorials from Digital Ocean:

Once your server is ready we can start preparing for the WordPress Install. The first step is to create a couple of generic configuration files that will avoid repeating ourselves in case we want to host multiple WordPress websites on the same server.

Configure Nginx

1- Create a “global” directory (where we will put the configuration files)

mkdir /etc/nginx/global
cd /etc/nginx/global

2- Create common.conf

Open common.conf in your favourite text editor, this tutorial being for people getting started with Linux and to keep things really easy to follow, I will use nano.

nano common.conf

This command will open an empty file, paste the code below and save the file using Ctrl+x. Press y when asked if you want to save the changes.Use the command ls and you should see a file named common.conf in the current directory.

more common.conf

This will show you the content of the file common.conf.

# Global configuration file.
# ESSENTIAL : Configure Nginx Listening Port
listen 80;
# ESSENTIAL : Default file to serve. If the first file isn't found, 
index index.php index.html index.htm;
# ESSENTIAL : no favicon logs
location = /favicon.ico {
    log_not_found off;
    access_log off;
# ESSENTIAL : robots.txt
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
# ESSENTIAL : Configure 404 Pages
error_page 404 /404.html;
# ESSENTIAL : Configure 50x Pages
error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/www;
# SECURITY : Deny all attempts to access hidden files .abcde
location ~ /\. {
    deny all;
# PERFORMANCE : Set expires headers for static files and turn off logging.
location ~* ^.+\.(js|css|swf|xml|txt|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
    access_log off; log_not_found off; expires 30d;

The purpose of common.conf is to set some default settings for Nginx like the default files to serve, the listening port and when cached files expire. You can refer to the comments in the file if you are curious.

3- Create wordpress.conf

We now need to create a file that will handle WordPress specific configurations.

nano wordpress.conf

Create a wordpress.conf file the same way we created common.conf.

# WORDPRESS : Rewrite rules, sends everything through index.php and keeps the appended query string intact
location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;

# SECURITY : Deny all attempts to access PHP Files in the uploads directory
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
# REQUIREMENTS : Enable PHP Support
location ~ \.php$ {
    # SECURITY : Zero day Exploit Protection
    try_files $uri =404;
    # ENABLE : Enable PHP, listen fpm sock
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
# PLUGINS : Enable Rewrite Rules for Yoast SEO SiteMap
rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

The code above tells Nginx how to process the request for a WordPress website, it also adds some security (as you can see requests targeting the upload folder are blocked).

Now that we have created these two files we can start to work on our website configuration file. It is assumed that you already have a domain name pointing to your server.

4- Creating server blocks

There are two important folders in the /etc/nginx directory; sites-available and sites-enabled. Sites-available is where we will save the configuration for all our different websites. In sites-enabled we will create a link pointing to a configuration file (pointing to /etc/nginx/sites-available/yourfile).
Nginx retrieves all the information contained in the files within the sites-enabled folder. We will see later how to create the link between the two  folders.

For this tutorial we will assume that we want to create a website with the url I like to use the url of the website to name the configuration files of my websites, I find it easier to maintain.

Create the server block file:

nano /etc/nginx/sites-available/

Paste the following configuration:

server {
    # URL: Correct way to redirect URL's
    rewrite ^/(.*)$$1 permanent;
server {
    root /var/nginx/www/;
    access_log /var/log/nginx/;
    error_log /var/log/nginx/;
    include global/common.conf;
    include global/wordpress.conf;

Replace the with the url of your own website.

We now need to restart the Nginx service.

nginx service restart

You should see ‘nginx’ printed on the screen. If you have any error messages verify that the paths of all configuration files are correct.

Configure our database (MySQL)

We need a database to be able to save all our data, when we were setting up our server we installed MySQL. We need to create a database, create a user and configure the appropriate access for our WordPress installation. WordPress installation script will create all the necessary tables for it to be able to work properly.

First, we need to connect to MySQL.

mysql -u root -p

Enter the password that you set up when installing MySQL
You should now be connected to MySQL and see something like mysql>.

We have to create a new database for our WordPress installation and a user to be able to connect to the database.

create database wp_leedme;

First we create a new database named ‘wp_leedme’; you can chose whatever name you want,just remember it you will need it when we install WordPress.

create user wp_leedme@localhost;

Then we create a new user. Same thing applies, choose the name that you want and remember it!

set password for wp_leedme@localhost= password("MyStrongPassword");

Set a password for the newly created user, something else to remember.

grant all privileges on wp_leedme.* to wp_leedme@localhost identified by 'MyStrongPassword';

Finally give all privileges to our new user for the new database.

flush privileges;

This command will tell the server to refresh the grant table and the privileges that we have just set up will take effect.


Quit MySQL.

Setup WordPress

Now that all the the backend items are ready (we have created the configuration files for Nginx and created our database), we can start working on WordPress.

cd /usr/share/nginx/www

First, navigate to the folder where you want to install WordPress; remember we specified the path in our configuration file (/usr/share/nginx/www/


This command will create our installation directory.


Our working directory is now (or  in your case, the name of your website).

Download the latest version of WordPress, and extract all the files.


This will download a archive containing the latest stable version of WordPress.

tar -xvf latest.tar.gz

This command will extract all the files, everything should be in a ‘wordpress’ folder. If you type ls you should now be able to see the archive file and the ‘wordpress’ directory.

Open a web browser and go to, you will see that we are still not able to see our website. If we look into the sites-enabled /etc/nginx/sites-enabled/ folder there is no configuration file for our website. We need to create a link pointing to the configuration file we created earlier in the /etc/nginx/sites-availables/

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

This will create a symbolic link between the two folders. Restart the Nginx service for all changes we’ve made to take effect.

service nginx restart

Once again we should be prompted with ‘nginx’ if there is no issue, if you see any error double check your configurations files.

Now if we go to we should see a WordPress installation page.


Press the ‘Let’s go!’ button and you will be redirected to a page showing a form to enter the details of your database.


Fill in all the fields and press submit, you will be redirected to a page showing a configuration file. Copy all the content, we will need it to create a wp-config.php which holds most of the settings for our WordPress website.

Let’s go back to our server.

cd /usr/share/nginx/www/

Navigate to our wordpress installation folder.

nano wp-config.php

Open the file wp-config.php in a text editor and paste the configuration that we have just copied for the website.

We just need to modify one thing in this file, above the line /* That’s all, stop editing! Happy blogging. *\ add the following:


This will allow us to upload media later without having to use an FTP connection but simply by using the WordPress Media Manager. Close the file Ctrl+x and save the changes y.

To avoid any permission issues we will need to change the owner and the group of our wordpress directory.

cd ..
chown -R www-data:www-data wordpress/

Double check that the owner and the group changed using the command ls -al.

service nginx restart
service php-fpm restart

Restart nginx and php-fpm services and your website is now ready and entirely configured.

Happy blogging!

Leave a Reply