// SPDX-License-Identifier: CC-BY-SA-4.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
= k9-validate-action Container Templates
:toc: left
:toclevels: 3
:sectnums:

== Overview

This directory contains container templates for the
https://github.com/hyperpolymath/stapeln[stapeln] container ecosystem.
The stapeln stack provides verified container packaging, edge gateway
policies, runtime monitoring, and supply-chain signing for Podman-based
deployments using https://www.chainguard.dev/[Chainguard] Wolfi base images.

All files use `{{PLACEHOLDER}}` tokens that are replaced by `just container-init`
(or by the top-level `just init` during project bootstrap).

== File Reference

[cols="1,3"]
|===
| File | Purpose

| `compose.toml`
| **selur-compose** stack definition. Declares services, volumes, networks,
  and health checks. The primary orchestration file for local and production
  deployment. Use `selur-compose up` or fall back to `podman compose`.

| `compose.example.toml`
| Concrete multi-service example with detailed comments. Copy and customise
  for your own stack. Not used directly by any tooling.

| `Containerfile`
| Multi-stage OCI container build specification. Stage 1 builds the
  application; Stage 2 produces a minimal runtime image on
  `cgr.dev/chainguard/wolfi-base`. Uses Podman (never Docker).

| `manifest.toml`
| **cerro-torre** bundle metadata. Describes the `.ctp` verified container
  package: provenance, dependencies, attestations, and runtime security
  profile. Used by `ct pack` and `ct verify`.

| `.gatekeeper.yaml`
| **svalinn** edge gateway policy. Controls authentication, rate limiting,
  container trust, request validation, CORS, and audit logging at the
  network boundary.

| `ct-build.sh`
| Build, sign, and verify pipeline script. Five stages: build (Podman),
  pack (cerro-torre `.ctp`), sign (Ed25519), verify, and push (optional).
  Gracefully degrades when cerro-torre tools are not installed.

| `entrypoint.sh`
| Container entrypoint with signal handling (SIGTERM, SIGINT), startup
  logging, and `exec` into the main application process.

| `vordr.toml`
| **vordr** runtime monitoring configuration. Defines health endpoints,
  crash detection, resource thresholds, and log output.

| `deploy.k9.ncl`
| **k9-svc** deployment component at Hunt trust level. Full pedigree
  (L1--L5), environment configs (dev/staging/prod), container
  configuration, and rolling deployment strategy.

| `0-AI-MANIFEST.a2ml`
| AI-readable manifest describing the container directory, file
  interconnections, and the stapeln ecosystem.
|===

== The stapeln Ecosystem

The stapeln container ecosystem comprises six interconnected tools:

**selur** (compose)::
  Container orchestration with zero-copy IPC for co-located services.
  Reads `compose.toml` files. Falls back to standard Podman Compose
  when the selur driver is unavailable.

**cerro-torre** (bundles and signing)::
  Verified container packaging. Produces `.ctp` bundles from OCI images,
  signs them with Ed25519, and verifies the full chain. Tools: `ct pack`,
  `ct sign`, `ct verify`, `ct push`, `ct explain`.

**svalinn** (edge gateway)::
  Policy-driven reverse proxy. Enforces authentication, rate limiting,
  CORS, and container trust policies defined in `.gatekeeper.yaml`.

**vordr** (monitoring)::
  Runtime container monitoring. Watches health endpoints, detects crashes,
  tracks resource usage, and emits structured logs.

**rokur** (secrets)::
  Secrets management for container deployments. Injects secrets at runtime
  without baking them into images. Currently a stub/placeholder.

**k9-svc** (deployment components)::
  Nickel-based deployment specification. Components declare their pedigree
  (identity, target, security, validation, recipes) and execute at one of
  three trust levels: Kennel (data only), Yard (evaluation), Hunt (full
  execution with cryptographic handshake).

== How to Initialise

[source,bash]
----
# Option 1: During project bootstrap (includes all placeholders)
just init

# Option 2: Container-specific initialisation
just container-init
----

The `container-init` recipe prompts for container-specific values
(service name, port, registry) and substitutes all `{{PLACEHOLDER}}`
tokens in the `container/` directory.

== Development Workflow

[source,bash]
----
# 1. Build the container image
just container-build

# 2. Verify the compose configuration
just container-verify

# 3. Start the stack locally
just container-up --detach

# 4. Check logs
podman compose --file container/compose.toml logs -f

# 5. Stop the stack
just container-down
----

== Production Deployment

[source,bash]
----
# 1. Build, sign, and verify the .ctp bundle
just container-sign

# 2. Push the signed bundle to the registry
just container-push

# 3. Deploy on the target host
selur-compose up --detach
----

For k9-svc managed deployments:

[source,bash]
----
# Validate the deployment component
nickel typecheck container/deploy.k9.ncl

# Deploy (requires Hunt-level authorisation)
k9-svc deploy container/deploy.k9.ncl --env production
----

== Base Images

All Containerfiles use Chainguard Wolfi base images:

* **Builder stage:** `cgr.dev/chainguard/wolfi-base:latest`
* **Runtime stage:** `cgr.dev/chainguard/wolfi-base:latest` (or
  `cgr.dev/chainguard/static:latest` for statically-linked binaries)

Chainguard images are minimal, CVE-free, and rebuilt daily. They use the
`apk` package manager (Alpine-compatible).

== Container Runtime

This project uses **Podman** (never Docker). All scripts, compose files,
and documentation reference Podman commands. The OCI Containerfile format
is compatible with Podman, Docker, and nerdctl.
