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.
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:
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).
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 “firstname.lastname@example.org”
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 126.96.36.199 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 188.8.131.52 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
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:
(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!
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:
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
email@example.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:
firstname.lastname@example.org mailhub=smtp.gmail.com:587 AuthUseremail@example.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 firstname.lastname@example.org
This should result in a received email that only says “test” - assuming you correctly entered your email address above :)
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!