build
The build section defines how imglife generates Dockerfiles from templates and pushes base images to your registry.
Structure
Section titled “Structure”build: core_version: "1.0.0" registry: registry.example.com/bases builder: imglife-builder # optional buildx builder name platforms: [linux/amd64, linux/arm64] sbom: true tag_format: "{registry}/{folder}:{mirror-tag}-{build_name}"
hooks: post_image_build: - cmd: cosign sign --yes {image} timeout: 120s
images: - name: alpine folder: images/alpine type: core mirror_image: registry.example.com/mirrors/alpine mirror_tag: "3.21.3" version: "3.21.3"Top-level fields
Section titled “Top-level fields”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
core_version |
string | yes | — | Organisation build version; bumped when your templates/config change |
registry |
string | yes | — | Base path where built images are pushed |
builder |
string | no | — | docker buildx builder instance name; omit to use the default |
platforms |
[]string | no | [linux/amd64] |
Default target platforms |
sbom |
bool | no | false |
Attach SBOM attestation (requires buildx) |
tag_format |
string | no | {registry}/{folder}:{mirror-tag}-{build_name} |
Token template for the full image reference (see Tag format) |
hooks.post_image_build |
[]Hook | no | — | Commands to run after each image is built and pushed |
Image fields
Section titled “Image fields”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | yes | — | Image name (used in logs and the {build_name} token) |
folder |
string | yes | — | Registry sub-path for the built image (the {folder} token), e.g. images/alpine |
type |
string | yes | — | core, spe, or spe-dev (affects EOL checking) |
mirror_image |
string | yes | — | Mirror image used as FROM (must not include a tag) |
mirror_tag |
string | no | latest resolved | Pin a specific mirror tag; omit to auto-resolve the latest |
mirror_tag_regex |
string | no | — | Restricts automatic latest-tag resolution to mirror tags matching this anchored regex (validated at config load). Mutually exclusive with mirror_tag. See Version lines. |
version |
string | conditional | — | Required for spe/spe-dev; forbidden for core (which uses core_version) |
tmpl |
string | conditional | templates/core.tmpl |
Template path; required for spe/spe-dev, forbidden for core |
args |
map[string]string | no | — | Additional --build-arg values |
os_family |
string | no | auto-detected | Overrides OS family detection for templates ({{.OSFamily}}). Known values: alpine, debian, ubuntu, rhel; free-form lowercase values are allowed for custom templates. |
platforms |
[]string | no | inherits top-level | Per-image platform override |
sbom |
bool | no | inherits top-level | Per-image SBOM override |
hooks |
Hooks | no | — | Per-image hooks |
Image types
Section titled “Image types”| Type | Description | EOL checked | Appears in status |
|---|---|---|---|
core |
Production base image | Yes | Yes |
spe |
Special-purpose variant | Yes | Yes |
spe-dev |
Development variant | No | No |
Version lines
Section titled “Version lines”Several build.images blocks may share the same folder (and usually the same mirror_image). Each block is then an independent version line, identified by its mirror_tag or mirror_tag_regex:
images: - name: jdk-core-8 folder: jdk type: core mirror_image: registry.example.com/mirrors/jdk mirror_tag_regex: ^8-jdk-alpine.*$
- name: jdk-core-25 folder: jdk type: core mirror_image: registry.example.com/mirrors/jdk mirror_tag_regex: ^25-jdk-alpine.*$Every command reasons per line, not per repository:
| Command | Per-line behaviour |
|---|---|
build |
Resolves the latest mirror tag within the line only |
status |
One table row per block, each with its own tag, build date, EOL cycle and Markdown link definition ([base-<image-name>]) |
cleanup |
keep_last is applied per line — an older line (JDK 8) is no longer evicted by a newer one (JDK 25) in the same repo |
check |
The suggested latest_tag and the EOL cycle stay within the line of the tag in use |
eol |
Alerts and endoflife.date cycles are resolved from the tag’s line |
The same applies to sync entries sharing a target, where the line is defined by tag / tag_regex.
Dockerfile templates
Section titled “Dockerfile templates”imglife renders Dockerfile.tmpl using Go’s text/template engine. The following variables are available:
| Variable | Example | Description |
|---|---|---|
{{.MirrorImage}} |
registry.example.com/mirrors/alpine:3.21.3 |
Fully-resolved mirror image reference (tag already appended) |
{{.CoreVersion}} |
1.0.0 |
Organisation core version (build.core_version) |
{{.Version}} |
3.21.3 |
core_version for core images, or the image version |
{{.Name}} |
alpine |
Image name |
{{.Type}} |
core |
Image type (core, spe, spe-dev) |
{{.OSFamily}} |
alpine |
OS family of the mirror image (see OS family resolution) |
{{.Args}} |
{KEY: value} |
Map of the image’s args |
Template helper functions
Section titled “Template helper functions”| Function | Example | Description |
|---|---|---|
bool |
{{ if bool (index .Args "FLAG") }} |
Parses an Args value as a boolean (accepts true/True/TRUE, false/False/FALSE, 1/0, t/f, case-insensitively — unlike a raw string comparison against YAML’s literal scalar text). Missing/empty arg → false without error; invalid value → build error. |
int |
{{ if gt (int (index .Args "RETRY_COUNT")) 5 }} |
Parses an Args value as an integer for numeric comparisons (e.g. gt, lt, eq). Missing/empty arg → 0 without error; invalid value → build error. |
float |
{{ if ge (float (index .Args "THRESHOLD")) 1.5 }} |
Parses an Args value as a float64 for numeric comparisons. Missing/empty arg → 0 without error; invalid value → build error. |
OS family resolution
Section titled “OS family resolution”{{.OSFamily}} is resolved through a three-level cascade; the first level that yields a result wins:
os_familyin the config — explicit per-image override, no network call./etc/os-releaseinspection — the mirror image layers are read from the registry and theID/ID_LIKEfields are mapped to a family (e.g. UBI images declareID_LIKE="rhel fedora"→rhel). Covers images whose name carries no OS hint, such aspython:3.13.- Name heuristics — keywords matched in the mirror image reference (
alpine,debianand its codenames,ubuntuand its codenames,ubi/rhel/redhat/centos/rockylinux/almalinux).
Possible values: alpine, debian, ubuntu, rhel, an unmapped os-release ID passed through as-is (e.g. wolfi), or unknown. When the resolution ends at unknown, a warning is logged at build time suggesting to set os_family explicitly:
images: - name: ubi folder: images/ubi type: core mirror_image: registry.example.com/mirrors/ubi9 os_family: rhel # explicit override — skips detectionExample Dockerfile.tmpl:
FROM {{ .MirrorImage }}
RUN apk add --no-cache \ ca-certificates \ tzdata \ curl
# OCI labels are injected automatically by imglifeimglife injects these OCI labels on every build:
org.opencontainers.image.created = <build timestamp>org.opencontainers.image.revision = <git SHA>org.opencontainers.image.source = <project URL>org.opencontainers.image.base.name = <mirror image>org.opencontainers.image.base.digest = <mirror digest>Tag format
Section titled “Tag format”tag_format is rendered with single-brace tokens (not Go templates). The default is {registry}/{folder}:{mirror-tag}-{build_name}, which produces the full destination reference. You can customise it:
build: tag_format: "{registry}/{folder}:{mirror-tag}-org{version}" # Produces: registry.example.com/bases/images/alpine:3.21.3-org1.0.0Available tokens:
| Token | Expands to | Example |
|---|---|---|
{registry} |
build.registry |
registry.example.com/bases |
{folder} |
the image folder |
images/alpine |
{type} |
the image type |
core |
{version} |
core_version for core, otherwise the image version |
1.0.0 |
{build_name} |
{type}{version} |
core1.0.0 |
{mirror-tag} |
the resolved mirror tag | 3.21.3 |
Validation rules: unknown tokens are rejected, {registry} is required, and at least one of {build_name}, {type}, or {version} must be present.
Multi-architecture builds
Section titled “Multi-architecture builds”build: platforms: [linux/amd64, linux/arm64] builder: imglife-builder # buildx builder must support multi-archWhen platforms has more than one entry, imglife uses docker buildx build with --push to publish a multi-arch manifest. A builder with docker-container driver is required.
Output-dir mode
Section titled “Output-dir mode”Instead of building and pushing, imglife can write Docker build contexts to a local directory for consumption by external builders (Kaniko, Buildah):
imglife build --output-dir /tmp/imglife-contextsEach context directory contains a Dockerfile, a build.json manifest, and any required files. See imglife build for the full reference.
build: hooks: post_image_build: - cmd: cosign sign --yes {image} timeout: 120s continue_on_error: falseIn hook commands, the literal placeholder {image} is replaced with the fully-qualified image reference including tag. It is the only substitution available; the command is run via sh -c.
Each hook entry accepts cmd (required), timeout (optional Go duration, e.g. 120s), and continue_on_error (optional bool).