To use a Docker container you need to prefix your step with docker://
and then specify the image name. This works for Docker Hub images out of the box. Here is an example to build a Jekyll static website using the official Jekyll Docker Image in Github actions:
name: Deploy Website
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [main]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Builds the website inside docker container
- name: Build website
uses: docker://jekyll/jekyll
with:
args: jekyll build
env:
JEKYLL_ENV: production
JEKYLL_ROOTLESS: true
As you can see, all we needed to do was tell GitHub actions that our second step uses the docker://jekyll/jekyll
container image. The arguments are passed to the Docker image which may be different for various containers. In this case, we want to build the website with the production
environment variable set.
I really like this because it avoids clumsily installing all the dependencies in the blank Ubuntu image (ubuntu-latest
) that the job starts with. There are other benefits too:
- It is consistent across build environments. You can build using the same image on your local machine and in Github actions without worrying about what the build step will do. It does exactly what the container should do.
- You avoid installing stuff. The container is ready-to-go, plug-and-play style approach. If you use official images like we did with Jekyll, you can be certain that it comes with everything it needs.
- Finally, it is easy to share. Most of these advantages are common to containers in general. You can share your build process and anyone can replicate it so long as they use the same container image.
For more complex pipelines, you can use a custom image with all the dependencies and tools you need. You will have to maintain that image but at least you get the same benefits.