Publishing My First Docker Image

So as I was working on upgrading one of my projects to use Headless Chrome with Karma, I found myself updating my Docker based CircleCI builds (config.yml) to install additional host packages needed to get Puppeteer to run. That in and of itself wasn’t an issue and was fairly easy to implement based on an example I found here. However, this meant each of my CircleCI builds were going to be installing these packages on every build, which is a waste of time and resources. It also meant and I would need to copy / paste this configuration into my other projects.

Having had some recent experience with Docker at my job which involved Dockerizing a local development environment to facilitate WordPress development and wanting to stay DRY, I knew what I needed to do…

To the Hub!

Yup! I decided why not make my own Docker image that already has this “baked in”, if you were, and be customized to my specific needs, like using a particular version of NodeJS? I could then publish it to Docker Hub and use it in any project I wanted as the base image. Leaving aside the fact that there are already images available that would have all this for me, I figured it would be a great learning opportunity while reducing the build time of my project.

So…… let’s do this!

1. Creating My Image

My first step was to create a GitHub repo for the project. I then identified what “features” I wanted and captured these as tasks in a milestone in the repo, and settled on these to start:

So in the end, this is what the Dockerfile to make the image looked like:

One thing I thought that was worth doing was to use CircleCI on my own project to build an image right from the project’s Dockerfile for each PR submitted. Continuous Integration ftw!

2. Publishing My Image

So now that I had a buildable Dockerfile, it was time to publish it! I made an account at Docker Hub and followed this guide. You can see my image published here!

A full set of steps for publishing an image are included in the repo to document for my own reference, and for anyone else who may find them helpful.

3. Using My Image

So now that I had built and published my image, it was time to use it! As I alluded to in the beginning of this article, I am in the process of using Docker in CircleCI to build my projects in The Greenhouse. Below is an example of a config.yml file I was using before:

And this is an example of what it looks like now!

We can look to the build output in CircleCi to confirm that our image is being used.

Parting Thoughts

Overall the process was pretty smooth but I did run into a couple issues when using my image.

  1. Missing Base Packages

PhantomJS was failing to install and it turned out I was missing the bzip2 package in my Docker image, which was easy enough to add to the Dockerfile. I also took this time to add additional helpful developer tools like curl, ssh, git, and vim.

This prompted me to document a more robust developer workflow that provides steps for cloning a real project and running real commands against it. I opened an issue to make this part of the Docker image’s continuous integration process too. (Feel free to submit a PR!)

2. Karma / Headless Chrome

I had to implement some additional configurations in my project for running Headless Chrome with Karma, mostly to allow additional time for the tests to run within the container.

So that was my journey making my own Docker image for NodeJS ad Continuous Integration. I would like to extend this to suit local development as well.

Let me know your thoughts and feel free to check out the repository and open an issue or PR!