Skip to content

Commit 15d4ac4

Browse files
authored
Merge pull request #912 from Icinga/containerfile
Create and publish container images from this repository
2 parents 6cbab3f + 8ea9d01 commit 15d4ac4

File tree

3 files changed

+161
-33
lines changed

3 files changed

+161
-33
lines changed

.github/workflows/container-image.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# The Build and Publish Container Image workflow builds container images and
2+
# pushes them to both GitHub Container Registry (GHCR) and Docker Hub.
3+
# It sets up QEMU and Docker Buildx for cross-platform builds,
4+
# and builds the container images using the Containerfile.
5+
# Upon pushes to the main branch or when releases are published,
6+
# it logs into GHCR and Docker Hub using credentials from GitHub secrets,
7+
# tags and pushes the images to both registries,
8+
# and generates and pushes signed build provenance attestations to each registry.
9+
# The workflow also triggers for pull requests to the main branch, verifying only the image build.
10+
11+
name: Build and Publish Container Image
12+
13+
on:
14+
push:
15+
branches:
16+
- main
17+
pull_request:
18+
branches:
19+
- main
20+
release:
21+
types:
22+
- published
23+
24+
env:
25+
# The variable ${{ github.repository }} is not suitable for container image names in our case because
26+
# they must be lowercase, and our organization name is Icinga.
27+
# Since our repository names are already lowercase, no additional modifications are necessary.
28+
IMAGE_NAME: icinga/${{ github.event.repository.name }}
29+
30+
jobs:
31+
build-and-publish-container-image:
32+
runs-on: ubuntu-latest
33+
34+
permissions:
35+
contents: read
36+
packages: write
37+
attestations: write
38+
id-token: write
39+
40+
steps:
41+
- name: Extract metadata (tags, labels)
42+
id: meta
43+
uses: docker/metadata-action@v5
44+
with:
45+
# This will generate tags and labels for both the GHCR image and Docker Hub image.
46+
images: |
47+
# GitHub Container Registry
48+
ghcr.io/${{ env.IMAGE_NAME }}
49+
# Docker Hub
50+
${{ env.IMAGE_NAME }}
51+
labels: |
52+
org.opencontainers.image.documentation=https://icinga.com/docs/icinga-db
53+
org.opencontainers.image.vendor=Icinga GmbH
54+
tags: |
55+
type=edge
56+
type=semver,pattern={{version}}
57+
type=semver,pattern={{major}}.{{minor}}
58+
type=semver,pattern={{major}}
59+
# Update the `latest` tag only on the default branch to ensure it represents the most current release when
60+
# releasing from multiple branches.
61+
type=raw,value=latest,enable={{is_default_branch}}
62+
63+
- name: Set up QEMU
64+
uses: docker/setup-qemu-action@v3
65+
66+
- name: Set up Docker Buildx
67+
uses: docker/setup-buildx-action@v3
68+
69+
- name: Log in to GitHub Container Registry
70+
if: github.event_name != 'pull_request'
71+
uses: docker/login-action@v3
72+
with:
73+
registry: ghcr.io
74+
username: ${{ github.actor }}
75+
password: ${{ secrets.GITHUB_TOKEN }}
76+
77+
- name: Login to Docker Hub
78+
if: github.event_name != 'pull_request'
79+
uses: docker/login-action@v3
80+
with:
81+
username: ${{ secrets.DOCKERHUB_USERNAME }}
82+
password: ${{ secrets.DOCKERHUB_TOKEN }}
83+
84+
- name: Build and push Container image
85+
id: build-and-push
86+
uses: docker/build-push-action@v6
87+
with:
88+
file: ./Containerfile
89+
labels: ${{ steps.meta.outputs.labels }}
90+
platforms: linux/amd64,linux/arm64
91+
push: ${{ github.event_name != 'pull_request' }}
92+
# The tags generated in the metadata step include tags for both Docker Hub and GHCR image names,
93+
# allowing the build and push action to build and push images to both registries.
94+
tags: ${{ steps.meta.outputs.tags }}
95+
# Keep the .git to allow including the commit in the --version output, see also:
96+
# https://docs.docker.com/build/building/context/#keep-git-directory
97+
build-args: |
98+
BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
99+
100+
- name: Generate artifact attestation for GitHub Container Registry
101+
if: github.event_name != 'pull_request'
102+
uses: actions/attest-build-provenance@v2
103+
with:
104+
subject-name: ghcr.io/${{ env.IMAGE_NAME }}
105+
subject-digest: ${{ steps.build-and-push.outputs.digest }}
106+
push-to-registry: true
107+
108+
- name: Generate artifact attestation for Docker Hub
109+
if: github.event_name != 'pull_request'
110+
uses: actions/attest-build-provenance@v2
111+
with:
112+
# According to the documentation [^1],
113+
# "index.docker.io" should be used as the registry portion of the image name when pushing to Docker Hub.
114+
#
115+
# [^1]: https://github.com/actions/attest-build-provenance?tab=readme-ov-file#container-image
116+
subject-name: index.docker.io/${{ env.IMAGE_NAME }}
117+
subject-digest: ${{ steps.build-and-push.outputs.digest }}
118+
push-to-registry: true

.github/workflows/docker.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

Containerfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
FROM golang:1 AS base
2+
3+
# Cache dependencies:
4+
# The go mod download command uses a cache mount,
5+
# ensuring Go modules are cached separately from the build context and not included in image layers.
6+
# This cache is used in the build stage and reused across builds, unless go.mod or go.sum changes.
7+
WORKDIR /build
8+
COPY go.mod go.sum ./
9+
RUN --mount=type=cache,target=/go/pkg/mod \
10+
go mod download
11+
12+
FROM base AS build
13+
14+
# Mount source code and build:
15+
# The --mount=target=. option mounts the source code without adding an extra image layer, unlike `COPY . .`.
16+
# The go build command uses the dependency cache and a dedicated mount to cache build artifacts for future builds.
17+
RUN --mount=target=. \
18+
--mount=type=cache,target=/go/pkg/mod \
19+
--mount=type=cache,target=/root/.cache/go-build \
20+
CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o /icingadb ./cmd/icingadb
21+
22+
FROM scratch
23+
24+
COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
25+
26+
COPY --from=build /icingadb /icingadb
27+
28+
COPY ./schema/mysql/schema.sql /schema/mysql/schema.sql
29+
COPY ./schema/pgsql/schema.sql /schema/pgsql/schema.sql
30+
31+
# addgroup -g 1001 icinga
32+
COPY <<EOF /etc/group
33+
icinga:x:1001:
34+
EOF
35+
36+
# adduser -u 1001 --no-create-home -h /var/empty -s /sbin/nologin --disabled-password -G icinga icinga
37+
COPY <<EOF /etc/passwd
38+
icinga:x:1001:1001::/var/empty:/sbin/nologin
39+
EOF
40+
41+
USER icinga
42+
43+
CMD ["/icingadb", "--database-auto-import"]

0 commit comments

Comments
 (0)