name: Build and push Docker images
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: user/app:latest
build-push-action
GitHub Action to build and push Docker images with Buildx
What is Build and push Docker images GitHub Action?
Build and push Docker images is a GitHub Action that automates building and pushing Docker images using Buildx, which leverages the robust features of Moby BuildKit. This includes capabilities like multi-platform builds, handling secrets, using remote caches, and more.
Basically, this Action helps streamline the creation of Docker images that are compatible with multiple platforms, which is great for ensuring our applications can run on different hardware setups without any extra manual setup. You don't even need to manually check out the repo if you use the default Git context—it's all handled automatically, which is pretty neat!
How to Push Docker Images to GitHub Container Registry with GitHub Actions
Combining Docker with GitHub Actions provides an efficient way to build and push Docker images directly to the GitHub Container Registry. This process ensures that our images are stored securely and are accessible for deployment. Here’s a concise guide on setting up a GitHub Actions workflow to build and push Docker images:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }} ## GitHub organization or username
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
- Set up Docker Buildx: Configures Docker Buildx for multi-platform builds.
- Log in to GitHub Container Registry: Authenticates with the GitHub Container Registry using the
GITHUB_TOKEN
. - Build and Push Docker Image: Builds the Docker image from the repository and pushes it to the GitHub Container Registry with the latest tag.
How to Build and Push Multi-Platform Docker Images with GitHub Actions
To ensure our Docker images are compatible across various hardware architectures, we need to build multi-platform images. GitHub Actions, combined with Docker Buildx, allows for automated building and pushing of these images. Here’s a quick guide on how to set up a GitHub Actions workflow to build images for both AMD64
and ARM64
architectures.
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: user/app:latest
How to Use Secrets in Docker Builds with GitHub Actions
Secure handling of secrets during Docker builds is critical, especially when sensitive data such as API tokens and credentials are involved. GitHub Actions provides a secure way to pass secrets to Docker builds using the --mount=type=secret
option in Dockerfiles. This method ensures that secrets are not stored in the image layers or logs, enhancing the security of our build processes. Here's a quick guide on how to use GitHub secrets in your Docker builds.
# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=github_token \
cat /run/secrets/github_token
Next, configure your GitHub Actions workflow to pass the GitHub token to the Docker build as a secret. This is done in the workflow YAML file:
- name: Build
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
tags: user/app:latest
secrets: |
github_token=${{ secrets.GITHUB_TOKEN }}
How to Push Docker Images to Multiple Registries with GitHub Actions
Deploying Docker images to multiple registries such as Docker Hub and GitHub Container Registry (GHCR) can enhance redundancy and availability across different platforms. Here's a concise guide on setting up a GitHub Actions workflow to build a Docker image and push it to both Docker Hub and GHCR simultaneously.
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
user/app:latest
user/app:1.0.0
ghcr.io/user/app:latest
ghcr.io/user/app:1.0.0
Effective Docker Cache Management with GitHub Actions
Inline Cache
The inline cache method is straightforward and is recommended for many typical use cases. However, it supports only minimal cache modes.
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:latest
cache-to: type=inline
Registry Cache
For more complex scenarios or when you want to use a maximal cache mode, use the registry cache method, which involves pushing and pulling cache from a registry.
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:buildcache
cache-to: type=registry,ref=user/app:buildcache,mode=max>
GitHub Actions Cache (Experimental)
The GitHub cache method uses the GitHub Cache API to fetch and upload cache blobs. It’s experimental and requires feedback for stability.
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: user/app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Sharing Built Docker Images Between Jobs in GitHub Actions
In GitHub Actions, each job runs in a separate environment, which means Docker images built in one job are not directly accessible in another job. This isolation can pose challenges when your workflow requires using a Docker image across multiple jobs. However, you can overcome this by leveraging the actions/upload-artifact
and actions/download-artifact
actions to share Docker images between jobs. Here’s how you can implement this in your workflow.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and Export Image
uses: docker/build-push-action@v5
with:
context: .
tags: myimage:latest
outputs: type=docker,dest=/tmp/myimage.tar
- name: Upload Built Image as Artifact
uses: actions/upload-artifact@v3
with:
name: myimage
path: /tmp/myimage.tar
use:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download Built Image
uses: actions/download-artifact@v3
with:
name: myimage
path: /tmp
- name: Load Image into Docker
run: |
docker load --input /tmp/myimage.tar
docker image ls -a