As many people still use shared hosting these days, we decided to start a series of tutorials that will teach you how to set up your own virtual private server (VPS), all the necessary services for serving a WordPress website and then we’ll even add a few guides to optimize it for speed and security for good measure.

Why is shared hosting not the best option?

  • Your WordPress has to fight for server resources
  • You can’t speed it up on your own
  • You can’t secure it on your own

One thing you need to understand is there’s a difference between shared hosting and managed hosting; The former is basically just a directory you get on the server plus an FTP access and some kind of a control panel (such as Plesk or cPanel).

The latter gives you a basic dashboard to set up the domain and access the database and not much else - all is done for you by the hosting company. There’s quite a few of them out there: WPEngine, Pagely, Flywheel, SiteGround - they make sure your website is optimized and updated (managed) for you, so you don’t have to worry about it.

So why a series of articles on self-managed WordPress? First, you’ll get to know the whole stack required to successfully host a WordPress website. Then you’ll learn how to set up and optimize each layer of that stack; From Linux (operating system) to services such as Nginx (web server) to FTP, SSH, databases and finally you’ll learn about serving WordPress, optimizing assets, overall security, and how to get better response times.

If you’re a kind of person to learn new stuff and tinker with settings only to discover there’s more steps to be taken in order to optimize your website’s performance further (in terms of speed, security and visitor conversion), then these tutorials will be a perfect match for you.

Prerequisites

Because you can’t manipulate a server in a traditional point-and-click way, you need to be familiar with a command line (or terminal if you’re using a Mac) and also have at least some basic knowledge about Linux, since we’ll be using a Ubuntu-based server. Lastly you also need to have an account with DigitalOcean. It’s also fine if you use another cloud hosting provider, but you’ll need to slightly adapt a few steps - nothing major though!

Also note that all terminal commands will start with a dollar-sign ($), which indicates it’s a command, and you shouldn’t enter it yourself, like this:

$ whoami

In this case, you just type whoami as the command.

Create your VPS

Creating your server is really easy and it just takes a few clicks. Login to your DigitalOcean dashboard, and click Create Droplet (that’s how they call their virtual servers).

DigitalOcean VPS WordPress dashboard
DigitalOcean dashboard

Next, you’re presented with a couple of options:

  • Hostname, which can be a domain name, a subdomain name or just an arbitrary word like “my-server”. I chose playground.
  • Region: You should select one that’s closest to your target visitors, I’ll go with New York because it is in reasonable distance to the US and Europe, the two places that most of our readers are from.
  • Image let’s you select a Linux distribution you like the most, I’ll go with Ubuntu (the first choice) because it’s the most widely known and supported platform.
  • SSH Keys: As you can see I have already uploaded mine, and I strongly recommend you do the same, so in the next section let’s do that.

Generating an SSH key

An SSH key is really a pair of two encrypted files, one public and the other private (think of the public as a padlock, while the private is a key). When you’re logging onto the server’s shell, if you uploaded the private file to the correct location, the server won’t ask you for your password as it will automatically compare the two files and let you log in if they match.

For Windows users: You should use PuTTY to connect to the server, and it also supports generating of key pairs. If you need help with it, let me know in the comments below and I’ll update this tutorial accordingly.

To generate the pair, go to the terminal and enter the following commands:

$ cd ~/.ssh
$ ssh-keygen -t rsa -C “your.email@your-domain.com”
WordPress VPS generate RSA
Generating an RSA key pair

You’ll be prompted for the name of the key and a pass phrase, which you should leave empty (just press enter) for now, but if you wish to learn more about them, visit Github’s article where they explain the additional step. For the name of the key, enter whatever you like or leave the default, but note it’ll overwrite the existing default key if you already have one, so caution is advised here.

Now that your SSH key is generated, go back to the Droplet creation form and click “Add SSH Key”, which opens a textarea where you should paste the public part of the key (the file that ends up in .pub).

(To get the contents of the .pub file, you either open it in text editor, or run $ cat playground.pub in the terminal.)

If all server settings are in order and the SSH key was uploaded successfully, click Create Droplet and wait a couple of minutes for the server to be created and booted up.

The last thing is optional, but will save you some typing when logging onto server so it’s highly recommended. Go to the .ssh folder with your keys and create a file named config (no extension) and add the following lines in:

Host Playground
HostName 104.131.53.181
Port 22
User root
IdentityFile /Users/Tomaz/.ssh/playground

(Don’t forget to change the HostName to the IP you were given and IdentityFile to the private key you generated). Save the file and close the editor.

Voila! Now you should be able to SSH on the server, for that, just enter:

$ ssh Playground

This will log you onto the server and what you’ll see first is the shell, which is an environment that server provides for you to enter commands (to run a program, create/modify a file,…).

Creating a user

Everything we’ve done so far, assumes we will perform server actions as the god-like user, called a root. This is a really bad practice security-wise, so we’ll create a normal user which you’ll use to log onto the server with.

On the server, run the following two commands:

$ groupadd admin
$ adduser webmaster --ingroup admin

You will be prompted for a password (the cursor won’t move as you type, just press enter once done) and some additional information, which you can fill out (but don’t really need to).

The group admin has more privileges than a normal user under a shared hosting would have and those privileges are already configured on Ubuntu. However, the group doesn’t exist by default, so we need to add it first.

Now that we have our user, it’s time to move the SSH key from the root, to this new user. Here’s how you can do it:

$ mkdir /home/webmaster/.ssh
$ mv /root/.ssh/authorized_keys /home/webmaster/.ssh/
$ chown -R webmaster:admin /home/webmaster/.ssh/

Here’s what the three commands do:

  • create a directory (a folder, if you’re a Windows user)
  • move the authorized keys file from root to the user
  • set up the webmaster user to own the file (so it can access it)

Now, it’s time to update the config file we created in the previous section, with the following contents:

Host Playground
HostName 104.131.53.181
Port 22
User webmaster
IdentityFile /Users/Tomaz/.ssh/playground

Once done, let’s SSH back onto the server.

Tighten the security

All our servers get all kinds of attacks on a daily basis, and one of the common ones is trying to brute-force an SSH login. This is achieved by trying 1000s of different username and password combinations, so what we’ll do next is preventing anyone (including us) from using this approach to log in - now we have a key pair, so no need for passwords.

There’s a configuration file which we need to edit:

$ sudo nano /etc/ssh/sshd_config

(You may be prompted for password at this point, enter the password you set for the webmaster user)

There is a lot of settings in this file, so here’s the ones that we’re concerned with and need to be changed:

PermitRootLogin no
PasswordAuthentication no

That’s it, save the file and exit the editor by pressing ctrl+X, shift+Y and finally enter. In order for changes to take effect, you also need to restart the daemon, which you do by:

$ sudo service ssh restart

Setting up Nginx

Now that security is in order, we first need to set up the web server software. We could use Apache (which I’m sure you’ve heard of) but it comes with a big memory footprint and slower request processing, so we’ll go with Nginx instead.

To install it, just enter the following commands

$ sudo apt-get update
$ sudo apt-get -y install nginx

To verify that it’s running properly, open your browser and enter the IP address of the server. You should now see the default “Welcome to nginx” page, like the one on the picture below:

WordPress VPS Nginx welcome screen
Nginx welcome screen

(We will properly configure the Nginx in our next week’s tutorial which will be covering installation and setup of our WordPress website)

Pretty easy, right?

Setting up PHP

WordPress is written an open source language called PHP (which stands for Hypertext Preprocessor), so we need to set it up on our server, using the following command:

$ sudo apt-get install -y php5-fpm php5-cli

PHP FPM is a FastCGI process manager that processes PHP files so that WordPress can function properly. It’s a standalone process (or a background application - also called a daemon) that our web server (nginx) talks to when it needs processing of PHP files.

An alternative that you’re probably used to is an Apache module, but the problem with that approach is that as a module it’s always on, meaning even if Apache has to serve a static file (say, an image), the module is active, which means it needlessly uses server resources. Whereas with our approach, the process only gets called when needed.

We also installed a command line interface (or CLI, for short) for PHP so we can run it from our command line, to test it out just enter

$ php -v

And if you see the following screen, you’re ready for the next step!

WordPress VPS PHP version
PHP Version command and output

Setting up database

We have two choices for our database engine, MySQL or MariaDB. We will go with the latter, because it’s a drop-in replacement for the former and is the work of the same author.

$ sudo apt-get install -y mariadb-server mariadb-client

You will be asked for the root user password twice. Make sure to pick a strong password and save it in a secure place (I recommend using 1Password)!

to test out whether it’s working, let’s try connecting to the database:

$ mysql -u root -p

You’ll be shown a password prompt, and once submitted, you should successfully be connected, like so:

WordPress VPS MySQL access
MySQL, accessed through command line

Exit pressing CTRL + D.

Setting up FTP

While not being a huge fan of the FTP personally, WordPress seems to work best with it, so we have no choice, but to set it up, which is what we’ll do in this section.

First, we need to create the FTP server (to which we will connect with our FTP client). We will use vsftpd, one of the most popular FTP servers around. To install it, just use apt-get, like in the previous cases:

$ sudo apt-get install -y vsftpd

In order to test it, open your favourite FTP client and connect to the server, using username and password you created earlier (if you followed this tutorial, then the username is webmaster).

There’s more setting up to do, but we’ll do that in the following tutorials, once we have our WordPress running.

Setting up mailer

Many developers overlook this important part when setting up their servers because they accept the default option where server sends an email directly to the recipient’s email address.

This is bad for several reasons:

  • The email is sent with minimal/misconfigured headers
  • The email has high probability of becoming marked as spam
  • Delivery can fail server-side, and you probably won’t notice it

That’s why I’m a huge proponent of setting up a mailer daemon properly, and I love to use sSMTP due to it’s simplicity. There’s literally just one small file to configure.

First, let’s install it:

$ sudo apt-get install -y ssmtp

During the installation, a configuration file will be placed in /etc/ssmtp/ssmtp.conf, which we need to edit:

$ sudo nano /etc/ssmtp/ssmtp.conf

Before you proceed, I strongly advise you to create a separate email account that the server will use for sending emails out, such as server@your-domain.com - and note the password, you’ll need it for the configuration below.

Or better yet, create an account on Mailgun and use it for sending out emails through it, it’s easy to get going and they support 10k emails free per month, a number you won’t easily get close to :)

An ugly-looking text editor will appear (you should be used to seeing only text by now) and make sure the settings in the file look like this:

root=postmaster@your-domain.com
mailhub=smtp.gmail.com:587
AuthUser=server@your-domain.com
AuthPass=password
UseTLS=YES
UseSTARTTLS=YES
rewriteDomain=your-domain.com

Save and close the file.

Last step is to test whether this configuration is working properly, which you can do by entering this command:

$ echo test | ssmtp you@your-domain.com

This should result in a received email that only says “test” - assuming you correctly entered your email address above :)

Conclusion

You should now have a VPS server that contains all the basic ingredients we’ll need to install WordPress on, which we’ll cover in the next week’s tutorial. The server as it currently is provides no real value, but it’s important to have one, so it’ll serve as a base for all our upcoming tutorials!

If you have any kind of questions, suggestions or remarks, I encourage you to leave a comment below!

EDIT: Our next tutorial is live! It's all about installing WordPress on the VPS we just configured, go check it out!

See you next week!

New Call-to-actionQuality: The Codeable Differene

  • A most excellent and well written tutorial. I would add one step, though. At some point (likely after installing all of your software), the user should run sudo apt-get update && sudo apt-get upgrade so that Ubuntu will download and install any and all relevant security patches and upgrades. That should be a key step that’s performed on a frequent basis so that the server is up to date with security patches and updates.

  • Mario

    Hi. I am trying to follow this tutorial, but, as an inexperienced user, the commands doesn’t seem to exist with the packages I’ve choosen. What Ubuntu version are you using?

    Sincerely

  • Livia Dobai

    Thanks for the tutorial! Helped me to finally decide and move my sites from shred hosting to VPS. However i have difficulty with the ftp. I can log in via ftp client but for any upload attempt i receive “550 Permission denied.” Any hint?

    • Livia Dobai

      Find a working solution:
      in the vsftpd.conf (/etc/vsftpd.conf) the write_enable=YES must be uncommented.

  • KonstantinKarpitsky

    Thank you very much for this tutorial. What do you mean by that:

    ‘Before you proceed, I strongly advise you to create a separate email account that the server will use for sending emails out, such as server@your-domain.com – and note the password, you’ll need it for the configuration below.”

    I’m interested: where and how to create this e-mail.

    Thank you :)

  • qdlaczian

    Maybe tel us more about securing php ? Disable functions ?

  • Justin Samuel

    Hi Tomaž,

    It would take away some of the fun of setting up your own DigitalOcean server for hosting WordPress, but to jump right into using the server for production hosting without doing any manual configuration, you might want to check out ServerPilot.

    https://serverpilot.io/wordpress-hosting

  • Really excellent walkthru.
    Only part I would question is that you don’t really need the FTP server. Anything requiring FTP can be accomplished with SFTP using the ssh key access generated at the start.

  • John Irvine

    Recently, I have ordered a vps from Phi 9 web host. I also followed your setups. Thank you for your great tutorial that has helped me a lot. Really appreciate this article!!!

  • Ava James

    Im looking for a cheap yet reliable VPS hosting provider that could help my website deliver content in a fast yet effective way. Any suggestions of cheap/reliable companies providing this service? So far i have found 1 that offers the cheapest rate and is called interserver. This is the cheapest service i could find online and has all the features of a premium service. Cpanel, phpmyadmin, Unlimited space, unlimited emails, unlimited databases, etc.
    currently they are offering VPS for only a penny. at attractivereview.com you can find the coupon code..

    • abdlmalk

      hey dear

      if you are still looking fora cheap vps

      so ‘ Interserver ‘ vps ison of the best vps in the world

      Interserver is an American hosting provider that has a fairly broad remit

      and really they have that you want

      so this is link of ‘ Interserver ‘ website

      LINK : https://goo.gl/LiqXn4

      ‘ if you Use this coupon when placing an order to get the first month of hosting for only 1
      penny ‘

      coupon: servercoupon

  • Hi Tomaz, great article you have here. For your information we’ve created a service (startup) called RunCloud to eliminate the tedious process of configuring NGINX and other server configs. Plus, we provide control panel to manage the server. We got 15 days free trial for you to play around. Do visit : http://runcloud.io to try it yourself today.

  • Arshid KV

    https://cmsget.org

    Single click WordPress installer for VPS or cloud.

    • Hi Arshid,

      One should always go for most reliable and affordable WordPress hosting provider which delivers best performance, security and scalability to managed cloud hosting services. Just as Cloudways does. All you need to do is select your cloud infrastructure (DigitalOcean, Amazon, Google, Kyup or Vultr) and the application you want to install. Within few minutes, you will not just have your application running on the cloud but it will also be highly charged to give lightening performance, ready with all the tools to give you complete control. It is an affordable and reliable web hosting provider where you Pay-as-You-Go, making scaling more affordable.

  • Suman Basuli

    Excellently written but I want a tutorial for windows and use putty please reply me at wrightabd@gmail.com how to use putty

  • vikasprogrammer

    You might want to check out the CMS Launcher’s WordPress VPS hosting. It comes with pre-installed Vesta Control Panel which can manage your websites and emails.

    (Full disclosure I am the founder of CMS Launcher).

    https://cmslauncher.com/cloud-vps-hosting

  • Nice article and after some years some of it still applies. We offer a highly optimized and managed WordPress VPS stack that incorporates Nginx along with various caching technology to speed up WordPress. You can find it at https://www.iozoom.com/managed-wordpress-vps.html for those who want to be more hands-off with the server management.

  • It is very nice article related to WordPress VPS hosting. After a very long time I read this type of informative article related to WordPress VPs Hosting. Thank you so much.

  • memorial

    great article!
    instead of using digital ocean I prefer to use https://www.vultr.com/?ref=7212354 for my VPS’s :)

    only 2,5 $ per month

    br memorial

    • Steacy Paquette

      For 2.5$ you only get a sandbox that you need to restart everyday

  • Host Domain Pakistan
  • Hasa ghu

    Most of provider charges less for first year but comes with huge charges upon renewal so i always prefer to have wordpress with installation from https://www.winshosting.com/scripts-hosting.html because they provide free ssl as well as free domain including all relevant hosting features but in very least price