Skip to main content
← Back to workflows

How to Build and push Docker images with GitHub Action?

docker/build-push-action -
GitHub Action
v5.3.0
4,309
Contributors
Contributor - crazy-maxContributor - zappy-shu
Categories
CICUBE ANALYTICS INSIGHTS
Engineering Velocity: 25% Team Time Lost to CI Issues
View Platform →
3.5h
Time Saved/Dev/Week
40%
Faster Releases
Click for next insight
Usage
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 logo

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