Kheeper

Build and Push a Configurable Image

A configurable image is a bootable container image with template files that are rendered per-host at deploy time. This lets you build one image and configure it differently for each machine.

Create the image

We'll build a simple Caddy web server image as an example. Create a directory with these files:

Containerfile

FROM quay.io/fedora/fedora-bootc:44

RUN dnf -y install caddy && dnf clean all
RUN systemctl enable caddy

# Caddy stores ACME certs under its data dir, but the caddy RPM ships no
# tmpfiles.d rule for it. On a bootc host /var is reconstructed from
# tmpfiles.d on each boot, so without this rule /var/lib/caddy never exists
# and Caddy fails TLS with "mkdir /var/lib/caddy: permission denied".
RUN printf 'd /var/lib/caddy 0750 caddy caddy - -\n' > /usr/lib/tmpfiles.d/caddy.conf

COPY Caddyfile.khtmpl /etc/caddy/Caddyfile.khtmpl
COPY schema.json /etc/kheeper/schema.json

RUN bootc container lint

Caddyfile.khtmpl — a Go template that will be rendered to /etc/caddy/Caddyfile when this image is configured.

{{ .domain }} {
    respond "Hello, {{ .name }}"
}

schema.json (Optional) — validates configuration values for this image.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "domain": {
      "type": "string"
    },
    "name": {
      "type": "string"
    }
  },
  "required": ["domain", "name"],
  "additionalProperties": false
}

Build

First set the ORG var to your user organization.

ORG=$(kheeper orgs list | grep 'user-[0-9a-f]' | awk '{ print $1 }')

The kheeper.configurable=1 annotation tells the registry to extract the templates and schema when the image is pushed.

podman build --annotation kheeper.configurable=1 --arch amd64 -t us.kheeper.com/${ORG}/getting-started:v1 -f Containerfile .

Push

kheeper push us.kheeper.com/${ORG}/getting-started:v1

Verify

kheeper images get ${ORG}/getting-started:v1

The output will include a ConfigImage field, confirming the registry recognized the image as configurable.