Docs Blog Apps Pricing

Getting Started

1. Install the CLI 2. Login 3. Build and Push 4. Boot on GCP 5. Boot on Bare Metal

Guides

Authentication Pushing and Pulling Images Configuring Images Working with Hosts Working with GCP Working with Bare Metal latitude.sh OVHcloud Working with AWS Backups Tips and Tricks

CLI Reference

kheeper auth kheeper authorizations kheeper bots kheeper clouds kheeper contexts kheeper hosts kheeper images kheeper orgs kheeper push kheeper releases kheeper status

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.