Making docker shiver

5 min read.

So I thought I would start my new blogging career by writing up how I’ve got this blog up and rolling. The technologies, or frameworks, that I decided to use are Ghost and Docker. I got all this up and running using DigitalOcean, a lightweight cloud-hosting platform similar to Amazon AWS.

Why Ghost?

Ghost is new blogging platform. In fact, it is still in its beta phase with version 0.3.3 being the current version as of writing this post. It got funded through Kickstarter earlier this year. It is built upon nodejs and currently you’ll have to download the source itself and host it on your own. In the future they hope to be able to also provide ghost as a platform as well.

I have for a long time had many thought of starting blogging and I’ve also had thoughts of building a personal site but never come around to doing it. Then a few weeks ago I saw a article about it and thought that I could give it a try. I could have used wordpress as well but I have wanted to spend some more time with node and I hope this might give me chance to do exactly that.

Why Docker?

We’ve started using Docker in my current project at work and as I’ve come to understand it, it seems to be a fast and simple way to setup web applications. I’m really not an expert in this area and I probably don’t know how it all works, but I would like to know more about it. Also it I’ve been looking for a way to host things I build with ease. I’ve earlier looked into using Chef, where you can setup your system once and then replicate it. This kind of solution is preferable to me because I’m not much into because being a sysadmin. I also looked at dokku a Docker powered self hosted version of Heroku but in the end I ended up only using Docker as is.

The Setup

What you will need to get this setup up and running are the following

  1. A Linux based hosting service
  2. A virtual machine running Linux (check out Vagrant)

I won’t go through how to install Docker or Ghost in any greater details. If you want to know more on how to do it there are great getting started documentation both Dockers and Ghosts webpages. Also, the source for this docker image can be found at Github.

You’ll need the following folder structure

    /
    |-Dockerfile
    |-ghost-0.3.3.zip
    |-config.js

The ghost.zip file in this case is the source code and the config.js will become your config.js for the ghost node application. The Dockerfile can be referred as the manifest file for your application when you’re going to build your Docker image. This is how mine looks like for getting my Ghost node application running.

  FROM ubuntu:12.10

  # Volumes
  RUN mkdir /data
  VOLUME ["/data"]

  #install dependencies
  RUN apt-get install -y python g++ make software-properties-common
  RUN add-apt-repository ppa:chris-lea/node.js
  RUN echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
  RUN apt-get update -y

  #Install nodejs and unzip
  RUN apt-get install -y nodejs unzip

  # Add Ghost zip to image
  ADD ./ghost-0.3.3.zip /tmp/

  # Unzip Ghost zip to /data/ghost
  RUN unzip -uo /tmp/ghost-0.3.3.zip -d /opt/ghost

  # Install Ghost with NPM
  RUN cd /opt/ghost/ && npm install --production

  # Add custom config js to /data/ghost
  ADD ./config.js /opt/ghost/config.js

  #change workdir to opt/ghost
  WORKDIR /opt/ghost

  # Expose port 2368
  EXPOSE 2368

  # Run Ghost
  ENV NODE_ENV production
  RUN pwd
  RUN echo $NODE_ENV
  ENTRYPOINT ["/usr/bin/npm","start"]

It basically tells Docker to use ubuntu 12.10 as a base and to install the necessary dependencies to the images. It will also add the ghost application and the config.js file to the image and finally, when everything is setup it will start the node application using npm start.

When it comes to the config.js file mine look something like this (some parts omitted)

  var path = require('path'),
  config;

  config = {
      development: {
         ...
      },
      production: {
          url: process.env.GHOST_URL,
          mail: {},
          database: {
              client: 'sqlite3',
              connection: {
                  filename: '/data/ghost.db'
              },
              debug: false
          },
          mail: {
            transport: 'SMTP',
            options: {
              service: 'Mailgun',
              auth: {
                user: process.env.MAILGUN_USER,
                pass: process.env.MAILGUN_PASS
              }
            }
          },
          server: {
              host: '0.0.0.0',
              port: '2368'
          }
      },
      testing: {
          ...
      },
      travis: {
      	...
      }
  };
  module.exports = config;

With this config file we can give environment variables when running the Docker image to configure our ghost application. I’m using the following environment variables

  • GHOST_URL - the URL to your blog
  • MAILGUN_USER - mailgun credentials
  • MAILGUN_PASS - mailgun credentials

For my setup I’ve chosen to use the Mailgun service but there are other ways to do it as well. If you would like to use something like gmail instead I suggest that you checkout the Ghost Documentation.

Building and running the Docker Image

When all files are in place we’ll have to build a Docker image using the following command

  sudo docker build -t <username>/ghost path/to/Dockerfile

If everything went as it should you will be able to run your new image using

	sudo docker run -e GHOST_URL=<your-blog-url> -e MAILGUN_USER=<your-mailgun-user> -e MAILGUN_PASS=<your-mailgun-password> <username>/ghost

Then run

	sudo docker ps

And retrieve the port that Docker have assigned to communicate with the running Docker container and you’ll be able to access your new ghost blog through < your-blog-url >:< port >

Alternatives

If you don’t feel like building the Docker image yourself then you can use

	sudo docker pull nilpath/ghost

To retrive my version of the Docker image and then you can just use the Docker run command as stated above. Although you will need to setup your own mailgun account.

Conclusion

That’s it! It isn’t really an in depth tutorial but I hope you get the idea. If you have any questions or feedback about this post, then you can contact me on @nilpath over at twitter.

comments powered by Disqus