Getting this blog up and running using Ghost, Traefik and Docker - more complicated than I expected!

Welcome to the first post on my blog! I am very new to this, so don’t expect anything too exciting just yet.

I started this blog to help convey everything I am learning on a day-to-day basis in some sort of interesting or helpful way.

For my first post, I thought the best idea would be to explain how I am running this blog, and where it is hosted. I will be going into more depth on each one of these services in future, in separate posts.

So please bear with me while I go through this, step by step…

We start with where the blog is being hosted, I am using AWS (Amazon Web Services) for hosting at the moment, this may change in future, but for now this is what I am most comfortable with. This is running on a standard t2.micro instance, running Ubuntu 16.04, in the free tier ;)

We then move onto what is being used to actually host the blog content. I decided to use Ghost as a blog backend, as it had been recommended to me by a friend, and I found it to be a platform that is very simple to set up and quickly get started. I also found that there are lots of areas that can be tweaked/customised within Ghost, however I am currently using mostly default configuration.

In order to get Ghost up and running, I decided to use Docker and Traefik. The process that I used was as follows:

Docker

Getting Docker up and running on an Ubuntu instance is dead simple, simply run: apt-get update followed by apt-get install docker and apt-get install docker.io, obviously this can be merged into a single command for those who are comfortable with that.

Once docker is actually installed, I established swarm mode on Docker, to allow the Docker Swarm commands to be run, as well as the possibility of more nodes, and auto-scaling at a later stage, if this is really required. I did this by simply running docker swarm init on the host. You can see this worked by running docker info on the host. You will then see a section that says:

 Swarm: active
 NodeID: <NODEID>
 Is Manager: true
 ClusterID: <CLUSTERID>
 Managers: 1
 Nodes: 1

This means that swarm mode is active, and we are ready to continue with setup!

With swarm mode activated, the next thing I did was establish an overlay network for Traefik to run on within the swarm. I did this by running docker network create traefik --driver=overlay

I will be explaining what this does in more detail in a later post.

With Docker, swarm mode and the overlay network up and running on the instance, I decided to implement Traefik as a frontend and management system for myself and the server itself, to allow me to run more than just this blog on the single instance if needed. This is also especially useful as Traefik will act as the reverse proxy and load balancer, should I require these features in future.

Before starting with creating the services, I needed to create the overlay network

Traefik

To get Traefik spun up in Docker, I decided to create it as a Docker service, allowing Docker to auto-heal the service should the container ever die or restart for some reason. The command that I used to start the Traefik service in Docker was the following:

docker service create \
--mount src=/var/run/docker.sock,dst=/var/run/docker.sock,type=bind \
--name traefik \
--network traefik \
--publish 8080:8080 \
--publish 80:80 \
traefik:latest \
--web --docker --docker.swarmmode --docker.watch --logLevel=DEBUG

I’m going to break this down, so that I can explain what each part of this is doing:

docker service create \ - pretty self explanatory

--mount src=/var/run/docker.sock,dst=/var/run/docker.sock,type=bind \ - This binds the docker.sock on the host to the Traefik service, so that Traefik can watch/listen for new containers and services being spun up on the host, and automatically create routing for them.

--name traefik \ - establishes the name for the service.

--network traefik \ - This attaches the service to the Traefik network that we created earlier.

--publish 8080:8080 \ - This publishes port 8080 from the Traefik service. By default this port is used for the Traefik web interface.

--publish 80:80 \ - This publishes port 80 from the Traefik service.

traefik:latest \ - This uses the latest version of traefik from the docker repo.

--web --docker --docker.swarmmode --docker.watch --logLevel=DEBUG - These are Traefik specific flags, in order: –web tells Traefik to expose its web interface, –docker tells Traefik we are using Docker back ends, –docker.swarmmode tells Traefik we are using docker in swarm mode, –docker.watch tells Traefik to watch the docker sock for new services created automatically.

Ghost

Now that we have Traefik up and running, I ran the following to get the Ghost publishing platform up and running:

docker service create \

--network traefik \ - attach Ghost to Traefik network

--name ghost \ - gives name to the service

--label "traefik.port=2368" \ - Tells Traefik that the Ghost service is listening on 2368.

--label "traefik.frontend.rule=Host:blog.devinsmith.co.za" \ - tells Traefik that the front end host needs to be blog.devinsmith.co.za.

--label "traefik.docker.network=traefik" \ - tells Traefik to use the Traefik network on this service.

--mount src=/blogdata/config.production.json \
 dst=/var/lib/ghost/config/production.json,type=bind \ 

These two mounts mount the ghost files from the host to the ghost service, so that the data persists if the service dies/restarts. I will be explaining the structure of this in a future post!

ghost:latest - this tells the service to use the latest image of Ghost in the docker repo.

And now if we run a docker service ls on the host, we get the following result:

ID            NAME     REPLICAS  IMAGE           COMMAND
6r892i0okfke  ghost    1/1       ghost:latest
dcb0v611ecau  traefik  1/1       traefik:latest  --web --docker --docker.swarmmode --docker.watch --logLevel=DEBUG

All good to go! Everything seems to be running smoothly! If we go have a look at blog.devinsmith.co.za on port 8080, we see the Traefik frontend, and everything seems to be happy!

Thanks for sitting through that with me! I am still working on exactly how to write everything, but if you made it this far, let me know what you’d like to hear about next, I am hoping to write separate posts about everything I used here, including Docker, Ghost and Traefik.

Please give me comments and suggestions below, let me know what is good, what is terrible, what you loved and what you didn’t.

comments powered by Disqus