Building Images¶
Host Image¶
This builds everything from source: Flutter web, workspace image
(podman), then the host image (Docker). Tagged locally with latest
and a version tag derived from git state (release tag, branch name,
or commit). Only the version tag is pushed to GHCR — :latest is
never pushed to the registry. The version is baked into
/home/klangk/version.json and served at GET /api/v1/version.
Custom Image with Plugins¶
To build a host image with plugins, CA certificates, or OIDC hooks baked in, see Customizing a Deployment.
Scanning¶
trivy-host # scan host image
trivy-workspace # scan workspace image
trivy-host --severity CRITICAL # critical only
No-fix CVEs (tracking)¶
Most HIGH/CRITICAL findings in the workspace image have no fixed Debian/Node
package available yet (Trivy status affected / fix_deferred). These can't
be resolved by an upgrade until upstream ships a patched package, so they are
tracked for awareness and re-scanned periodically.
To render a focused report that separates upgradeable findings from the no upstream fix yet set:
trivy-workspace-report # scan + report in one shot
trivy-workspace-report scan.json # render an existing JSON scan
trivy-workspace --severity CRITICAL,HIGH --format json \
| trivy-workspace-report - # pipe a scan into the report
The trivy-workspace-scan
workflow automates this: it builds a fresh workspace image weekly (Mondays
06:00 UTC, or on demand via Run workflow), scans it, and posts the report
plus raw artifacts to the workflow run. It is informational — it never
fails a run — so reviewers check the Actions tab rather than gating CI.
Image Versioning¶
No :latest tags are pushed to the registry. Every image (host,
workspace, workspace base) is pushed only with an explicit version
tag. This prevents confusion when stable branches would otherwise
overwrite :latest with an older version. Consumers always reference
a specific version via KLANGK_REF or build locally.
Locally, build-workspace-image tags klangk-workspace:latest
(used by the backend at runtime with pull policy never) and a
deterministic version tag (YYYY.MM.DD-<commit>). Stale version
tags from previous builds are automatically removed so they don't
accumulate. The local :latest tag is never pushed to GHCR.
Workspace Base Image Pin¶
The workspace Dockerfile pins its base image to a specific version
via a build ARG:
ARG WORKSPACE_BASE_IMAGE=ghcr.io/mcdonc/klangk/klangk-workspace-base:2026.06.10-e973f3c
FROM $WORKSPACE_BASE_IMAGE
This means changes to Dockerfile.base on main don't silently
affect other branches. The flow:
- Someone changes
Dockerfile.baseand pushes to main. - The
image-workspace-base.ymlworkflow builds and pushes the new base image with a versioned tag. - The same workflow automatically opens a PR to update the
ARGdefault insrc/containers/workspace/Dockerfileto the new version. - A maintainer reviews and merges the PR.
Stable/deploy branches keep their original pinned base version and
are unaffected. To override at build time:
--build-arg WORKSPACE_BASE_IMAGE=ghcr.io/.../klangk-workspace-base:some-version.