I like music, films, travelling and most things computer related. This here's a blog.

  • » Updated - Using Docker and Nginx to serve multiple Wordpress sites » 18 Sep 2016

    Two things happened recently: My SSL certificate for capslocknotificationapp.com expired and I needed to launch a new Wordpress site.

    I went to my old server and revisited my old Docker setup (detailed in a previous post here) and it was in a bit of a state. It was using a very old version of Docker and it was a pain to get a new certificate etc.

    Anyway, I decided to rework the whole shebang:

    • updated Docker (v1.12 - latest at the time) so I can use Docker Compose (v1.8.0), allowing the setup to be a bit more flexible in the long run.
    • integrated Let’s Encrypt so I don’t have to deal with Comodo via the HTTPS_PORTAL container.
    • switched from MySql backend to the maintained, compatible and open source MariaDB.

    Here are the steps:


    1. Get a DigitalOcean instance
      • This time I got a beefier 2GB Ram, 40GB SSD instance as I intend to be running more (non-critical) sites from it.
    2. A suitable OS that supports Docker
      • I selected Ubuntu 16.04, although I think CoreOS is a good option too.
    3. Create a SSH key on your local box - guide here
      • unless you set up the SSH during the DO instance creation, which wasn’t working for me.

    DigitalOcean box setup

    We want to secure the DO instance and make sure it is up to date.

    SSH into the box using the password/IP address sent in the DO email and change the password. Add your newly created SSH key to the DO instance:

    cat ~/.ssh/<your-key>.pub | ssh root@[your.ip.address.here] "cat >> ~/.ssh/authorized_keys"

    SSH into the box and update the SSH config file (sshd_config) to stop SSH connections using the password. (You might want to setup an SSH config to make this easier: info)

    sudo nano /etc/ssh/sshd_config

    Change or add the following line to the ‘Authentication’ section:

    PermitRootLogin without-password

    Restart the SSH server for the changes to take effect

    ps auxw | grep ssh
    kill -HUP <PID of SSH process>

    Setup swap space for MariaDB use later on

    The database eats up a lot of memory and I found it killed some of my docker container. A way to solve that is to give the box more swap space. I set it to 4G due to the amount of space/memory I had on my box. Yours may differ.

    sudo swapon -s
    free -m
    sudo fallocate -l 4G /swapfile
    sudo chmod 600 /swapfile
    ls -lh /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    sudo swapon -s
    free -m

    Next we need to update the filesytem partition confi file

    sudo nano /etc/fstab

    Then add to the bottom (if /swapfile is not already there)

    /swapfile   none    swap    sw    0   0

    Install the latest Docker files

    These steps install the latest Docker Engine and Docker Compose. Steps taken from their website here and here. Check them out for additional configurations!

    # Install Docker Engine
    sudo apt-get update
    sudo apt-get install apt-transport-https ca-certificates
    sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
    sudo rm /etc/apt/sources.list.d/docker.list
    sudo touch /etc/apt/sources.list.d/docker.list
    sudo echo 'deb https://apt.dockerproject.org/repo ubuntu-xenial main' >> /etc/apt/sources.list.d/docker.list
    sudo apt-get update
    sudo apt-get purge lxc-docker
    sudo apt-cache policy docker-engine
    sudo apt-get update
    # Requires manual input:
    sudo apt-get install linux-image-extra-$(uname -r)
    sudo apt-get update
    # Requires manual input:
    sudo apt-get install docker-engine
    # Start and test docker install
    sudo service docker start
    sudo docker run hello-world
    # Start docker automatically on box restart
    sudo systemctl enable docker
    # Install Docker Compose
    curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose

    Setup DO instance for HTTPS_PORTAL and Wordpress containers

    There needs to be some data saved and shared on the DO box, so we need to create folders for them

    # Folder to store Nginx config files for each site
    mkdir -p ~/sites/conf.d/
    # Folder to store LetsEncrypt generated SSL certs
    mkdir -p ~/sites/ssl_certs/
    # Folder to store MariaDB data
    mkdir -p ~/sites/mysql/data/
    # Folder(s) to store Wordpress sites
    mkdir -p ~/sites/www/wp-<sitename>/
    cd ~/sites

    Create Docker Compose files for HTTPS_PORTAL and Wordpress containers

    I have two Docker Compose files to create and run my containers. One is for HTTPS_PORTAL and the other is for MariaDB and Wordpress sites. Unfortunately, the compose files need to use V1 syntax, due to underlying containers using that old syntax.

    HTTPS_PORTAL listens for and will generate LetsEncrypt SSL certs on any containers created that have a VIRTUAL_HOST environment variable set.

    Create a file ~/sites/https_portal.yml

      container_name: https-portal
      image: steveltn/https-portal
        - '80:80'
        - '443:443'
      restart: always
        STAGE: 'production'
        - /root/sites/conf.d:/etc/nginx/conf.d/:rw
        - /root/sites/ssl_certs:/var/lib/https-portal:rw
        - /var/run/docker.sock:/var/run/docker.sock:ro

    This sets up:

    • the ports to listen and expose
    • makes sure the container is always restarted
    • hooks into the nginx configs and SSL certs

    Next, create a file ~/sites/sites.yml

      container_name: mysql
      image: mariadb
      restart: always
        - /root/sites/mysql/data:/var/lib/mysql:rw
      container_name: wp-SITE1
      image: wordpress
      restart: always
        - mysql:mysql
        VIRTUAL_HOST: SITE1.com, www.SITE1.com
        - /root/sites/www/wp-SITE1/:/var/www/html:rw
      container_name: wp-SITE2
      image: wordpress
      restart: always
        - mysql:mysql
        VIRTUAL_HOST: SITE2.com, www.SITE2.com
        - /root/sites/www/wp-SITE2/:/var/www/html:rw

    This sets up:

    • the MariaDB instance, with password
    • wordpress sites, each with it’s own database instance
    • VIRTUAL_HOST environment variable for each site with acceptable url’s
    • makes sure the containers are always restarted

    Finally, to run the sites we just run docker-compose and it will create the containers as daemons and also ensure they are not destroyed/recreated if the command is re-run.

    # Launch HTTPS_PORTAL
    docker-compose -f https_portal.yml up -d --no-recreate
    # Launch sites
    docker-compose -f sites.yml up -d --no-recreate

    ### PHPMyAdmin

    If you want to run PHPMyAdmin against the database

    docker run --name phpmyadmin -d --link mysql:db -p 8080:80 phpmyadmin/phpmyadmin

    Just remember to stop the container when you are done!

    Show comments

  • » Allowing multiple Disqus comment threads on a single page » 25 Aug 2015

    I show multiple posts on the main page of this blog, and as it is essentially a site static (run off GitHub Pages), I don’t have the ability to run my own commenting system.

    Luckily, there is a service called Disqus that provides an easy way to enable comments on each post. The issue is that you can only have once comment thread on a single page due to the way Disqus embeds its comment form and use of global variables.

    Fortunately, we can get around this with a bit of hackery and allow for multiple threads per page. Although, technically, only 1 thread is shown at any one time and there is a nasty looking browser exception thrown occasionally.

    First, we need to add the ability to show comments:

    <a class="comments-load" onclick="loadDisqus($(this), 'The Title Of The Thread', 'a-unique-url-tag');">
      Show comments
      Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a>

    When a user clicks on the ‘Show Comments’ link, the loadDisqus function is called. I put the following in a separate Disqus.js file that is loaded with the page:

    // Global variables needed by Disqus. The identifier and url should be different for each comment thread.
    var disqus_shortname = 'donalfarrellblog';
    var disqus_identifier;
    var disqus_url;
    // Loads the Disqus JS file that will create the comment form and threads.
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; // Found in disqus.js script
    // Called in each location you want to show the thread.
    // Disqus searches for 'disqus-thread' elements and uses the first one it finds so to
    // overcome this, the function will clear any previous comment threads (by finding 'comments-load' elements)
    function loadDisqus(element, postTitle, postUrlTag) {
      var identifier = postTitle;
      // Including the hashbang ('/#!') is important.
      var url = window.location.origin + '/#!' + postUrlTag;
      var disqus_identifier = identifier;
      var disqus_url = url;
      if (window.DISQUS) {
        // Horrible, but jQuery wasn't removing the div elements fully
        $( ".comments-load" ).each(function() {
          var len = this.childNodes.length;
          for(var i = 0; i < len; i++)
            if (this.childNodes[i].tagName == "DIV") {
        $(element).append('<div class="disqus-thread" id="disqus_thread"></div>');
        /** if Disqus exists, call it's reset method with new parameters **/
          reload: true,
          config: function () { 
            //important to convert it to string
            this.page.identifier = identifier.toString();    
            this.page.url = url;

    Show comments

  • » Local Development with Docker, Nginx to serving multiple Wordpress sites » 21 Aug 2015

    Quick post here.. my last post focused on hosting multiple Wordpress sites on a remote DigitalOcean instance, which is grand and all but most developers want to run things locally first to test things out.

    Here’s a quick guide to getting things ready locally before running the steps in the previous post

    1. Install DockerToolbox from Docker.io.
      • This also installs Kitematic, which is a handy GUI for managing Docker containers.
    2. Start Docker/Kitematic and run the following command to get the IP Address of the underlying virtual machine:
      • ‘default’ is the name of the VM Docker Machines creates on setup.

        docker-machine ip default
    3. Update your hosts file to point to the expected SSL domains:
      • On OSX, run the following command in the terminal:

        sudo nano /etc/hosts
      • Insert a line for each SSL certificate you want to use (The I.P. Addr is whatever the boot2docker vm IP Addr is) e.g: capslocknotificationapp.com <SSL-Cert-Name>
      • Sometimes you need to refresh the DNS Cache:

        dscacheutil -flushcache; sudo killall -HUP mDNSResponder
    4. Get your SSL Certificates and create a folder to place them in.
      • Ideally, create a sub-folder in the local Kitematic directory (you can change the where a Docker container’s volume points to in Kitematic)
      • On OSX, Kitematic defaults to /Users/<username>/Documents/Kitematic

        mkdir /Users/<username>/Documents/Kitematic/nginx-proxy/root/certs
    5. Run the steps in the previous post.

    This should get you up and running with the ability to test HTTPS connections.

    Note: Don’t forget to remove the host file redirects before testing the real site!

    Show comments

  • » Using Docker and Nginx to serve multiple Wordpress sites » 11 Aug 2015

    Note: There is an more recent post that uses an updated method with Docker Compose. Read it here

    I’ve just moved back to London and have a bit of spare time to work on a few of my side projects so I decided to have a bash at re-working my websites, notably CapsLock Notification app.

    I use DigitalOcean (Note: Referral link!) to host my sites and I didn’t really want to spin up new instances for each of my sites as for a lot of the time they would be sitting idle, wasting resources and adding unecessary cost.

    Currently, my sites are run on Wordpress so my requirements are:

    • Ability to share the same MySql instance (as these are memory hogs individually)
    • Have a mechanism to route requests to the appropriate site
    • Routing should allow for SSL Certificates

    The lastest releases of Wordpress allow you to host multiple sites but my brief look at this found it clunky and as a bit of a tech enthusiast I’ve been looking to get my hands dirty with Docker and this fits the bill.

    So, here’s how to set up a single DigitalOcean instance to host multiple sites including routing and HTTPS.


    1. Get a DigitalOcean instance
      • I recommend a 1GB Ram, 20GB SSD instance as the MySQL database eats a lot of memory!
    2. Install Docker (I’ve been using v1.7.1)
      • DigitalOcean provides pre-made Docker images for easy set up.

    Generate certificates for each of your sites

    Once we have access to the DO server instance we need to generate certificates so we can get SSL certificates for HTTPS.

    Hopefully this will become much more streamlined once Let’s Encrypt has launched

    1. Create private key and CSR on the server:

    openssl req -new -newkea rsa:2048 -nodes \
      -keyout capslocknotificationapp.com.key \
      -out capslocknotificationapp.com.csr

    Note: resultant file should be <domain-class>.<domain-name>.<extension>.crt e.g blog.donalfarrell.com.crt

    2. Generate SSL certificate with Certificate Authority

    Copy the .key and .csr files from the server to a local machine and register the SSL cert as necessary.

    If you used Comodo as you CA, wait for verification email with certificate chain. Condense the chain into one .crt file:

    cat capslocknotificationapp_com.crt \
      COMODORSADomainValidationSecureServerCA.crt \
      COMODORSAAddTrustCA.crt \
      AddTrustExternalCARoot.crt \
       > capslocknotificationapp.com.crt

    Note: resultant file should be <domain-class>.<domain-name>.<extension>.crt e.g blog.donalfarrell.com.crt

    3. Copy final .crt certificate back to server:

    scp capslocknotificationapp.com.crt <user>@<server-name>:/root/certs/

    Set up Nginx Reverse Proxy

    Now we have the certificates in place we want to set up a server to route any requests. This should be able to look at the incoming request and be able to point it at the correct site and attach any matching certificates.

    Apache is quite clunky in my opinion and the new hotness is Nginx, so I went with that. There is a fantastic docker image that allows you to create a Nginx reverse proxy complete with dynamic configuration generation and matching of SSL certificates. Details of it can be found here: http://jasonwilder.com/blog/2014/03/25/automated-nginx-reverse-proxy-for-docker/

    ### Configure nginx reverse proxy: docker run -d
    –name nginx-reverse-proxy
    -p 80:80 -p 443:443
    -v /root/certs:/etc/nginx/certs
    -v /var/run/docker.sock:/tmp/docker.sock:ro


    You can easily add customised config directories for each hosted site by adding a volume pointing to the configs:

    -v /root/nginx-configs:/etc/nginx/vhost.d:ro

    Again, the naming convention is important and should be the name of your domain (no .config either!)

    Set up MySQL instance

    As I run Wordpress sites, I need to use MySQL as my backend store. With Docker, I have a choice of running a Wordpress image that has MySQL already included, or pointing a Wordpress image to a dedicated MySQL instance.

    docker run -d \
      --name mysql-db \
      -v /root/mysql/data:/var/lib/mysql \
      --restart=always \

    Note: Memory buffer issues

    You may find that your MySQL instance aborts occasionally as you add more databases and run more docker containers. This is usually due to insufficient memory in your server instance. A useful tip is to add/increase the swap space on your server:


    Note: PHPMyAdmin

    A useful tool to look at the contents of the MySQL instance is PHPMyAdmin. This tool creates an admin portal that is accessible through a webpage.

    docker run -d \
      --name phpmyadmin \
      -p 1000:80 \
      --link mysql-db:mysql \

    Set up web containers

    Finally, we are ready to create our Wordpress sites (alhthough, the method will work for any other site I’d imagine). Below I set up 2 separate Wordpress containers and point each to the MySQL instance with each creating it’s own database.

    1. Your first Wordpress Container

    docker run -d \
      --name wp-site1 \
      -e WORDPRESS_DB_NAME=wpsite1db \
      --link mysql-db:mysql \
      --restart=always \

    2. A second Wordpress Container

    docker run -d \
      --name wp-site2 \
      -e WORDPRESS_DB_NAME=wpsite2db \
      --link mysql-db:mysql \
      --restart=always \

    The <SSL-CERT-NAME> is the name of the SSL cert you copied to the /root/certs/ folder, e.g capslocknotificationapp.com. You do not need to include the .crt extension!

    Typing the URL into the browser (as long as you have pointed the DNS records to the IP address of the DigitalOcean server) you should now see the Wordpress installation page.

    Show comments

  • » VirtualBox and Windows 8 » 28 Nov 2013

    Ok, so my previous post put a lot of blame on Windows 8, but I’ve come to realise it may be due to the environment (although, Windows 8: The Experience is still not great).

    I run linux so I decided to use my VirtualBox instance to boot up Windows 8. I got to coding and quickly had a working app that was recieving keypresses and showing a notification. But I hit a problem. For an unknown reason, when I pressed the CapsLock key, I was getting two notifications in quick succession as if I had pressed it twice. In debug mode it never appeared. Even stranger, if I added a second delay in my event handler there was only one notification!

    Unusual, but it had a workaround. The real showstopper was that although I could detect a CapsLock keypress, there was no way of determining if CapsLock was enabled or not. Every state reading put it as false. Numerous libraries were tried and numerous hooks made into low level COM objects but nothing worked. As a final attempt I decided to run my code on an actual Windows 8 desktop - success! A quick installation of Windows 8 on VMWare Player found it was working also.

    So there seems to be a defect in how VirtualBox handles keyboard input in Windows 8 guest, or maybe it was a dodgy install? Regardless, there’s a VirtualBox bug ticket for it now.

    Show comments

  • » Windows 8 Horror » 27 Nov 2013

    Ok, I’ve taken on a side side-project creating a simple CapsLock notification for Windows 8. It seems that there is no indication whether CapsLock is on or not, except if you are using an on-screen keyboard (e.g on a tablet), or if you are at the login screen. You can turn on an annoying beeping sound but it only really has the effect of letting you know you have hit the CapsLock button, not if the system is in uppercase or not.

    While this doesn’t directly affect me (I use Crunchbang), my Dad finds it a pain in the ass, particularly when entering passwords. As I have a fair bit of C#/WPF experience I thought I’d whip up a quick notification on the desktop when in caps mode. I should be so lucky.

    All I have managed in about 4 hours is restart windows 4 times, install Visual Studio 2013 Express, attempted to run several official vs2013 samples, tried repairing VS2013 (which actually just redownloads everything). It is infuriating. For some unknown reason, there are two separate versions of Visual Studio 2013 Express. One for standard Windows Desktop development and one for new ‘Metro’ apps, cleverly named Windows. Why they didn’t bundle them together I can’t fathom. Either way it seems all the samples are directed for the Metro version.

    I’ll have one more optimistic bash at it then I might burn a copy of windows 8 just to have the satisfaction of throwing it out.

    Edit: Note for the future - the majority of samples require Windows API Code Pack

    Show comments

  • » Movement » 26 Nov 2013

    Although the tag line for this site is ‘Born in Belfast; working in London’, it should now really read ‘Born in Belfast; worked in London; back in Belfast’. In the last month I have moved back to Belfast. It’s just a temporary measure though, so back to the job in London around April.

    So this means I’ve suddenly got a lot more free time. Most of it has been taken up with handyman tasks that have been a refreshing change of pace, but I’ve also been able to tinker away with some small projects.

    One such project is Hubblog (site still in development…). It is an Android app with the aim to make it easy and quick to write articles in markdown or plaintext and post them to a Jekyll-based blog, like this one! As this blog is hosted using the fantastic GitHub-Pages, currently Hubblog only connects to that service for posting and editing articles.

    Aside from the actual use of the Hubblog app, there were two main motivations to creating it:

    • I’ve had no previous experience with making Anroid apps, aside from a quick day or two messing around, so I was keen to make a non-trivial app that followed good code and design patterns.

    • I needed encouragment to write more (it’s a skill I’m trying to develop..so blogging seems to be the best way) and by creating an app I suddenly have something interesting to write about!

    Hopefully, future posts will be written from the app!

    Show comments

  • » Films and Tv » 24 Sep 2013

    I watch a horrendous amount of films and tv. The majority hit the bar at terrible consisting of a pick-n-mix of swiss-cheese plots, cardboard acting and disillusioned direction.

    Regardless, I find myself forced to watch because how do you know the good if you don’t know the bad? That’s my logic anyway.

    So with a bit of inspiration from the flatmate, I decided I should start to blog about what I watch. This will serve to help me remember what was good and bad and also let me slag of the really shit parts of a movie. Or the whole thing (I’m looking at you ‘Jobs’).

    I’ve created a subdomain for this at thethingsiwatch.donalfarrell.com. No content yet as i’ve a couple of things to finish off, but will hopefully be done soon.


    Show comments

  • » Finally... Part 2 » 09 Sep 2013

    Just over a year ago I set up this page, then promptly left it alone with the exception of 4 posts. Not this time! No, this time it’s different!

    This time i’ve put up a nicer design and some flashy icons.

    Also, i’ve got some new projects in my head I want to crack on with (‘cause who wants to finish the old ones?) so hopefully i’ll get a few posts out of them.


    Show comments

  • » GigSpotting Beta is ready to use » 19 Sep 2012

    So I have deployed my other side project, GigSpotting, to the internets.

    The premise of the project is to allow a user to search for an artist and a location and have any relevant gigs show up on the map along with the date and additional details, such as supporting artists. As there may only be one or no results, similar artists are also searched and will appear alongside the original artists.

    It is still in the very very early stages, but you can do a basic search (which is slooow) and artists will be plotted onto the map.

    Show comments

  • » Issues with Calex and GitHub » 17 Sep 2012

    So my side project Calex is pretty much finished, except for one critical issue - adding a new blog post is not possible while using a custom domain.

    To give a quick summary, the idea behind Calex was to easily add and view what activities/tasks were done on any particular day. Using GitHub Pages to host, the main page is one big calendar and has a nice tick for each day that I accomplished a task. Adding a new task for a day was a matter of committing a new post with details of what I had done.

    Committing a new blog post is easy if I am on my development machine and have SSH GitHub access but I wanted it to be able to commit from anywhere (e.g from my mobile). Hence, I created a page to commit new posts that formats them nicely with markdown syntax.

    I use a javascript library, GitHub-WebCommit, to commit to the Calex GitHub repository by following the GitHub API. This is where the problem lies. In normal circumstances, the javascript library works exactly as planned and will easily commit a new post from a project page but only if the domain is still showing ‘xxxx.github.com’ or from ‘localhost’.

    Github Pages gives you the ability to use custom domains, which is what I am doing with this site, but as I have set my main User Page all other GitHub project pages in my repository will use this custom domain. For that reason the javascript commit requests will use ‘donalfarrell.com/calex’ as their origin which is a big no-no as it violates the same domain policy.

    I’ve tried many things to get around this, but the simple fact is that I need to either set the domain name to be ‘xxxx.github.com/calex’ (something I am unwilling to do as I will lose this blog domain), or to register the app with GitHub and implement the OAuth protocol.

    Show comments

  • » Setting up GitHub redirects » 13 Jul 2012

    This site is actually hosted on GitHub. It uses the fantastic GitHub Pages service, which uses the Jekyll static site generator. It essentially serves up whatever content you have in your git repository.

    While this works fine, the default url that is used by GitHub to display the site is http://Username.github.com/. Luckily you can set up your own custom domains in GitHub. This involves nothing more than adding a CNAME file to your repo and adding whatever redirects you want. In mine I have only one site:


    Setting up my DNS settings was a little tricker. The GitHub documentation is a little vague on this so I had to do a little fiddling to get mine working:

    DNS Settings

    Any changes you make to your DNS settings take a few hours to update.

    A nice side effect is that any other GitHub projects that you set up to use Pages will automatically show the correct url in the address bar e.g. my project CaleX

    Show comments

  • » Finally... » 07 Jul 2012

    I’ve finally got this site in order! I’m not planning on updating this regularly, but i’ll do the odd bit here and there. Hopefully you should start seeing content soon.


    Show comments