Build A WordPress Website From Scratch

Step 1 – The Prep Work

When creating WordPress website from scratch there are a couple things we need to do up front.

First, we need a to purchase a domain name (e.g. foo.com) from a domain name an ICANN-Accredited registrar. This can be done on a registrar websites. First, search for the desired domain name to see if it is available (it does not have to be a .com, it can be a .org, .space, .io or any available top-level domain name). The domain name prices typically range from $0.99/year to $1,000/year depending on the popularity of the domain name you wish to use. I’ve found that most hover around the $12.99/year mark.

Second, we need to purchase space on a Virtual Private Server (VPS). There are loads of VPS providers out there. A simple google search will do. If you are just starting out I recommend purchasing a VPS that will provide around 1 GB of Ram and 10-20GB of SSD storage space to start. The RAM will help with performance, and the storage space will be plenty for a basic website. That should cost somewhere between $15-30/year. We will need to install some form of Linux (for this post we use Ubuntu 16+) on the VPS. This will likely be provided as a pre-install option when purchasing the VPS.

Third, after the first and second steps are completed, we will need to take the IP address of our VPS (this will be provided by the VPS), log onto our chosen registrar and change our DNS records to that point to this IP address. When this is completed, someone who accesses our website using our domain name (e.g. types in foo.com or www.foo.com into a web browser) will be directed to our site.

The record entries should look something like this:

Note: Be sure to change xxx.xxx.xxx.xxx to your IP address, and foo.com to your domain name. After the changes are saved, it will take a few minutes (I’ve found it to be around 20 minutes) for this change to propagate the DNS databases across the internet. Once that is complete. Typing your domain name into your browser will take you to your soon to be developed website.

Please note, that if you try now, you will either get an error of an unresolved domain name (because we haven’t developed our server yet), or if your Linux instance has an Apache2 web-server installed and running by default, then you will be taken to its default page (which will look like the image below).

Congratulations we are now ready to begin our server-side development!


Step 2 – Server-Side Setup

Step 2 – Part A – Set up Linux Accounts and Security

Okay, now the meat begins! We start by login into your new VPS. You should have received default login information (i.e. Username (likely root) & Password) from the VPS provider (you might want to check your email).

So lets open up our favorite Linux terminal (you can enabled Bash on Windows 10), and use the ever-favorite SSH protocol to login. Type the following into the terminal, but replace foo.com with your domain name. Type yes to the authenticity question, followed by the default password.

$ ssh root@foo.com

Ok, now we are in! Just like a spy movie ;).

First things first, we are going to secure the server. This consists of the following but not limited: updating & upgrading Ubuntu, changing the default root password to something long and complex (you probably won’t ever need it again, but you may want to have it just as a catastrophic backup), add a user with superuser privileges and set up ssh keys, disable root access over ssh entirely, set up the firewall, and set up unattended security updates. So let’s go through these step-by-step.

Change the root password

$ passwd

Then enter a SuperSecretPassword!

Update & Upgrade:

$ apt-get update

$ apt-get upgrade

Create a new user

$ adduser computer

End a SecondSuperSecretPassword!

Give the user superuser (sudo) privileges

$ visudo

Add the following line to the bottom of the file, then press control-z

computer ALL=(ALL:ALL) ALL

Install nano text editor (because it’s awesome…)

$ apt-get install nano

Exit the server

$ exit

Set up SSH keys for easy of login (make sure you do this from a secure computer). You will be prompted for your new user password. Be sure to replace foo.com with your domain.

$ ssh-keygen

$ ssh-copy-id computer@foo.com

Log into as the new user (no password needed because now we have SSH key authentication. Also if the shell looks strange and you cannot use the up arrows then that may mean the new user account was created with /bin/sh as its login shell, which symlinks to the dash shell by default. To fix this type “sudo chsh -s /bin/bash” then logout and log back in. Be sure to replace foo.com with your domain.

$ ssh computer@foo.com

Change some permissions for security. The first command (chmod 400) prevents accidental overwriting of our SSH keys. The second command makes our new user the owner of the computer directory (recursively).

$ chmod 400 /home/computer/.ssh/authorized_keys

$ chown computer:computer /home/computer -R

Disable root ssh login and restart the service. You will be prompted for you password.

$ sudo -s

$ nano /etc/ssh/sshd_config

Change the line that says:

PermitRootLogin yes

To the following. Then press control-x, followed by y:

PermitRootLogin no

Now restart the ssh service

$ service ssh restart

Now install and set up a firewall some rules. Then enable the firewall.

$ apt-get install ufw

$ ufw allow 22

$ ufw allow 80

$ ufw allow 443

$ ufw enable

Finally set up some unattended auto-security updates

$ apt-get install unattended-upgrades

$ nano /etc/apt/apt.conf.d/10periodic

Add the following lines to the file (note: the file may be empty when you first open it). Then press control-z, then press y.

APT::Periodic::Update-Package-Lists “1”;
APT::Periodic::Download-Upgradeable-Packages “1”;
APT::Periodic::AutocleanInterval “7”;
APT::Periodic::Unattended-Upgrade “1”;

$ nano /etc/apt/apt.conf.d/50unattended-upgrades

Add the following line to the file if it is not already there. Append the line into the proper section, if the section is already there. Then press control-z, then press y.

"Ubuntu lucid-security";

Ok we made it! We officially have a secure Linux server that is ready to be worked on.

Step 2 – Part B – Install LAMP stack (Apache & SQL)

Run the following commands to install Apache

$ sudo apt-get update

$ sudo apt-get install apache2

$ sudo apache2ctl configtest

The last command should return “Syntax OK”

$ sudo nano /etc/apache2/apache2.conf

Scroll to the bottom of the file and add the following line (replace foo.com with your domain name). Then press control-z, then press y.

ServerName foo.com

Restart Apache

$ sudo systemctl restart apache2

Allow Apache through the firewall

$ sudo ufw allow in “Apache Full”

Go to your domain and see if you see the Apache Page below. If you see this, then everything worked successfully.

Run the following command to install SQL. When prompted, put in a good root database password. If you mess this up and need to restart, use the following commands to purge SQL: $ sudo apt-get remove –purge mysql-server mysql-client mysql-common -y $ sudo apt-get autoremove -y $ sudo apt-get autoclean $ rm -rf /etc/mysql $ sudo find / -iname mysql* -exec rm -rf {} \;

$ sudo apt-get install mysql-server

Secure the server with the following command. You will need to root password you just set. Select the security options as you see fit. I recommend: Validate password: n, Remove anonymous users: y, Disallow root login remotely: y, Remove test database: y, Reload privilege tables now: y.

$ mysql_secure_installation

Run the following command to install PHP

$ sudo apt-get install php libapache2-mod-php php-mcrypt php-mysql

Run the following command

$ sudo nano /etc/apache2/mods-enabled/dir.conf

Change this:

<IfModule mod_dir.c>
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

To this:

<IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>

Then press control-z, then press y

Restart Apache

$ sudo systemctl restart apache2

Step 2 – Part C – Set up HTTPS encryption

Run the following commands:

$ sudo apt-get install software-properties-common

$ sudo add-apt-repository ppa:certbot/certbot

$ sudo apt-get update

$ sudo apt-get install python-certbot-apache

Run the following command: enter you email address, agree to the terms, and say no to the sharing of your email address (advised), and select redirect all requests to https. To test is this was successful go to: https://www.ssllabs.com/ssltest/analyze.html?d=foo.com&latest

$ sudo certbot –apache -d foo.com

Step 2 – Part D – Create a MySQL Database and User for WordPress

Type the following command. You will be prompted for the SQL root password again. Make sure to choose a good password for the user you are creating. Replace the
SecretSQLUserPassword with something strong.

$ mysql -u root -p

mysql> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

mysql> GRANT ALL ON wordpress.* TO ‘wordpressuser’@’localhost’ IDENTIFIED BY ‘SecretSQLUserPassword’;

$ FLUSH PRIVILEGES;

$ EXIT;

Install additional PHP extensions

$ sudo apt-get update

$ sudo apt-get install php-curl php-gd php-mbstring php-mcrypt php-xml php-xmlrpc

$ sudo systemctl restart apache2

Type the following command:

$ sudo nano /etc/apache2/apache2.conf

Add this to the bottom of the file. Then press control-z, then press y.

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

Now run these commands:

$ sudo a2enmod rewrite

$ sudo apache2ctl configtest

$ sudo systemctl restart apache2

Now run all of the following commands to install wordpress:

$ sudo apt-get install curl

$ cd /tmp

$ curl -O https://wordpress.org/latest.tar.gz

$ tar xzvf latest.tar.gz

$ touch /tmp/wordpress/.htaccess

$ chmod 660 /tmp/wordpress/.htaccess

$ cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php

$ mkdir /tmp/wordpress/wp-content/upgrade

$ sudo cp -a /tmp/wordpress/. /var/www/html

$ sudo chown -R computer:www-data /var/www/html

$ sudo find /var/www/html -type d -exec chmod g+s {} \;

$ sudo chmod g+w /var/www/html/wp-content

$ sudo chmod -R g+w /var/www/html/wp-content/themes

$ sudo chmod -R g+w /var/www/html/wp-content/plugins

Run the following command and it will return values:

$ curl -s https://api.wordpress.org/secret-key/1.1/salt/

Run the following command and use values returned by the previous command to overwrite the defaults in the file.

$ nano /var/www/html/wp-config.php

The defaults look like this:

define(‘AUTH_KEY’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_KEY’, ‘put your unique phrase here’);
define(‘LOGGED_IN_KEY’, ‘put your unique phrase here’);
define(‘NONCE_KEY’, ‘put your unique phrase here’);
define(‘AUTH_SALT’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_SALT’, ‘put your unique phrase here’);
define(‘LOGGED_IN_SALT’, ‘put your unique phrase here’);
define(‘NONCE_SALT’, ‘put your unique phrase here’);

In addition, replace your database name, username, and password in the appropriate lines. See the lines below (but with your password in there).

define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpressuser');

/** MySQL database password */
define('DB_PASSWORD', 'password');

And that’s it! I have finished with the server side.

Step 3 – Set up Client-Side

To Be Continued…….