Setting up a self-hosted Wordpress
Tags: wordpress, nginx
Published: 2020-10-26 05:25:21

Many of you have heard of Wordpress, the premier CMS tool for creating blogs and modern websites. There are basically two ways to install Wordpress:

- As a managed Wordpress instance, such as from Wordpress.com and commercial hosting providers that include Wordpress deployments. These give you a control panel you can use to install Wordpress graphically, such as Plesk, cPanel, and phpMyAdmin.
- As a *self-hosted* Wordpress instance that you run on your own hardware and you set up the appropriate services yourself.

This guide will show you how to install a self-hosted Wordpress instance. For best results, make sure you also have a domain name to point Wordpress to. You can easily buy a domain from registrars like Namecheap if you don't have one. It must have an A record with a blank key and an answer value of the wordpress server's IP address. You may also add an entry with a www key if you like, to let people access www.yourdomain.com.

It is no secret that Wordpress requires PHP and a MySQL-compatible database in order to function. But even if you are not familiar with these languages, this guide will help you learn enough to be able to create the database, the database user and chance settings.

So, without further ado, let's begin.

First, download Wordpress.org from the [official download link](https://wordpress.org/download/), unzip the archive and come back when you're done.

## Install MySQL

These commands assume you are using a Debian-based distribution with apt. Change the package manager and package names appropriately if this isn't true.

Run the following command as root:

`apt install mariadb-server`

This installs MariaDB, a FOSS, MySQL-compatible database without Oracle's strings attached. Being MySQL compatible, it contains all the commands that MySQL has.

Once that's done, make sure the MySQL server is running using `systemctl start mysql`, and run the following as root:

`mysql_secure_installation`

This guides you through setting a root password, and disabling insecure features.

Next, you'll need to connect to the MySQL server and create a MySQL user for wordpress. The following commands create a database user `wordpress` with a password, and give it permission to modify all databases. In a production setting where there are many unrelated databases stored at once, as opposed to only the Wordpress database, you would give the user permission only for that Wordpress database for security reasons. But since the database doesn't exist yet, we have to do it this way.

```
$ mysql
<Enter MySQL root password when prompted>
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' IDENTIFIED BY 'password of wordpress';
```

Log out of MySQL by typing `\q`, then run the MySQL command again, this time as the user you just created. This time, we need to create the Wordpress database:

```
$ mysql -u wordpress -p
<enter password you set for 'wordpress' user when prompted>
MariaDB [(none)]> CREATE DATABASE db_wordpress;
```

Type `\q` again to log out. That concludes the cration of the MySQL database.

## Install PHP

Make sure that PHP, the MySQL plugin to PHP, and the php-fpm plugin (you'll need this when you create the Nginx configuration file) are all installed by running as root:

`apt install php php-mysql php-fpm`

## Edit the Wordpress configuration file

In the Wordpress folder you downloaded, there should be a file called `wp-config-sample.php`. You need to rename it to `wp-config.php` and edit this file and put the database name, database user, and database user password that you created earlier.

Using your favorite text editor (I use vim), open that file, and change the following lines:

```
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
```

In our tutorial, `DB_NAME` would be `db_wordpress`, and `DB_USER` would be `wordpress`, while `DB_PASSWORD` is the password we made for the `wordpress` user.

Save and exit the file. Then create a folder for the Wordpress folder contents somewhere in `/var/www`:

`mkdir -p /var/www/yourdomainname.com/html`

Move the contents of the Wordpress folder you extracted to `/var/www/yourdomainname.com/html`. Don't just place the folder itself in `html/`, the **files** need to be in `html/` for Wordpress to work properly.

*Tip:* If you don't have a domain name, replace yourdomainname.com with any text string, but record it's name, it's crucial to put the name of this folder in the nginx configuration file later, so you must not forget it.

## Install nginx

You need web server software such as nginx to run Wordpress, so we need to install that. Run the following to install nginx:

`apt install nginx`

We will now create a configuration file for our wordpress website. Create a file at `/etc/nginx/sites-available/yourdomainname.com`, open it with a text editor and paste the following contents in there:

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

        # Omit this line if you don't have a domain name
        server_name yourdomainname.com www.yourdomainname.com;

        # If you created the folder with a name other than  yourdomainname.com, you must change it here.
        root /var/www/yourdomainname.com/html;

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

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }
}
```

Save and close this file. Now, you need to enable this configuration file by making a symbolic link of it in the `sites-enabled/` nginx folder:

`ln -s /etc/nginx/sites-available/yourdomainname.com /etc/nginx/sites-enabled/yourdomainname.com`

Next, check the configuration file for errors by running `nginx -t`. If the program displays no errors, then the configuration file is valid. Otherwise, you need to fix the configuration file accordingly.

Finally, you need to make nginx re-read all of its configuration files, so it processes the one we just created. Run the following command as root:

`nginx -s reload`

That's it! Head over to `http://yourdomainname.com` to use your new Wordpress.org instance!

## Bonus: Set up HTTPS

*You must have a domain name to use HTTPS.* IP addresses alone will cause problems with the certificate validation and will display a browser warning to your site visitors, which you don't want them to see.

Up to now, we made a Wordpress site, but without HTTPS. You really should not use Wordpress without HTTPS, because with HTTP, hackers can intercept the admin password while you log in. HTTPS prevents this.

We can use Let's Encrypt to get a free HTTPS certificate for our site. First, certbot needs to be installed:

`apt install certbot python3-certbot-nginx`

Next, run `certbot` and follow the on-screen instructions. It will ask you for an email address to send certificate expiry warnings to, and will ask you which sites to set up HTTPS for, and whether to redirect HTTP connections to HTTPS (**It's highly recommended you do this**).

You don't need to restart or reload nginx after you run `certbot`, because certbot does it for you.

Now You can head over to your HTTPS-secured Wordpress site and start using it.

## And we're done

There are many guides for setting up Wordpress on the internet, this is yet another one so that there's more information floating around the internet for you to find.

If you see any errors in this post, please let me know so I can correct them.