September 29, 2017

Continuous Deployment Blogging

As I make an attempt at blogging I thought it would make sense to have my first “official” post be about how I ended making my blog. I chose my stack based on ease of use, speed of deployment, and cost (aka only free things). As I started to set things up and research tools to use I decided I wanted deployment to be so easy that I wouldn’t have to think about it. So after playing around with different things this is the stack I ended up with.

  • Hugo for static file generation.
  • Firebase to host the static files.
  • CircleCI to build updates.
  • Docker to setup build environment.

Continuous Delivery

Continuous Delivery is the process of being able to continuously deploy software into production as soon as code is checked in. It doesn’t need to happen automatically but it’s about having the ability to do so if you so choose. This allows code to get into production as fast as possible to end users. It helps to eliminate big bang releases to avoid weekend or off hour deployments and keeps developers happy. Of course there is a lot more to it that I won’t go into in this post but ultimately that’s a trait of devops nirvana. Essentially how do we get code that’s finished into production as fast as possible without impacting end users and minimizing risk?

For this blog that’s exactly what I want. I want to be able to make tweaks, change styling, make a new post instantly without doing a bunch of manual updates or even running scripts. If there is a new commit on the master branch in github I want that deployed to my public facing site, hinds.io ASAP. Here are the tools that I used to help me get there.

Hugo

Hugo is a super fast static site generator written in go. It’s similar to jekyll which is a maturer and larger community but I found hugo faster and easier to use. Making new content is dead simple since it’s just a new markdown file. There is a whole ecosystem of pluggable themes for it and it is pretty simple to make your own as well.

The quick start is straight forward to get something made fairly quickly.
The quick start does a fantastic job setting up a new site so it would be repetitive to repeat it here. But once you’re done you can generate your static files running just hugo and they will be in a new folder called public/.

Firebase

Firebase is a platform for developing mobile and web apps and abstracts away some of the infrastructure for you. You can get a free account and use it to host your static which is what I am doing. Once you have an account and a hosting project created, install the firebase cli tool

npm install -g firebase-tools.

After you have built your static files. All you need to do is run the login & deploy commands.

firebase login

firebase deploy

Viola, go back to Firebase Go To Console > [project-name] > Hosting[Getting Started] and you can see the recent deployment under Deployment History. If you look under Domains you’ll see [project-name]hinds-io.firebaseapp.com and you can visit that domain to see the website. If you want your own domain name you’ll have to buy one. There are many places that you can buy from and use to manage it. I bought mine from Namecheap and am using Cloudflare to control the domain name.

CircleCI

I hope you found building the static files and deploying to firebase easy and straight forward. Now this is where we get something else to do that hard manual work for us. To do that I’m going to utilize CircleCI and use some Docker to help as well. CircleCI is a continuous integration tool that we will use to continuously deploy our website. Similar tools to this are TravisCI and Jenkins plus many others.

We are essentially going to have CircleCI run the commands to build the static files, and deploy to firebase. You can run mostly whatever in the build script to install hugo and the firebase cli. But that takes time so we’re just going to use docker for our deployment environment. Here is the dockerfile with the dependencies.

FROM golang

LABEL maintainer="Jonathan Hinds"

# get repo for nodejs 7
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -

# installing nodejs
RUN apt-get install -y nodejs

# install hugo
RUN go get github.com/kardianos/govendor
RUN govendor get github.com/gohugoio/hugo
RUN go install github.com/gohugoio/hugo

# install firebase cli
RUN npm install -g firebase-tools

we can build that to push it to Dockerhub. CircleCI can use that image for our builds. CircleCI supports using private docker images as well but there are no secrets or proprietary knowledge in the image. The only thing we need to add to the CircleCI config is static file generation and deployment.

version: 2
jobs:
   build:
     docker:
       # use custom image with hugo & firebase-tools pre-installed.
       - image: jhinds/blog-deploy
     steps:
       # checkout git repo and theme submodules
       - checkout
       - run: git submodule sync
       - run: git submodule update --init
       - run:
            name: Build static files
            command: hugo
       - run:
            name: Deploy to firebase
            command: firebase deploy --token $FIREBASE_DEPLOY_TOKEN

This file gets placed in our git repo as .circleci/config.yml. If the project is configured in CircleCI it will find this file and run it. Once it gets picked up you can check the status in CircleCI. Once that is done check your firebase domain and you’ll see the latest deploy show up. And now we have a continuous deployment setup for our blog and all free.

This is just a small blog so it’s a pretty simple example of what it’s like to have continuous deployment. But hopefully you’ll appreciate the simplicity of what the setup enables you to do, which is deploying changes to production with a simple git push.