For most people who want to start a WordPress blog, I recommend you stick with shared hosting. But, if you’re a self-hosting kind of person, like me, then this post will show you from start to finish how to install WordPress on Ubuntu Server 18.04.


The first step is to get a VPS, or Virtual Private Server. If you already have a server to run WordPress on, then you can skip this step. Otherwise, you’ll need to sign up and purchase a VPS from an IaaS(Infrastructure as a Service) provider. I recommend you use Vultr, or any other IaaS provider; all you need is a VPS with a public IP address.


If you do decide to go with DigitalOcean, then all you need to do is sign up, then log in. Once you’re at the dashboard, simple click the blue “Get Started with a Droplet” button:

Now, all you need to do is slide over to the $5 VPS, like so:

The size options available for a DigitalOcean VPS

You can change any other options you like(I recommend setting the hostname to your domain name), then click the green “Create” button:

The summary of all the selected options

Now, you have to wait for the VPS to be created, then check your email for the root password. Once you get it, copy it into your clipboard, then SSH into your server with the following terminal command for Mac or Linux:


If you get asked Are you sure you want to continue connecting (yes/no)?, then just type yes, followed by pressing the enter key.

If you’re on Windows, then you can either use the DigitalOcean console:

The browser window for DigitalOcean's console feature

or install an SSH client such as Putty. Once you’re in, you’ll be prompted to change the password for security reasons(emails can be intercepted among other things). Choose a secure password, and continue with the tutorial.

All Other IaaS Providers

If you decide to use a provider other than DigitalOcean, then what you need to do is create a VPS and SSH into it. As much as I would like to create a tutorial for each IaaS provider out there, I don’t have the time. However, chances are someone else has a tutorial on how to do it, so Google is your friend here.

Actually Installing WordPress

Now we get into the “hard” part, which is mostly copying and pasting commands.

Update Your VPS

Right after you get into your VPS, it’s important to update all the software. Luckily for you, Linux has a much simpler approach for updating all the packages on a system than other OS’s, especially Windows. For the case of Ubuntu, all you need to do is run two commands:

apt update
apt upgrade

You’ll see something similar to the following:

The following NEW packages will be installed:
  libuv1 linux-headers-4.15.0-39 linux-headers-4.15.0-39-generic
  linux-image-4.15.0-39-generic linux-modules-4.15.0-39-generic
The following packages will be upgraded:
  apport bind9-host dnsutils gettext-base git git-man grub-common
  grub-efi-amd64 grub-efi-amd64-bin grub-efi-amd64-signed grub-pc-bin
  grub2-common kmod libbind9-160 libdns-export1100 libdns1100 libglib2.0-0
  libglib2.0-data libirs160 libisc-export169 libisc169 libisccc160
  libisccfg160 libkmod2 libldap-2.4-2 libldap-common liblwres160 libmspack0
  libnss-systemd libpam-systemd libpython3-stdlib libpython3.6
  libpython3.6-minimal libpython3.6-stdlib libsystemd0 libudev1
  linux-headers-generic linux-headers-virtual linux-image-virtual
  linux-virtual lxd lxd-client open-vm-tools openssh-client openssh-server
  openssh-sftp-server python3 python3-apport python3-distupgrade python3-gdbm
  python3-minimal python3-problem-report python3-update-manager python3.6
  python3.6-minimal shim-signed sosreport systemd systemd-sysv ubuntu-keyring
  ubuntu-release-upgrader-core udev update-manager-core update-notifier-common
64 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 66.8 MB of archives.
After this operation, 165 MB of additional disk space will be used.
Do you want to continue? [Y/n] 

Just type y, press enter, and let Ubuntu do its magic. If you get any prompts, it’s safe to just press enter on the default option.

Install Required Software

Now that you have an up to date VPS, the next thing to do is install the required packages to run WordPress. In order for WordPress to work, you’ll need to install a web server, PHP, and MySQL on your VPS. We’ll be using Apache as a web server, and we’ll actually use MariaDB instead of MySQL. To install these packages, we’ll again use apt:

apt install apache2 libapache2-mod-php7.2 php-mysqli mariadb-server

Again, press y when prompted, and wait for the packages to install. If any prompts pop up, just press enter with the default settings(if nothing happens, press tab then enter). Next, it’s good practice to secure the MySQL install, so run mysql_secure_installation, leave the current root password password blank, set a new root password, verify it, and just press enter without typing anything for the rest of the prompts.

Install & Configure Postfix

If you want WordPress to be able to send emails(e.g. for password recovery), you’ll need to install postfix. All you need to do is run:

apt install postfix

Then, press tab and enter on the first screen:

Just press enter on the next screen:

Lastly, enter your domain for the last screen:

Configure Apache

Now that we’ve gotten everything installed, it’s time to configure all of the packages, starting with Apache. Apache uses something called virtual hosts which allows for multiple websites to be hosted on a single public IP address. Even if you just plan on running one website on your server, it’s still a good idea to create a virtual host.

First, let’s disable the default virtual host by telling Apache to remove it from the sites-enabled folder:

a2dissite 000-default

Now, go into the Apache configuration folder, and make a copy of the default configuration:

cd /etc/apache2/sites-available
cp 000-default.conf 000-wordpress.conf

Edit the file using nano:

nano 000-wordpress.conf

And edit the file to match the following(use the arrow keys to navigate, and press Control + X, then y when you’re done editing):

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.

	DocumentRoot /var/www/wordpress

	<Directory /var/www/wordpress/>
	AllowOverride All

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

You can leave out all the lines that start with # if you want because they’re just comments and ignored by Apache. Also, replace “” with your domain if you have one. Apache doesn’t know that we want to actually use the new configuration, so run the following enable it:

a2ensite 000-wordpress

The last thing to do with Apache is to enable some required modules:

a2enmod rewrite

Now, restart Apache to make the changes live, and move on to the next step:

service apache2 restart

Download WordPress

Once Apache is configured, we need to download and unzip all of the WordPress files. To do this, we move into the webroot, then download and decompress the tar.gz file, all of which can be accomplished by running the following:

# Move into the directory
cd /var/www/
# Get the WordPress zip file
# Decompress the file
tar xf latest.tar.gz
# Set proper permissions
chown -R www-data:www-data /var/www/wordpress

That’s it, you now have WordPress downloaded, and we’re almost done!

Create a Database

The last step before visiting your site is to create a database for WordPress. We’ll also need to create a user and password that WordPress can use to access the database we make. All of this can be accomplished by running the following commands:

# Go into the MariaDB shell
# Create a database
# Create a user, password, and grant access to the database
# You should probably change the password :)
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_user'@'localhost' IDENTIFIED BY 'password';
# Update privileges
# Exit MariaDB

Remember the password you used, as you’ll need it for the WordPress install.

Install WordPress

To install WordPress, go to the IP address of your server, where you’ll be greeted with the WordPress install page.

The initial WordPress Install Page

Click on “Let’s go!”, and fill out the database information from the previous step. The only thing you’ll need to change from the screen shot below is the password:

The WordPress database configuration base

If all went well, you should see this screen:

The WordPress page you want to see

If you don’t, double check your database password. The next screen is where you set up your site and admin account:

The WordPress set up page

After WordPress finishes installing, you’ll be redirected to the login page, where you log in with the credentials you just set.

After all that work, you are now officially in the WordPress admin panel, congratulations!

Basic Server Security


Now that you have WordPress installed, it’s important to lock down your server a bit. The first step in doing this is to set up the firewall to only allow web and SSH traffic. Doing this is easy, just run the following commands:

# Enable the firewall(you'll need to press y and enter when prompted)
ufw enable
# Limit 22/tcp
ufw limit 22/tcp
# Allow 80/tcp
ufw allow 80/tcp

The commands above simply enable the firewall, rate limit SSH(to help prevent brute force attacks), and allow HTTP access.

Don’t Use Root

In this tutorial, you’ve been using the root account to do everything. This is generally not recommended for security reasons. To create your own account(highly recommended), simply run the following commands:

# Create the user
# Enter your new password and verify when prompted
# Press enter for everything else
adduser user_name
# Give yourself sudo access
adduser user_name sudo

You now have a non-root account! To run root commands, simply prefix each command with sudo. You will be prompted for your password, after which the command will run as the root user. To access the root shell, just use sudo su.

Remember To Update!

Since you’re managing this server yourself, it’s up to you to remember to update it. All you need to do is run the following commands every now and then:

# Update package indexes
apt update
# Upgrade without prompting
apt -y upgrade


You now have a fully self-hosted WordPress blog.