
Ready a v16.04 Ubuntu Server for WordPress on Amazon…
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>
The above entry is for a top level domain. If you are creating a site for a sub domain, e.g. test.clouded.ch. Then just remove the ServerAlias bit.
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.
If you are having trouble, then I always like to go to the following page https://httpd.apache.org/docs/2.4/vhosts/examples.html
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;