Building Docker images in GitHub Actions to be used by other workflows

CJ Hewett
3 min readFeb 21, 2023

In this post, I’ll go over how to use a GitHub Action to build and push a runner image to GitHub Packages, and then use said runner image as the base for another action. These two actions will be part of the same GitHub repository.

All code referenced is also in this repository can be found here:

In this example, I have some Terraform in the branch that I want to be able to run plans on within a GitHub action. The GitHub ubuntu-latest runner does not have Terraform installed, which means we could either install it in the pipeline. However, it could be more efficient to use an image that has Terraform, and any other tools we need, pre-installed.

We could define this image with a Dockerfile in our repo, and have an action that builds this image and pushes it to GitHub packages only when there are changes to that Dockerfile. (As we don’t need to build a new image every time there are changes to the whole repository).

tooling.yaml — Workflow to create the tooling image

This is a pretty simple action that will only run on commits that have changed to the Dockerfile in the tooling directory. It will build a Docker image and push it to GitHub packages in the same repo. The image will have the name of the repo, and be tagged with the branch name. The name of this repo is collective and all this code is in the terraform branch, so the image name with be ghcr.io/cjh-cloud/collective:terraform.

We don’t need to set up a secret for GITHUB_TOKEN (line 28) in the repository as GitHub automates the authorisation for us during the workflow run.

We can see within GitHub that we now have a package 📦 as part of the repo:

The Docker image in GitHub packages.

infra.yaml — Workflow to use the tooling image to run Terraform

The terraform job uses the container parameter to set the Docker image to run the job on, in this case the image we created with the previous Action. We can then checkout the repo and run Terraform commands in the pipeline, since the image that was built has Terraform installed.

It’s possible to create any kind of image with the tools you need installed, thereby saving time for the workflow that uses this image by eliminating the need to install these tools each time it runs.

If this helped you in any way, please consider giving me a follow. I’m trying to get to 100 followers, so it would mean a lot!

Cheers 🤙

--

--

CJ Hewett

🛹 Skateboarder. 🏂 Snowboarder. 🏄 Websurfer. I write monthly* about Cloud/DevOps/IoT. AWS Certified DevOps Engineer and Terraform Associate