A Technical Hick-up and Opportunities

Posted by Riomhaire Research on Monday, August 1, 2016

A couple of weeks ago on a Monday morning we noticed that we had stopped receiving email, and then we discovered that the company public facing website was also down!! A few expletives latter it turns out the server was down and to top it all it won’t reboot at all - cue more expletives.

The Problem

The server that ran the company website and email server was ancient - by ancient I mean 15+ years old. At one time it was our main developers desktop machine, but with the passing of time it was wiped and became our company web-server and email server. Apart from regular software updates she ran like the dependable workhorse she was and was left to her own devices - partially because when we set up the email server all those years ago it was a real pain to configure everything to get it running right. Alas she was dead - so what do we do!!! Fortunately we make regular backups of the databases, static files and configuration so we did not actually loose much in the way of emails or site updates. The question was - what next? There were a number of main options available:

  1. Get a new server or re-purpose another one and restore from backup.
  2. Look at docker or some other virtualization technology.
  3. Use an external hosting solution.

Option 3 was discarded - we like hosting our own site and it was cheaper too since we had spare hardware and a static IP address and our site and email preferences are relatively modest, although there are many pro’s to using a hosting service.

So this left option 1 and 2. Using a “bare-bone” machine as an email and website is common, BUT virtualization is becoming more and more common and when we did some research there are a number of docker images which provide email and website pretty much pre-configured (’tvial/docker-mailserver’ and ’nginx’). When you factor in the time to set up a physical server then you can save many hours going down the virtualzation route. The opportunity to modernize some of our infrastructure had presented itself and we grasped it. Option 2 it is.

The Company Website

The company website was a pretty static affair even though we were running wordpress (keeping that piece of software up to date is a big task in itself). There are many docker images for wordpress, but after some thought we came to the conclusion that it would be an over-kill for our actual needs. Recently we have been looking at the GO programming language (https://golang.org/) for some projects and had become aware of the excellent static website generator called ‘Hugo’ (https://gohugo.io/) which has a large number of available themes to use. Some more on-line research and a short meeting later the following steps to rebuild the company website using docker were defined:

  1. Find alternative hardware server, wipe it and install docker.
  2. Create folder structure suitable for nginx and hugo.
  3. Convert old website to be a one generated from a Hugo project - output folder being where docker nginx will serve the content from.
  4. Create docker-compose and nginx configuration files.
  5. Create AND install as a systemd service.
  6. Reconfigure router/dns to point to new company website server.

Step 1 - Preparing the hardware

We located a server which although not new is not old either - Has 8GB of RAM a decent 120GB SSD drive. Enough for what we want. After installing The Latest Ubuntu 16.04 server image we installed the latest docker version - the post https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04 covers this.

Step 2 - Creating Folder Structure.

We want nginx to serve content from a folder (which will be ngnix root folder), but also we will need a config for nginx and a docker-compose configuration. We created a ‘services’ user on the new server and created the following file structure:

/home/services/websites/www.riomhaire.com
    /conf/
    /html/
    /src/

We will store the docker and services stuff in the ‘…./www.riomhaire.com’, the hugo files in ‘src’ and the generated files in the ‘html’ (nginx root). The ‘conf’ folder will contain the nginx configuration.

Step 3 - Converting The old Website to Hugo format

Taking from backups for the website (including a static website backup using the WGET - see https://www.guyrutenberg.com/2014/05/02/make-offline-mirror-of-a-site-using-wget/ ) it was fairly simple to take this and create a new responsive company website within a couple of hours within the ‘src’ folder mentioned and generated into ‘html’. Hugo has a built in webserver which allowed us to check that the site looks like what we expected.

Step 4 - Create docker-compose and nginx configuration files.

Firstly since we want to the user the nginx docker image we need to down load it. This is done via the command:

docker pull nginx

Then we need to create a nginx ’nginx.conf’ configuration file within the ‘/home/services/websites/www.riomhaire.com/conf’ folder. For what we wanted this is a rather sparse:

user nobody nogroup;
worker_processes auto;          # auto-detect number of logical CPU cores

events {
  worker_connections 512;       # set the max number of simultaneous connections (per worker process)
}

http {
  server {
    listen *:80;                # Listen for incoming connections from any interface on port 80
    server_name "";             # Don't worry if "Host" HTTP Header is empty or not set
    root /usr/share/nginx/html; # serve static files from here
    include       /etc/nginx/mime.types;
  }
}

Note we are serving on port 80 internally.

The Docker compose file (’/home/services/websites/www.riomhaire.com/docker-compose.yml’) to build and run everything is equally simple:

website:
    image: nginx
    # build: .
    hostname: www
    domainname: riomhaire.com
    container_name: riomhaire-website
    ports:
    - "80:80"
    volumes:
      -  "/home/services/websites/www.riomhaire.com/html:/usr/share/nginx/html:ro"
      -  "/home/services/websites/www.riomhaire.com/conf/nginx.conf:/etc/nginx/nginx.conf:ro"

Note the volumes definition where we map the nginx configuration and the generated site folder mapping so the container can serve the content we want.

To start the service all that is required is ‘docker-compose start’ and thats it … the company website was up and running on port 80 - ALMOST. Why ‘ALMOST’ ? Well although the above got the site up and running it did not do that automatically on computer reboot. The solution to this comes in two parts. Firstly enable the docker service on boot-up:

systemctl enable docker

The second is to start the container website container once docker is running.

Step 5. Create AND install as a systemd service.

On the server where the docker daemon is running auto-starting virtualized containers can be achieved via a number of methods - a good place to look is dockers own documentation https://docs.docker.com/engine/admin/host_integration/ . We decided to go down the systemd route since the server we are using runs Ubuntu and we have used systemd before.

The process is fairly straight forward:

  1. Create a systemd service file defining how to start and stop the service and its dependencies.
  2. Copy it to the ‘/etc/systemd/system/’ directory.
  3. Set the access permissions.
  4. Enable the service via the appropriate ‘systemctl’ command described above.

The ‘website.service’ file we defined is fairly straight forward:


Description=Website Service Container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a riomhaire-website
ExecStop=/usr/bin/docker stop -t 2 riomhaire-website

[Install]
WantedBy=default.target

After following the steps test it with start and stopping the service via systemctl (‘start’ and ‘stop’ options).

Job Done.

Step 6. Reconfigure router/dns to point to new company website server.

This step is dependent on how your infrastructure is set up. In our case we used a different IP address on the server hosting the website to the server that had died. So remember to reconfigure your router/ADSL-modem to forward website traffic to the new server.

We hope this post has been useful. Soon we will be posting one on how to set up a docker based email server.