Rootless Podman image used as the MaksIT CI builder sandbox (cr.maks-it.com/library/podman:latest).
Base image: Rocky Linux 9 — RHEL-aligned, long support lifecycle, and the same Podman stack used on enterprise Linux hosts (better fit for maksit-cicd than a fast-moving Fedora release).
It runs RepoUtils release pipelines inside ContainerBuilder: image build/push (nested Podman), OCI chart publish, and HelmSelfDeploy to the target Kubernetes cluster.
| Tool | Purpose |
|---|---|
| Podman | Nested image build/push inside the sandbox |
| PowerShell 7 | RepoUtils Invoke-ReleasePackage.ps1 |
GitHub CLI (gh) |
RepoUtils GitHub plugin (create/update releases) |
| Helm 3 | OCI chart pull, helm upgrade --install, registry login |
| kubectl | Namespaces, secrets, waits, BGP manifests |
| oras | OCI artifact operations used by RepoUtils |
| cosign | OCI image signing used by RepoUtils ImagePush when images[].sign is true |
| git | In-sandbox clone/checkout and plugin fetch helpers |
| ca-certificates | TLS for HTTPS git clone and registry calls |
| openssh-clients | SSH remotes when clone URLs use git@ / ssh:// |
XDG_RUNTIME_DIR=/home/podmanuser/run is set so nested rootless Podman can run inside ContainerBuilder sandboxes (/run is tmpfs and empty at container start).
Nested rootful Podman (ContainerBuilder sandboxes run privileged as root) also needs a cgroup v2 leaf: the sandbox PID must not sit in the cgroup root, or nested podman start fails with missing pids controller under /libpod_parent. ContainerBuilder’s exec preamble reparents processes into /sys/fs/cgroup/init before nested Podman runs.
Helm and kubectl are on PATH for user podmanuser (UID 1000). Cluster access is not baked into the image — ContainerBuilder materializes a kubeconfig into the workspace and sets KUBECONFIG when HelmSelfDeploy is enabled.
- Builder sandbox (ContainerBuilder) — command overridden to
sleep infinity; ContainerBuilder execs git clone into/home/podmanuser/workspace(token via env var name), then runs RepoUtils aspodmanuser. - Podman API sidecar (local Compose) — command overridden to
podman system service tcp://0.0.0.0:8080; ContainerBuilder connects viaCONTAINER_HOST. - Standalone pod — default
CMDservesGET /healthzon port 8080 for Kubernetes probes.
Set registry credentials as environment variable ContainerRegistry (base64 username:password).
# from repo root
$env:ContainerRegistry = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("user:pass"))
utils\Invoke-ReleasePackage-Single.batRelease flow uses maksit-repoutils: bump repo-root VERSION, update CHANGELOG.md, tag vX.Y.Z, then run the release engine. Image: cr.maks-it.com/library/podman:<version> and :latest.
See CONTRIBUTING.md for details. Sync engines with utils\Update-RepoUtils.bat.
On the cluster side (not this image):
- ContainerBuilder must pass kubeconfig into the sandbox (
Configuration:ContainerBuild:ClusterAccessModein maksit-cicd). - The identity in that kubeconfig needs RBAC to run
helm upgrade --installand apply manifests in target namespaces.
Inside the sandbox, RepoUtils expects:
helmandkubectlon PATH (provided by this image)- Vault-backed env vars for registry credentials (
ContainerRegistry, etc.) KUBECONFIGpointing at.maksit/kube/configin the workspace (set by ContainerBuilder)
VERSION— semver for releases (read by RepoUtilsFileReleaseVersion)src/Dockerfile— image definitionsrc/storage.conf— rootless Podman storage driversrc/healthz.py— default HTTP health serverutils/— RepoUtils engines and plugins (from maksit-repoutils)
MIT — see LICENSE.md.