GitHub Packages hosts a Docker container registry at ghcr.io
. I have experimented with publishing and consuming container images from GitHub Actions.
GithHub Packages experiment
GitHub Packages include container registry running at ghcr.io. To try it out simple ruby cli script was created and packaged into single purpose container image published to ghcr.io.
Ruby cli scirpt - http-monitor
runs series of http get request to a given url measuring response times and calculating average response time.
GitHub repo https://github.com/tsertkov/http-monitor was linked to a http-monitor package on GitHub as described in the documentation to make it possible publishing container image and pulling it from docker repository ghcr.io/tsertkov/http-monitor as a package.
Logging into github packages docker registry at ghcr.io
The GitHub Actions environment must log into the ghcr.io
Docker registry using the secrets.GITHUB_TOKEN
token before pulling and pushing images.
A custom script step can be used to log into the Docker registry:
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
or docker/login-action
action:
- name: Log in to docker registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Publihsing a container image from GitHub Actions
Building and publishing to the GitHub Packages Docker registry, using Actions cache, is very simple with the docker/build-push-action
action.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
...
- name: Image meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push demo container image to registry
uses: docker/build-push-action@v4
with:
cache-from: type=gha
cache-to: type=gha,mode=max
push: true
context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Achieving the same result with a custom script step, which provides full control over the workflow, is also straightforward.
- name: Push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
[ "$VERSION" == "main" ] && VERSION=latest
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
Using a container image from GitHub Actions
The published container image is later used in a separate workflow from GitHub Actions.
steps:
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
- name: Run docker container
run: docker run --rm -t ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME:latest "${{ inputs.url }}" "${{ inputs.time }}" "${{ inputs.sleep_interval }}"
Dotfiles docker image
Following the initial http-monitor experiment, the CI for dotfiles was updated to build and publish docker image with dotfiles demonstration environment.
You can see the package in action and explore dotfiles from within an isolated container without installing anything other then Docker:
docker run --rm -it ghcr.io/tsertkov/dotfiles:master