Wednesday, February 15, 2017

Installing Wordpress on PHP7, Nginx & Ubuntu 16.04 With SSL Support


Nginx Wordpress Logo
This tutorial assumes you already have LEMP installed on Ubuntu 16.04 with PHP7 & PHP-FPM. If you don't have anything installed yet, you can find a tutorial on how to do it in here.

For this tutorial, I'll assume you are logged in as root. Ideally however, you must use a non-root username and prefix all the commands with sudo.

Update your packages

apt-get update && apt-get upgrade

Install PHP Packages that Wordpress will use

apt-get install php-xmlrpc php-xml php-gd php-mbstring php-curl php-mcrypt

Restart PHP-FPM

systemctl restart php7.0-fpm

Configure Nginx

I'll assume my website is called mysite.com and the configuration file will be called mysite.com as well (you can call them differently)

First, create the directly where the SSL certificate & key will be uploaded (Even if you won't use SSL, proceed with this step)
mkdir /var/www/mysite.com

And create the directory where wordpress will be uploaded
mkdir /var/www/mysite.com/html

Secondly, create the nginx configuration file:
vi /etc/nginx/sites-available/mysite.com

server {

    # Force Redirect to www, change server_name according to your needs

    server_name mysite.com;

    rewrite ^/(.*)$ http://www.mysite.com/$1 permanent;

}

server {

    # Domain name
    server_name www.mysite.com;

    # Location of files
    root /var/www/mysite.com/html;

    # Location of access & error Logs, you can call them anything you like
    access_log /var/log/nginx/www.mysite.com.access.log;
    error_log /var/log/nginx/www.mysite.com.error.log;

    # Listen to Port 80 (http)
    listen 80;

    #Listen on SSL with http2 support
    listen 443 ssl http2 default_server;
    ssl_certificate /var/www/mysite.com/ssl.cert;
    ssl_certificate_key /var/www/mysite.com/ssl.key;


    # Default file to serve. If the first file isn't found,
    index index.php index.html index.htm;

    # Don't log favicons
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    # Configuring robots.txt and disable its logging
    location = /robots.txt {
         allow all;
         log_not_found off;
         access_log off;
    }

    # Configure 404 Pages
    error_page 404 /404.html;


    # Configuring Error 50x Pages
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/www;
    }


    # Denying all attempts to access hidden files (example .htaccess)
    location ~ /\. {
         deny all;
    }

    # Expiry date 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;
    }

    # Rewrite rules, sends everything through index.php
    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    # Deny access to PHP Files in the uploads directory
    location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
    }

    # Enable PHP Support
    location ~ \.php$ {
       include snippets/fastcgi-php.conf;
       fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    # 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;

    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;
}

If you enable listening on port 443, make sure to have the ssl files in their appropriate location (As defined in the configuration file)
/var/www/mysite.com/ssl.cert
/var/www/mysite.com/ssl.key

Create a link (shortcut) in sites-enabled

ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

(Optional) Disable the default server_name by deleting its link

unlink /etc/nginx/sites-enabled/default

Test nginx settings & syntax

nginx -t

Reload nginx configuration

systemctl reload nginx

Create new Database User and Table

Login into database:

mysql -u root -p 

Create database table:

I'll call it wpdb in this example,
CREATE DATABASE wpdb DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;


Create database user and grant the user all the privileges, I'll call the user wpuser:

GRANT ALL ON wpdb.* TO 'wpuser'@'localhost' IDENTIFIED BY 'password'; 

Flush the Database for the changes to take effects immediately:

FLUSH PRIVILEGES;

Exit the Database

Exit

Installing Wordpress

Go to the previously created directory

cd /var/www/mysite.com/html

Download latest Wordpress version

https://wordpress.org/latest.tar.gz

Uncompress it

gunzip latest.tar.gz

tar -xvf latest.tar

Remove latest.tar

rm latest.tar

The files will be located in a directory called wordpress, move them outside it

mv wordpress/* .

Delete the empty Wordpress directory

rm -rf wordpress

Change owner of the files from nobody to www-data

chown -R www-data:www-data *

Install Wordpress from the domain name you entered in server_name in the configuration file, your domain must be pointed.
Example: http://xxx.xxx.xxx.xxx
Where xxx.xxx.xxx.xxx is your server's IP address or domain name

Follow the instructions and use the database credentials you created earlier on.



Any questions or suggestions, post them below!