Select Page

Introduction

This document lists the steps required to prepare a Linux server to setup your server on Amazon for running one or more WordPress sites. If you decide to have the database on the server, then the architecture is known as “LAMP” which is an acronym for “Linux, Apache, MySQL and PHP”.

If you’re setting up your first machine, then write down the commands and any connection information into a journal. It will help you remember the steps and internalise anything you learn along the way. You should add knowledge to it as you go along and will see that it will become more valuable than any book you can buy.

Prerequisite

  • You have created an EC2 instance on Amazon and know how to connect to the machine using Putty or SSH.
  • You have chosen to run the database on the same server or use Amazons RDS service.
  • You have a domain name configured for your website on Route 53 or another DNS provider.

Step 1: Ensuring Machine Is Up To Date

When you log in to the machine, you will see information about how many packages and security updates are available. You should never ignore those messages.

sudo apt-get update
sudo apt-get upgrade

First update which refreshes the list of available packages and their versions, but does not install or upgrade any packages. The upgrade command installs newer packages and security updates. Neither of them runs automatically; I recommend a monthly calendar reminder, so you keep your server safe.

If you run the server over a couple of months, then dist-upgrade will bring the operating system up to date and is known to clean up better after itself.

sudo apt-get dist-upgrade

If you are asked a question with a “Y/n” answer, type in “y” and otherwise follow any instruction.

Step 2: Install Apache Web Server

sudo apt-get install apache2

It will start installing. You will be prompted to Press Y and hit Enter to continue, so do that for the installation to advance.

Step 3: Checking the web server is running

Type the IP into your browser and check the web server is running. If you haven’t created an A record to point to the IP of the server, then do it now. You should get the default page, if so, then congratulate yourself.

Step 4: Configuring Your Access Rights

We want maximum lockdown later on and for you to be able to work without using the “super user do” command sudo all the time. Ignore this step, and you’ll be using sloppy access commands later on like “chmod 777”, then you could end up in a situation where you have an unprotected directory, and that’s not good.

The Apache server on Ubuntu will be running under www-data here is how you can double check that:

ps -ef | egrep '(httpd|apache2|apache)' | grep -v `whoami` | grep -v root | head -n1 | awk '{print $1}'

Assuming the user is “www-data” we’re now going to add you to the apache user group.

sudo usermod -a -G www-data ubuntu
exit

We need to logout and login again for the change to show. To check the changes are in place you can now run.

groups

You should see the “www-data” group listed.

Step 5: Setup Database On Server (The low budget option)

If you have decided to use Amazon RDS, then you should follow their instructions and have the instance connection information ready.

BUT, if you follow a backup strategy, then I think there is nothing bad about running the database on the server while the site is small.

I suggest you use MariaDB over MySQL. It took me a lot of time to get used to the idea of MariaDB, as I had been using MySQL since I built my first web server 15 years ago. I now realise what MariaDB is and its development is more open and vibrant, don’t believe me, then check out the activity on GitHub. Also, it’s said to be between 3 and 5% more performant, which is very relevant for web server backends.

The command to install the database and client is.

sudo apt-get install mariadb-server mariadb-client

In the next step, we use the MySQL utility to secure everything.

This hardening we are about to do will require that you come up with a password for the root user.

sudo mysql_secure_installation

I would allow remote login, so you have the opportunity to later connect via MySql Workbench.

Lets login to the database to demonstrate the security.

sudo mysql -u root

Notice it didn’t ask for a password. What happend? MariaDB is per default configured to use your operating system credentials through the auth_plugin.

If you want to force the password for root in the terminal, run these commands.

update mysql.user set plugin=null where user='root';
flush privileges;

To close the MySQL database client use the command

exit;

Step 6: Installing PHP

This step is setting up the scripting language used on WordPress sites.

sudo apt-get install php libapache2-mod-php php-mysql
php -v

Apache will try to first serve up index.html files. We can make an optimisation by making index.php first in the list.

sudo nano /etc/apache2/mods-enabled/dir.conf
<IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>

When you are finished, save and close the file by pressing Ctrl-X. You’ll have to confirm the save by typing Y and then hit Enter to confirm the file save location.

sudo systemctl restart apache2
sudo systemctl status apache2

Step 7: Sanity check to ensure PHP is running

sudo nano /var/www/html/info.php
<?php
phpinfo();
?>

Now go to the web browser enter the IP address /info.php and you should see the information page.

Step 8: Preparing your web server for multisite

Delete the HTML directory

sudo rm -rf /var/www/html

Also, we will disable the default site.

sudo a2dissite 000-default.conf

Step 9: Install WordPress the Command Line Interface (CLI)

The WP-CLI is the official command line tool for interacting with and managing your WordPress sites. It will help us download and install WordPress in seconds. It can also do a lot more.

We should go into the home directory.

cd /home/ubuntu

Now we download the WordPress tool by (or use the official instructions link).

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

Check it works using the command.

php wp-cli.phar --info

Making it a standard executable.

chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

If you WP-CLI installed successfully, then you’ll be presented with important version and directory information

Step 10: Creating your first site

You need the decide on the following

  • website_name shown below as clouded.ch

Start by setting up Route54 DNS so the domain is pointing to the web server.

Create the directory where the site will be hosted.

cd /var/www 
sudo mkdir clouded.ch 
sudo chown www-data:www-data clouded.ch 
sudo chmod 775 clouded.ch

Some like to copy the default template but it is missing stuff, but, it is incomplete for our needs. So we create our own blank configuration.

sudo nano /etc/apache2/sites-available/clouded.ch.conf

Now add this into the file

<VirtualHost *:80>
    ServerAdmin info@clouded.ch
    ServerName clouded.ch
    ServerAlias www.clouded.ch
    DocumentRoot /var/www/clouded.ch
    ErrorLog ${APACHE_LOG_DIR}/clouded.ch-error.log
    CustomLog ${APACHE_LOG_DIR}/clouded.ch-access.log combined
</VirtualHost>

SUPER IMPORTANT: check for mistakes in the configuration file using the command.

sudo apache2ctl configtest

The system response should be “Syntax OK”. You will use the above command every time you change the web server configuration.

Enable the site using the command.

sudo a2ensite clouded.ch.conf

If all is OK then continue by restarting apache.

sudo systemctl restart apache2

Step 11: Installing WordPress

Before you proceed, decide on the following information and securely store somewhere in a password safe such as KeePass. I’ve highlighted them in bold below.

  • Database name e.g. clouded_ch.
  • Database username e.g. clouded_ch_user.
  • Database password.
  • Website URL.
  • Site title.
  • Admin username.
  • Admin password.
  • Admin email address.

Start by going into the website directory.

cd /var/www/clouded.ch

We download WordPress.

wp core download

Creating the database.

sudo mysql -u root -p

You will get asked for the password you set for the MySQL root account.

CREATE DATABASE clouded_ch DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON clouded_ch.* TO 'clouded_ch_user'@'localhost' IDENTIFIED BY '***SecretPassword***';

We need to flush the privileges so that the current instance of MySQL knows about the recent changes we’ve made.

FLUSH PRIVILEGES;
EXIT;

Ensure the database name, user and password are correct!!

wp core config --dbhost=localhost --dbname=clouded_ch --dbuser=clouded_ch_user --dbpass=***SecretPassword***

Now we generate the WordPress configuration file wp-config.php

wp core install --url=www.clouded.ch --title="Clouded.CH" --admin_name=james --admin_password=***SecretAdminPassword*** --admin_email=info@clouded.ch

Prepare it for accepting uploads, which may already exist.

cd wp-content
mkdir uploads

We will set the ownership of all directories and files, as well as the group id bit on each of the directories, which makes new files created inherit the group of the parent directory.

sudo chown -R www-data:www-data /var/www/clouded.ch
sudo find /var/www/clouded.ch -type d -exec chmod g+s {} \;

Step 12: Make your site HTTPS

Always check your system operating system version and check https://certbot.eff.org/ for actual instructions.

lsb_release -a

The following will install certbot which does all the lifting.

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache

The command that will allow you to make your site HTTPS.

sudo certbot --apache
  • You will need your email address, so they can contact you for urgent renewal and security notices.
  • You will need to agree to there terms of service (which I would recommend downloading for safekeeping).
  • Then it will ask which sites you would like to activate HTTPS on.
  • You also need to choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access, I would use the redirect because often people forget to type in the S on the end of HTTP

You can see the added configuration files in apache here.

ll /etc/apache2/sites-available/

Use the cat command to review them if you like.

sudo cat /etc/apache2/sites-available/clouded.ch.conf

Lets test if the renew will work.

sudo certbot renew --dry-run

All good? let us hope so.

The certificate needs to be replaced regularly. We can setup automatic renewal using the scheduler. You only need to do this once.

sudo crontab -e

Choose NANO as editor it’s the easiest to use, then add the following line and Ctrl+X to both save and exit. This will make the server check for a new SSL certificate every morning at 03:15am and is something you only need to setup once.

15 3 * * * /usr/bin/certbot renew --quiet

Check the settings are stored

sudo crontab -l

Finished! GO CHECK OUT YOUR WEBSITE.

Miscellaneous: Unable To Install Plugins In WordPress

This will be a permissions problem. Run the commands to set up the ownership.

sudo chown -R www-data:www-data /var/www/clouded.ch 
sudo find /var/www/clouded.ch -type d -exec chmod g+s {} \;

Miscellaneous: Unable To Upload Theme To WordPress

You just bought yourself an awesome new theme and want to upload it to the site. WordPress fails by asking are you sure and do you want to try again.

Start by checking your error log. They are found in the /var/www/apache2 folder.

cd /var/www/apache2
cat clouded.ch-error.log

If you see a message like “POST Content-Length exceeds the limit”, then it’s the default limit in PHP, which is 8M.

To find the php.ini file run this command.

php -i | grep 'php.ini'

Then edit the file.

sudo nano /etc/php/7.0/apache2/php.ini

Now choose the max upload size wisely (use Ctrl + W to find quickly).

upload_max_filesize = 50M
post_max_size = 50M

Finally, you need to restart the web server.

sudo systemctl restart apache2
sudo systemctl status apache2

Miscellaneous: Resetting the root database password.

These happen to me so often. Start by identifying your database.

mysql --version

It should be MariaDB

sudo systemctl stop mariadb

We start it without security or network

sudo mysqld_safe --skip-grant-tables --skip-networking &

Connect to the DB

sudo mysql -u root

When you get the mysql> prompt.

FLUSH PRIVILEGES;

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');

EXIT;

Now to restore the database to normal operation

sudo kill `/var/run/mariadb/mariadb.pid`

sudo systemctl start mariadb

Finally, confirm you can login.

sudo mysql -u root -p

Miscellaneous: Resetting the database password.

Login to your MariaDB using the command

sudo mysql -u root -p

Then run

SET PASSWORD FOR 'clouded_ch_user'@'localhost' = PASSWORD('***SecretPassword***');
FLUSH PRIVILEGES;
EXIT;