To create a bash script that will work only for your user, you can store the bash files in your user’s home directory. The standard place to put them would be a folder called bin. Create it if it does not exist, then create the file. The name of the file is the name of the command you want to type to run it. So, if I want to call my command “commandname”, I would do…

mkdir ~/bin
sudo nano ~/bin/commandname

Then, create the script with the shebang! at the top…

#!/bin/bash

# Update, upgrade, then restart
apt-get -y update
apt-get -y upgrade
apt-get autoremove
service apache2 restart

# update WordPress through WP-CLI
cd /var/www/html
wp core update
wp plugin update --all

Now, make the file executable…

sudo chmod +x  ~/bin/commandname 

Then, to run the file from any directory, you’ll have to update your user’s .profile file…

sudo nano ~/.profile

Adding the following to ~/.profile tells linux that there are executable scripts in the ~/bin directory…

PATH=$PATH:~/bin
PATH=~/bin:$PATH

Now you should be able to run the command, commandname, from any directory.

You can run this manually from the command line or you can create a cron to run it at regular intervals.

1 * * * * /bin/bash -c "~/bin/commandname"

Then reload the cron with…

sudo service cron reload

You can monitor the cron log in real-time with tail…

tail -f /var/log/syslog

AWS Lightsail is the closest thing AWS has to shared hosting. It is their quick, easy and inexpensive off-the-shelf hosting that has SSH access and many of the benefits of using a more expensive EC2 instance.

It is an affordable entry in cloud computing, but is it any good?

I decided to try out Amazon’s cheapest hosting offering by moving a WordPress blog from some shared hosting to Lightsail. I have tried EC2 in the past so this was not my first experience with AWS, but I was curious to see what their new more consumer-based hosting was like.

Creating an Instance

When you create an instance of Lightsail you chose how big or small you want it. You also chose whether you want just the OS, or you can have an app pre-installed with Bitnami (“App+OS“). The options for the app include a pre-installed WordPress blog, LAMP, MEAN, LEMP or several other applications. Alternatively, you can choose “OS Only” where you currently have the choice of either Windows or Linux flavors: Amazon Linux, Ubuntu, Debian, FreeBSD, openSUSE and CentOS.

I went with the PHP 7 LAMP stack option in the smallest size ($3.50 per month). I chose this option because I wanted to make sure WordPress was exactly the way I wanted it. And I wanted to see what the LAMP option was like.

In the price you also get a dedicated IP which makes setting up a breeze before pointing the domain name at the new instance, definitely a nice touch.

The LAMP 7 option came with PHP 7.1. But it’s possible to upgrade. All the elements of LAMP come pre-installed (Linux, Apache, MySQL and PHP) but you’ll want to configure them to your needs.

The main thing you can say about the setup is that it was lightening fast. Within seconds I had a fully operational instance. In the past, when setting up some hosting you might have assumed it would take at least a couple of days. Because the dedicated IP is plainly visible on the AWS console, you can immediately see the default index page in your browser.

First Look at Lightsail App+OS

The main difference between the “App+OS” option and a normal VPS is Bitnami. You notice right away is that the default username is “bitnami” and after logging into the Linux console you get a large “Bitnami” logo at the top of the screen.

So, what is this Bitnami?

Bitnami

Amazon AWS has so many quirks that you might assume that Bitnami is an AWS thing, as is their own Amazon Linux, but it is quite widely used in cloud computing (including Oracle Cloud and Google Cloud Platform).

With the “App+OS” Bitnami a lot of the things you normally have to do to set up a LAMP stack are already done for you. For example, Apache is pre-installed with most/all modules and even MySQL is pre-installed. However, to find your root login for MySQL you’ll need to look for it, see below.

With Bitnami other slightly unusual thing you notice upon logging into SSH or SFTP is the directory structure, the apache.conf does not look the same as normal, and where are the virtual host files?

Bitnami uses httpd-app.conf, httpd-prefix.conf and httpd-vhosts.conf files, as described here.

This is unusual and I imagine many people who do not want to use Bitnami would want to use the “OS Only” option. While it may take a little longer to set up, once that’s done you have a “normal” Bitnami-free Linux instance.

Transferring a Website to Lightsail

Having gone with the LAMP (PHP 7) option I basically followed my guide from here to move a WordPress blog over to different hosting. With minimal setup to do it was mainly a case of setting up the database, installing WordPress then using WP-CLI to install the plugins and theme.

As the instance was just going to be hosting one website I didn’t have to worry at all about the virtualhosts as everything was set up to just work from the off.

My first question was how do I login to MySQL. The login info for MySQL did not appear to be anywhere in the AWS console. To find the password for the root user you need the Bitnami Application password. From the home directory (where you arrive after logging in) just type…

$ cat bitnami_application_password

Transferring everything across, most things just worked. While PDO worked fine in normal PHP pages, I had to tweak the php.ini to get PDO to work from a script run with cron. For me, I just had to uncomment the .so file for PDO which was almost the last line of the php.ini.

After changing something like the php.ini you’ll have to restart. The following command seems to stop everything (apache/HTTPd, PHP and MySQL, ), then restart everything; perfect for making sure everything gets restarted all at once but not very graceful (from here)…

$ sudo /opt/bitnami/ctlscript.sh restart

To just restart apache you’d just add “apache” to the end…

$ sudo /opt/bitnami/ctlscript.sh restart apache

Linux

While some things are very different in Bitnami, it’s basically just a Linux instance. The Linux version I got with the LAMP (PHP 7) option was actually Ubuntu 16.04, so if you want the latest version of Ubuntu (18.04 is currently the latest LTS), or a different flavor of Linux, chose the “OS Only” option. I am most comfortable with Ubuntu/Debian and a lot of the standard CLI functions are exactly the same as Ubuntu.

Nano comes pre-installed and was the default editor for the crontab.

$ crontab -e

BTW, cron needs the full path to php, i.e. something like…

* * * * * /opt/bitnami/php/bin/php -f /opt/bitnami/apache2/htdocs/scripts/index.php "name_of_method()"

Then…

$ sudo service cron reload

The timezone is quite important because it can also affect your keyboard layout when typing into the Linux terminal. Changing the timezone is based on Ubuntu 16.04, so something like this would work to list the timezones, select a timezone then check which timezone you’re using…

$ timedatectl list-timezones   
$ sudo timedatectl set-timezone America/Vancouver  
$ timedatectl

Now, that the Linux timezone is set, you may also need to update the timezone PHP uses by updating this line in the php.ini…

date.timezone="Europe/London"

For all the PHP timezone variables, click on your region from the PHP timezones page.

Something else that is the same as Ubuntu is updating and upgrading…

$ sudo apt-get update
$ sudo apt-get upgrade

Once you get used to the quirks and the different directory structure with Bitnami, most things seem the same as a typical Ubuntu instance.

Issue(s) with AWS Lightsail

The first “upgrade” was a large one which took a while. It took so long in fact that either putty went inactive, or my computer went to sleep, or both. After this, the website went down and I had no access to SSH. What I seemed to have to do was not “reboot” the instance, but “stop” and “start” the instance from the AWS console. After this, I had a different public IP address but I was able to fix whatever had happened with the upgrade.

If the restart is the opposite of graceful, stopping and starting was similarly very ungraceful, comparable to doing the same thing with any VPS instance.

Apart from some minor changes that will probably be easy to get used to, I did not have many issues at all.

AWS Lightsail App+OS: Conclusion

Bitnami saved some time during setup, but honestly, any time I saved was probably offset by time spent figuring out what was going on with Bitnami.
I’m not 100% sure that the speed of setup of Bitnami is worth the changes it makes to the Linux operating system. For something like this example, a WordPress blog, that isn’t going to need a lot of administration, the “App+OS” option was fine though.

If you are a purist and don’t mind setting up the Linux instance with everything you need there is always the “OS Only” option which I don’t believe uses Bitnami. This would be better for a website where you’re going to want to make more changes to the Virtualhost file and/or possibly upgrade to an EC2 instance in future. If you are already a full stack LAMP developer you’ll probably be wanting to use that option for any actual development. App+OS seems to be mainly for people who do not want to get too involved with the “L” or “A” parts of LAMP.

AWS Lightsail with the App+OS option is perfect for someone who just wants to have a cheap WordPress blog running on AWS, as I did here. For a brand new blog, choosing the “WordPress” option would simplify the whole process even more.

I’d say App+OS might also be a good way to play around with something new such as MEAN before starting an actual project with it. Everything would be pre-installed so you could get straight into the javascript and the NoSQL.

So far so good. The instance seems fast for a WordPress blog, it certainly is compared to the previous shared hosting. And, very affordable.

Here are some tweaks you can make to various parts of Linux to make the whole experience a little easier and more intuitive. This guide is for Ubuntu and Debian flavours of Linux.

Change the Config Editor to Nano

The Debian default editor is Joe, if you do not know this text editor, change it to one you know, i.e. Nano. This command gives you all the options you have available so you can select the editor you wish to use…

sudo update-alternatives --config editor

Now, commands that use the default editor such as visudo will use your chosen editor.

Turn off passwords for a User

Once the config editor is nano, you can edit the sudoers file with the visudo command…

sudo visudo

One thing you might want to do is turn off passwords for yourself so that you do not have to keep typing the password when you run sudo commands. Add this like near the end of the file, after the “%sudo” group line…

myuser ALL=(ALL) NOPASSWD:ALL

Tweak Nano

Some changes I like to make when I first set up Linux are on Nano. I like to put smooth-scrolling on and to turn the keypad back to numeric. To do this, edit the nano config file by running this command as either root or with sudo…

sudo nano /etc/nanorc

Installing More Than One Version of PHP

To list all the versions of PHP that are installed you can type…

update-alternatives --list php

This then allows you to switch between them if you have more than one installed at any one time. Really this is more useful on a development machine, it is probably not needed on a web server.

These days there are often WordPress apps on the control panel of hosting providers that enable you to install WordPress easily with a click. You can install and run WordPress entirely by FTP/SFTP and the admin dashboard, but this can be slow. However, if you are comfortable with the Linux command line, you can install WordPress, themes, and plugins at a lightning fast speed. This is particularly useful if you are moving from one hosting company to another and you have more than one WordPress blog to move at the same time.

Installing WordPress from the Command Line

Sometimes SFTPing to a host can be very slow. WordPress is made up of so many individual files that uploading everything when installing or updating can take a very long time.

This method is very quick and snappy way to download the latest version of WordPress when you are initially installing your blog…

wget http://wordpress.org/latest.tar.gz
tar xfz latest.tar.gz

WP CLI

These commands install WP-CLI…

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

You can do this from anywhere because the three lines are 1) download, 2) change permissions and 3) move.

If you install WP-CLI before installing WordPress you can even install WordPress with WP-CLI, see wp core install

wp core download –locale=nl_NL
wp core install –url=example.com –title=Example –admin_user=supervisor –admin_password=strongpassword –[email protected]
wp core version

The 3 lines are 1) download, 2) install and 3) check the version of WordPress that is installed.

Installing Plugins

Assuming you have already set up the WordPress blog (wp-config.php and database), you can then install and activate multiple plugins very easily like this…

wp plugin install wordpress-seo jetpack post-volume-stats add-target-fixer –activate

Another use might be that you can easily de-activate plugins if you ever have problems logging in…

wp plugin deactivate plugin-name

Search and Replace

One thing that you cannot do with SFTP and the WordPress admin dashboard is a sitewide search and replace. There are probably plugins that will help you do this, but it is made very easy with WP-CLI…

wp search-replace oldstring newstring

The --dry-run flag also helps you to see what you’re about to change before you change it.

Updating WordPress

Perhaps the most useful function of WP-CLI for me is the ability to update WordPress very easily and quickly. This is all it takes…

wp core update

Summary

For more info see the docs at WP-CLI.

Here is a guide to Setting up a Linux Webserver with SSH. This is for Debian 8 (Jessie) although other versions of Debian will be similar, and Debian-based versions of Linux, like Ubuntu will also use similar commands. I’ll just call it the webserver because it can be a dedicated server, a VPS, or a cloud instance.

A lot of this comes from these excellent guides… Getting Started with Linode and Securing your Server… but I’d say that searching around and getting different information from different sources is definitely a good way to go. I wanted to install PHP 7.0 so some of this guide is different to other guides, which tend to use PHP 5.6. This guide is also primarily for people using a Windows PC to talk to a remote Linux webserver, but other operating systems will be the same for most of the stages. Most of the contents of this guide uses a terminal and an SSH connection, which windows needs software for (e.g. Putty), but other operating systems may have it built-in. This guide doesn’t talk about FTPing (or SFTPing) much, but a good SFTP client for Windows is WinSCP.

There is often more than one way to get the same results. For example, you can reboot the system in a number of different ways. I tend to use the methods that appear simplest to me.

Requirements

  • A linux server (Debian 8, in this case).
  • The IP address of the server.
  • The root password of the server.
  • A computer to access your remote linux webserver, in this case a Windows PC with Putty installed.

Contents

1) Login to the server with SSH
2) Update/upgrade
3) Install Apache2
4) Find your webserver’s IP address
5) Set a Hostname
6) Configure the Apache virtual hosts
7) Create the web directory
8) Install PHP7
9) Your webserver’s Timezone
10) Unattended upgrades
11) Install Sudo
12) Add a user
13) Public/private key pair
14) Turn off root login
15) Sending email
16) Fail2ban
17) Firewall: UFW
18) Install MySQL and PHPmyAdmin
19) Monitor
20) Apache Config file
Conclusion

1) Login to the server with SSH

With Windows you can download and install some software, such as Putty, then connecting to your instance should be pretty straight-forward with the login information from your hosting company. To begin with you’ll probably be logging in as “root” so you will not need to type sudo as root is the master login (this is handy because sudo is not installed, yet). The commands on this guide may need sudo adding at the beginning if you are not logging in as “root”.

2) Update/upgrade

Once you are logged in the first thing to do is to make sure everything is updated so that you are installing the latest versions of everything when you get to that stage.

apt-get update && apt-get upgrade

or, later if you login as another user, you’ll need sudo…

sudo apt-get update && sudo apt-get upgrade

3) Install Apache2

First, you can check if Apache is already installed by typing…

which apache2

If it is not already installed, i.e. the above does not give you any results. To install Apache type…

apt-get install apache2

4) Find your webserver’s IP address

If your hosting company has not told you what the IP address is, this shows all IP’s installed on your instance…

hostname -I

5) Set a Hostname

The hostname can be anything. If you have more than one instance you might name your instances so that they are all plant species, stars, geographical locations, chemical elements, Roman Emperors or Greek philosophers.

Add the hostname by opening up the hosts file in nano…

nano /etc/hosts

Then, the hosts file might look like using the IP address that you already know, above…


127.0.0.1 myhostnamegoeshere.example.com myhostnamegoeshere localhost
127.0.1.1 myhostnamegoeshere
123.123.456.789 example.com

Also, edit the hostname file…

nano /etc/hostname

Then, after this you’ll need to reboot the instance from the control panel of the hosting company or by rebooting from the control panel: shutdown -r now.

The hostname and FQDN are important for all kinds of server functions. Test your hostname settings like this…

hostname hostname
hostname -i ip address
hostname -f or hostname --fqdn fully qualified domain name

6) Configure the Apache Virtual Hosts

Make sure 000-default.conf is off, copy it to mywebsite.com.conf and enable. link

cd /etc/apache2/sites-available
cp 000-default.conf example.com.conf
nano example.com.conf

Then, edit the example.com.conf so that it looks like this…

ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com

Then, enable the site by typing…

a2ensite example.com

7) Create the web directory

We specified the DocumentRoot should be /var/www/example.com, above. So, now we need to make it!

Move to the place for all your web directories…

cd /var/www/

Then, create the web directory…

mkdir example.com

Once you have the directory you can add an index.html inside it.

If you have not restarted apache2 since typing the a2ensite command you need to do that before the domain name will work in your browser. Restart then test it by typingthe domain name into a browser.

8) Install PHP7

You can install any version of PHP. For Debian 8, it seems that PHP5.6 is the default, whereas with Ubuntu 16.04 LTS PHP7.0 is the default. I wanted to go with PHP7.0 so followed this guide for setting it up on Debian 8… Installing PHP7

Add these two lines to your /etc/apt/sources.list file:

deb http://packages.dotdeb.org jessie all
deb-src http://packages.dotdeb.org jessie all

Add the GPG key:

wget https://www.dotdeb.org/dotdeb.gpg
apt-key add dotdeb.gpg

Install PHP 7:

apt-get update
apt-get install php7.0

Then, straight away before you do too much else you’ll want to add the other modules you need. There is information abput some common ones from here..

apt-get install php7.0-cli php7.0-common libapache2-mod-php7.0 php7.0 php7.0-mysql php7.0-fpm php7.0-curl php7.0-gd php7.0-bz2

You can then test out the PHP by making a page that has phpinfo(); on it to show you 1) that it’s working and 2) the modules that are installed and enabled. Assuming everything works fine it’s time to do more setting up…

At this stage I normally make sure everything is installed that I’ll need for phpmyadmin. Then enable mod_rewrite

a2enmod rewrite

9) Your webserver’s Timezone

Set your server timezone by typing the following command…

dpkg-reconfigure tzdata

Then, this command shows you the current time on your server…

date

10) Unattended upgrades

You will want to keep everything as up-to-date as possible on your instance. You can do this by configuring the Unattended upgrades… Automatic updates. Then if you don’t want to have to login to your instance and reboot/restart it after every upgrade, you can automatically reboot, if needed, after upgrading. First install the package…

apt-get install unattended-upgrades

Then configure the settings you want in nano…

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

To test unattended-upgrades as root or with sudo run…

unattended-upgrade -d

11) Install sudo

From Installing sudo on Debian

apt-get install sudo

12) Add a user

adduser myname

Then, add the user to sudo…

usermod -aG sudo myname

You can check which users are in the group sudo by running…

getent group sudo

Then logout of root, login as myname and test sudo out by doing something that requires sudo privileges, e.g. restarting apache: service apache2 restart.

13) Public/private key pair

This is the main thing that is different on Windows PCs than it is with either Linux or Macs. For Windows PCs you have to use downloadable software, such as putty. This guide: Use Public Key Authentication with SSH talks you through the process.

The most important thing to note is that you should either be logged in as the user you want to make the key pair for when you make the ~/.ssh directory and put the authorized_keys file in it, or if you do it as root the location should be “/home/yourusername/.ssh/authorized_keys” and the owner should the yourusername not root. So, if you’re logged in as root you can run su yourusername to login as the user you’ve just created, then when you go to cd ~/ it will take you to “/home/yourusername/”. If you do it this way you have to make sure to check that the owner of the “authorized_keys” file is yourusername… chown yourusername:yourusername -R ~/.ssh as suggested here.

Then, logout of root and login with your user to check that the new user works correctly with the public key authentication. You should be asked for the keyphrase, as opposed to the password.

14) Turn off root login

If you can login with the username you set up with the public/private key pair you can “turn off” root logins.

Turn off root logins and turn off password authentication in the sshd_config file using nano…

nano /etc/ssh/sshd_config

For the changes you have made to work, you will need to restart SSH…

service ssh restart

15) Sending email

You will need to be able to send emails from the server to get the unattended-upgrades emails (if you have asked it to send emails).

Rather than send the emails manually this guide walks you through setting up postfix with Mailgun.

The only thing I found a little confusing was the mapping on this line…

[email protected]_hostname [email protected]_subdomain_for_mailgun

Really, as you’ll mainly be sending emails as a user (e.g. www-data or root) you should have lines like this to allow that…

root [email protected]

If you’ve set up your Mailgun account to use a subdomain, e.g. mail.example.com you can still use an address like [email protected] here!

Alternatively, https://www.debian.org/releases/jessie/amd64/ch08s05.html.en allows server to send email.

16) Fail2ban

Fail2ban

apt-get install fail2ban

Then, you can edit the config file, and/or make a local file…

nano /etc/fail2ban/fail2ban.conf

17) Firewall

For a firewall, UFW (Uncomplicated Firewall) is there for Debian systems. This is a good guide: Configure firewall with UFW

apt-get install ufw

As the guide says, you’ll have to be very careful when switching on the firewall that you do not lock yourself out of SSH.

18) Install MySQL and PHPmyAdmin

Here are two useful guides: MySQL and MySQL on PHP7.

apt-get install mysql-server
mysql_secure_installation
apt-get install libapache2-mod-php7.0 php7.0-mysql php7.0-curl php7.0-json

Then, once MySQL is installed there is more MySQL information here about how to create a database and a new user.

A good place to begin before installing PHPmyAdmin is by checking the phpmyadmin prerequisites and installing everything needed (e.g. mbstring). If 500 server errors, check the prerequisites again, installing anything that isn’t already installed, then re-install phpmyadmin to get rid of the error. Install PHPmyAdmin on Debian 8

sudo apt-get install phpmyadmin

For each virtual host that you would like to give access to your PHPMyAdmin installation, create a symbolic link from the document root to the phpMyAdmin installation location (/usr/share/phpmyadmin). You do this by moving into the public directory of each virtual host, then creating a symlink…

cd /var/www/example.com/public_html
sudo ln -s /usr/share/phpmyadmin

19) Monitor

You can monitor the performance and usage of the web server by using top… Just type top into the terminal and you’ll get a summary of the usage every few seconds.

Linux TOP command explained

You can also set up a script that will email you if certain conditions are met (RAM usage, for example).

20) Apache Config file

It’s a good thing to take a look at the apache2 config file to make sure it is configured correctly. One of the things you’ll want to check is that KeepAlive is set to off. From Setting up LAMP on Debian 8.

sudo nano /etc/apache2/apache2.conf
KeepAlive Off

TL;DR / Conclusion

Different setups are all slightly different. If you are getting errors the best thing to do is to either examine the error itself or find the relevant error logs and do some problem solving. Unix & Linux Stack Exchange and Server Fault tend to have a lot of problems already answered.

This is just a general guide to setting up a Linux Webserver with SSH with a Windows PC talking to a Debian 8 remote webserver. You may want to change the order I have followed here and there may well be steps I’ve missed out here, errors I get that you do not get, or vice versa. But, I hope it can be useful to someone.

After getting this far there will probably still be thing you need to do to your webserver. There will be other PHP and Apache modules that your web applications and/or frameworks require, such as mod_rewrite… As before, figure out what you need for your application and add it as required. Have fun!