Container Image Build¶
This workflow is used to build container images in a standardised way.
Usage¶
Basic usage of this action only requires the image_name input.
test-img-build:
uses: hotosm/gh-workflows/.github/workflows/image_build.yml@1.6.0
with:
image_name: ghcr.io/${{ github.repository }}
This will build an image for the repository.
If multiple images are built in the same repository, it is possible to name the images under separate paths:
ghcr.io/${{ github.repository }}/backend
ghcr.io/${{ github.repository }}/frontend
ghcr.io/${{ github.repository }}/some-other-service
Defaults¶
- Build an image using the root directory, and file
Dockerfile
. - Automatically tag your image, depending on the branch or version number.
- Inject the build-args:
- APP_VERSION=${{ github.ref_name }} (the current branch or tag)
- COMMIT_REF=${{ github.sha }} (the current commit)
- Cache your image in the Github Container Registry for future builds.
- Push your image to the registry for future use.
Vulnerability Scanning¶
Two types of vulnerability scan are available.
Both are enabled by default.
Static Code Analysis of Dockerfile¶
Scanning of Dockerfiles for best practice security is done by checkov.
This can be disabled with the input parameter:
scan_dockerfile: false
.
CVE Scanning of Built Image¶
The built image is scanned for CVEs present in the installed software by Trivy.
This can be disabled with the input parameter:
scan_image: false
.
Multi Architecture Builds¶
There is basic support for building multi-architecture images.
By using the multi_arch: true
option, builds can be made for
AMD64 (default Linux/Windows), and ARM64 (newer MacOS M-chips).
Please note, however, that using multi_arch
may increase your build time
by up to 3x.
If speed is important, there is another workflow availble named image_build_multi that will build across multiple Github runners and should be faster (amd64 | arm/v6 | arm/v7 | arm64).
Note: you should carefully consider if multi-architecture builds are worth the performance tradeoff.
As of 2023, deployment on architectures other than AMD64 is rare. To accomodate MacOS users during app development, it is suggested they build the image themselves on their own architecture (often a single command).
Inputs¶
INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
---|---|---|---|---|
build_target | string | false | The target to built to (default to end of the Dockerfile). |
|
cache | boolean | false | true |
Use GHCR caching. Default true. Set this false if registry is not ghcr.io. |
context | string | false | "." |
Root directory to start the build from. |
dockerfile | string | false | "Dockerfile" |
Name of dockerfile, relative to context dir. |
extra_build_args | string | false | Space separated list of extra build args to use for the image. |
|
image_name | string | false | Name of image, without tags. Not required if image_tags specified. |
|
image_tags | string | false | Default=the images are automatically tagged. Override tags with space separated list. |
|
multi_arch | boolean | false | false |
Build a multi-arch image for AMD64/ARM64. |
push | boolean | false | true |
Override prevent pushing the image. |
registry | string | false | "ghcr.io" |
Override GHCR to use an external reg. |
scan_dockerfile | boolean | false | true |
Enable dockerfile vulnerability scanning, prior to build. |
scan_image | boolean | false | true |
Enable image vulnerability scan, after build. |
skip_cve | string | false | "CKV_DOCKER_8,CKV_DOCKER_2,CKV_DOCKER_3,CKV_DOCKER_5" |
Skip specific CVE from checkcov (override rules). |
Outputs¶
OUTPUT | VALUE | DESCRIPTION |
---|---|---|
image_name | "${{ jobs.build-image.outputs.image_name }}" |
The final full image reference. |
image_tag | "${{ jobs.build-image.outputs.image_tag }}" |
The final image tag. |
Secrets¶
No secrets.
Example Usage¶
Standalone
Multi-arch, cached, auto-tag, auto-push:
backend-build:
uses: hotosm/gh-workflows/.github/workflows/image_build.yml@main
with:
context: src/backend
build_target: prod
image_name: ghcr.io/${{ github.repository }}/backend
extra_build_args: |
APP_VERSION=${{ github.ref_name }}
COMMIT_REF=${{ github.sha }}
Manual tagging:
backend-build:
uses: hotosm/gh-workflows/.github/workflows/image_build.yml
with:
context: src/backend
build_target: prod
image_tags: |
"ghcr.io/hotosm/fmtm/backend:latest"
extra_build_args: |
APP_VERSION=0.1.0
Passing Variables
Example variable extraction from FMTM:
name: Extract Project Variables
on:
workflow_call:
inputs:
environment:
description: "The GitHub environment to extract vars from."
type: string
default: ""
outputs:
api_version:
description: "Backend API Version."
value: ${{ jobs.extract-vars.outputs.api_version }}
jobs:
extract-vars:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
outputs:
api_version: ${{ steps.extract_api_version.outputs.api_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract api version
id: extract_api_version
run: |
cd src/backend
API_VERSION=$(python -c 'from app.__version__ import __version__; print(__version__)')
echo "api_version=${API_VERSION}" >> $GITHUB_OUTPUT
Then example variable passing from FMTM:
jobs:
extract-vars:
needs:
- pytest
- frontend-tests
uses: ./.github/workflows/extract_vars.yml
with:
environment: ${{ github.ref_name }}
backend-build:
uses: hotosm/gh-workflows/.github/workflows/image_build.yml
needs: extract-vars
with:
context: src/backend
build_target: prod
image_tags: |
"ghcr.io/hotosm/fmtm/backend:${{ needs.extract-vars.outputs.api_version }}-${{ github.ref_name }}"
"ghcr.io/hotosm/fmtm/backend:latest"
extra_build_args: |
APP_VERSION=${{ needs.extract-vars.outputs.api_version }}