Install WordPress on Ubuntu with Nginx, PHP, MySQL


Creating and managing servers has now become a part of my daily life. Along with it, my love for Linux has also matured up to such level that I do not see myself going back to Windows in future again (Sorry Microsoft, if that hurts). For me setting up servers has become a cup of tea while I still see newly born developers around me struggling to get started with basic things like installing WordPress if they do not get access to cPanel. Yes, I mean if they get handed VPS or simply any bare metal server, they are unable to set things up. Thus, I am writing this article here to help those fellow devs easily install WordPress on Ubuntu (with Nginx, PHP and MySQL) and figure out how things work when you do not have cPanel or anything similar.

Login w/ SSH

You need to have shell/SSH access to your (new and untouched) VPS server and prior to that, you need to have a VPS server. If you got one, all good. Otherwise, friends at DigitalOcean got some really affordable pricing plans to get started with. Other providers worth considering are Vultr, Linode and AWS (Lightsail).

While creating a server, make sure to select Ubuntu 16.04, preferably 64-bit as your OS template.

Once you have a server up and running, SSH into it as root using below command (replace XXX.XXX.XXX.XXX with your server IP):

ssh ubuntu@XXX.XXX.XXX.XXX

If you have got the server hosted by AWS, login as ubuntu user:

ssh root@XXX.XXX.XXX.XXX

Install WordPress

Once logged in, update apt cache and upgrade any upgrade-able packages:

sudo apt update
sudo apt upgrade -y

After it completes, we can now start installing required packages that are Nginx, PHP, MySQL and other dependencies.

sudo apt install mysql-server nginx php-fpm \
    php-curl php-gd php-mbstring php-mysql \
    php-xml php-zip

Carefully choose a strong password for MySQL root user when configuring the mysql-server package.

Now edit the configuration for default Nginx site with below command:

sudo nano /etc/nginx/sites-available/default

Clear everything and paste below configuration in the editor, then hit ^O and ^C to save and close.

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

        root /var/www/html/wordpress;

        index index.php index.html index.htm index.nginx-debian.html;

        server_name _;

        location = /favicon.ico {
                log_not_found off;
                access_log off;

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;

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

        location ~ \.php$ {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;

Once saved, restart Nginx server with following command:

sudo systemctl restart nginx

Navigate to above specified document root and download, then extract WordPress:

cd /var/www/html
sudo wget
sudo tar -xf latest.tar.gz
sudo rm -f latest.tar.gz

Because we did download operations using sudo, the wordpress directory is now owned by root. We need to change its ownership to www-data for WordPress to be able to write to it (e.g., for installing plugins and themes). Run below commands to apply it:

sudo chown -R www-data:www-data wordpress

WordPress needs a MySQL database to work. You can create one by logging into MySQL server as shown below and create the database.

mysql -u root -p

Enter the password (chosen while configuring mysql-server) for root user and issue below SQL statement.

CREATE DATABASE `wordpress`;

Now navigate to the IP address of this server in your favourite browser (I ❤ Firefox) and finish with the WordPress installation wizard by using wordpress as database name, root as database user and the chosen password when asked.

Finishing Up

So, this was how you could quickly install WordPress on Ubuntu 16.04. It may not be the safest way (no firewall, uses MySQL root password, no SSL and no optimisation) as I wanted the post to be as simple as possible to follow. I will cover these other things up in upcoming posts separately.