GitHub Actions - Build and Push a Docker Image
Github Actions are here, and they are really great to work with. Let's take a look at how you would use a GitHub action to build and push a Docker image to your GitHub container registry.
First, here's the YAML file we will consider. It lives in a repository at .github/workflows/dockerpublish.yml
name: Docker
on:
push:
branches:
- master
env:
IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/ghost
jobs:
push:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v2
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME:${{ github.run_number }}
- name: Log into registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin
- name: Push images
run: |
docker tag $IMAGE_NAME:${{ github.run_number }} $IMAGE_NAME:latest
docker push $IMAGE_NAME:${{ github.run_number }}
docker push $IMAGE_NAME:latest
Let's break that down into smaller chunks to observe what is happening.
First, we name this workflow (pipeline) "Docker". That translates to what you see here:
Note that you could have many workflows in your repository. They will show up in a list in that same location.
Next, we tell GitHub Actions that we only want to trigger this workflow when there is a push to the branch named master using these lines:
on:
push:
branches:
- master
This one is pretty simple. We simply set an environment variable IMAGE_NAME
with a value. In this case, ${{ github.repository }}
will be replaced with the name of the repository. For consistency, here are the two lines used to do that:
env:
IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/ghost
You can specify as many environment variables as you need in this section.
Now we can start defining our jobs like this:
jobs:
push:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
Don't be confused here -- this instance of push
on the second line is simply the name I gave the job. Then we set the job to run on ubuntu and state that we only want to run the job if the event trigger was a git push
. Lastly, we put in the steps block. Now let's take a look at the steps that occur.
- uses: actions/checkout@v2
This is a reusable unit of code that has been written by the community (by GitHub in this case). It simply checks out my code. (More information)
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME:${{ github.run_number }}
This is how you define a bash script that you want to run. You give the step a name and define the command you want to run.
- name: Log into registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin
This step is how you would go about logging into your personal github package registry so that you can push or pull image containers. Note that I have created a secret in this repository called GITHUB_TOKEN
which contains a personal access token that I generated via GitHub. You will need to do the same if you plan to use the GitHub package registry.
The final step is an example of a multi-line script. Using the |
character (standard for YAML), says "continue reading until you reach the next line at this indent level"... or something like that anyway.
- name: Push images
run: |
docker tag $IMAGE_NAME:${{ github.run_number }} $IMAGE_NAME:latest
docker push $IMAGE_NAME:${{ github.run_number }}
docker push $IMAGE_NAME:latest
That's the gist of GitHub Actions wrapped up into a relatively simple pipeline. The pipelines are relatively simple to write and have a lot of extremely powerful capabilities that continue to grow in relation to other CI/CD tools.
Here are some useful links to go with this content:
- (The repo)[https://github.com/justin-vanwinkle/ghost-website]
- (GitHub Actions Homepage)[https://github.com/features/actions]
- (GitHub Actions Documentation)[https://docs.github.com/en/free-pro-team@latest/actions]