WordPress
Article

Building a VPS with WordPress on a LEMP Stack

By Tim Carr

With site performance a key metric in Google’s ranking algorithms, more WordPress users are turning to dedicated, managed WordPress hosting such as WP Engine, Media Temple or SiteGround.

However, these can be expensive solutions for some, with costs starting at ~$30/site per month.

If you’re comfortable with basic server administration and WordPress, it’s possible to setup your own, inexpensive hosting for small WordPress websites, that matches the performance of managed WordPress hosting providers using a LEMP Stack (Linux, nginx, MySQL, PHP).

Creating a DigitalOcean Virtual Private Server (VPS)

This article uses DigitalOcean, but you can equally use services such as Linode, Vultr or a number of other providers. The other sections of this guide will equally apply, regardless of who you’re using.

First, register an account at https://cloud.digitalocean.com/registrations/new.

Once completed, click the Create Droplet button:

Create Droplet

We’ll use the following settings for our VPS:

  • Droplet Hostname: Enter something meaningful – perhaps your company or website name
  • Select Image: Choose Ubuntu 14.04 x64 – this should be selected by default
  • Select Size: We’ll start with the $5/month option, which comes with 512 MB, 1 CPU, 20 GB SSD and 1000 GB Transfer
  • Select Region: Choose a region appropriate to your business. If you’re US based, select a USA region. If you’re UK based, select a UK region.
  • Available Settings: Enabling the Backups option is recommended, as it’ll take nightly snapshots of your server. If something goes wrong, you can then roll back to the previous day’s backup.

Droplet Hostname

Click the Create Droplet button, and you’ll then see on screen progress whilst your VPS (Droplet) is created.

Creating droplet

Once completed, you’ll see your VPS on screen. Make a note of the IP address:

VPS

You’ll also receive an email with your root password, which you’ll need as well.

Logging into Your VPS

Next, let’s login to our VPS.

NOTE: In our example, to keep things simple, we’ll be using a password to login to our server. I’d recommend looking into using SSH keys for additional security.

Windows

For Windows users, download PuTTY. Once downloaded, run PuTTY and enter the following information into the dialog box that appears:

  • Host Name: Enter the IP address you made a note of above
  • Connection type: SSH

PuTTY Configuration

Click ‘Open’, and you should be presented with a security alert. This tells us that the server’s host key is new, and therefore asking us if we want to trust it. Click ‘Yes’.

PuTTY Security Alert

Next, let’s login as the root user. Enter root for login as, and press ‘Enter’. You’ll then be prompted to enter your password; enter the password that was emailed to you. Don’t worry if you can’t see the password as you type it – this is for security. Press ‘Enter’ when done.

Mac OS X

For Mac OS X users, open Terminal and enter the following command, replacing 123.123.123.123 with the IP address above:

ssh root@123.123.123.123

You’ll be asked to accept the server key – type yes and press ‘Enter’:

Server Key

Next, enter your password and press ‘Enter’.

Changing the Root Password

The first time you login to your server, you may be prompted to change the root password:

Root Password

Enter the current password, and then enter a new password when prompted.

UNIX Password

Installing the LEMP Stack on Ubuntu

WordPress requires Apache or nginx, PHP and MySQL, as well as a few other components to get things working.

Ubuntu uses a package manager, which can be thought of as a command line based app store. Before we start downloading and installing components from it, we need to update its catalog by entering the following command:

sudo apt-get update

Once completed, we can then install our components:

sudo apt-get install nginx mysql-server php5-fpm php5-mysql php5-curl php5-gd php5-cgi

You’ll be asked if you want to continue – type in Y, and press enter.

Components

Configuring MySQL

During the installation process, MySQL will ask you to set a new password for the root database user. Note that this is different from the root login for the server. For security, I’d strongly recommend making this a different password than the root login to your server.

Once the installation has completed, we need to run two more commands to complete the MySQL installation.

First, enter:

sudo mysql_install_db

Then, enter:

sudo mysql_secure_installation

  • Type in your current MySQL root password, which you set above.
  • Enter n when asked to change the root password (as we’ve already done this, no need to do it again).
  • Enter Y when asked to remove anonymous users.
  • Enter Y when asked to disallow root login remotely.
  • Enter Y when asked to remove the test database and access to it.
  • Enter Y when asked to reload privilege tables.

Finally, we need to create a MySQL user and database:

mysql -u root -p

Enter your MySQL password when prompted, and if correct, you’ll be presented with the MySQL prompt:

MySQL

Let’s create our new database and user – replace ‘password’ with a unique password:

CREATE DATABASE wordpress;
CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON * . * TO 'wordpress'@'localhost';
FLUSH PRIVILEGES;
exit

Configuring PHP

We need to make a slight alteration to get PHP working with nginx:

sudo nano /etc/php5/fpm/php.ini

Configuring PHP

Hold down the Ctrl key and press W, and you’ll be asked to type into a Search field. Enter:

fix_pathinfo and press Enter:

Configuring PHP

Change the following line:

;cgi.fix_pathinfo=1

to:

cgi.fix_pathinfo=0

To save our changes, hold down the Ctrl key and press X, followed by Y and then the Enter key.

Configuring nginx

We need to change nginx’s configuration to get things working with WordPress:

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

Configuring nginx

Let’s remove the current configuration. Keep pressing Ctrl and K to cut each line of the configuration file, until it’s blank:

Removing current configuration

Next, copy the nginx configuration below and paste it into your Terminal/PuTTY window, remembering to change domain.com to your domain name:

server {
# Listen on port 80
listen 80 default_server;

Document Root

root /usr/share/nginx;

Domain(s)

server_name www.domain.com;

Index

index index.php;

GZIP Compression

gzip on;
gzip_types text/plain image/svg+xml text/javascript application/x-javascript text/xml text/css;
gzip_vary on;

Cache Static Files

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff)$ {
expires 1y;
}

Load File

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

# Pass the PHP scripts to FastCGI server
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

To save our changes, hold down the Ctrl key and press X, followed by Y and then the Enter key.

Creating a SSH Login

For security reasons, we don’t want to run WordPress as the root user. Let’s go ahead and create a new server user for that purpose:

sudo adduser wordpress

Enter a password for this user, and then just press ‘Enter’ on the other fields.

Creating a SSH Login

Next, add our new wordpress user to the www-data group. This is the group used by PHP, so when we go to upload WordPress files, they’ll correctly run:

sudo usermod -a -G wordpress www-data

We need to tell PHP which user and group can run PHP files:

sudo nano /etc/php5/fpm/pool.d/www.conf

Scroll down until you find the user = www-group line, and change this to:

user = wordpress

Configure SSH Login

To save our changes, hold down the Ctrl key and press X, followed by Y and then the Enter key.

Restart the Server

To make sure everything’s working, let’s restart the server:

reboot

Login and Install WordPress

To install WordPress, let’s log back into the server and then enter the following commands:

cd /usr/share/nginx
wget http://wordpress.org/latest.tar.gz
tar xfz latest.tar.gz
mv wordpress/* ./
rm latest.tar.gz
rmdir wordpress

The above commands download WordPress from wordpress.org, extract/unzip it into the /usr/share/nginx/wordpress folder. We then move the contents of that folder back into /usr/share/nginx before removing the original download file and WordPress directory.

To avoid file permission issues when trying to install Plugins or upload images, let’s recursively set permissions on nginx’s web accessible root folder to the wordpress user and www-data groups that PHP is configured to use:

sudo chmod g+w /usr/share/nginx -R
sudo chown -R wordpress:www-data /usr/share/nginx

Next, in your web browser, load http://123.123.123.123 (or http://www.domain.com, if you’ve set your domain’s A name record to point to your server’s IP address).

If everything worked, you’ll see the familiar WordPress configuration screen. Click Let’s go!, and then enter the following information on the next screen:

  • Database Name: wordpress
  • User Name: wordpress
  • Password: [the password you entered when setting up MySQL]
  • Database Host: localhost

WordPress config

Click Submit, and if the details are correct, you’ll be asked to run the installation:

Run Installation

Enter your ‘Site Title’, ‘Username’, ‘Password’ and ‘Email Address’ before clicking Install WordPress

WordPress Install

That’s it!

Conclusion

We’ve successfully created a VPS on DigitalOcean, and logged into it over SSH. We’ve then installed nginx, PHP and MySQL, and configured each to work with WordPress.

We’ve also setup a server user, and granted them permissions on our WordPress installation.

Finally, we confirmed everything worked by running through the WordPress installation process.

No Reader comments

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Instant Website Review

Use Woorank to analyze and optimize your website to improve your website to improve your ranking!

Run a review to see how your site can improve across 70+ metrics!

Get the latest in WordPress, once a week, for free.