makerfloss/src/containers/komodo
Lars Rossen bca395d7f9 Add portainer and komodo as parallel container-management modules
portainer: Portainer CE on rootful podman (Portainer drives the
Docker-compatible API, and rootless is not supported upstream), published via
network:proxy with proxyAllowedZones left unset so members reach it from a
client zone but the internet does not. Login is OIDC: identity:identity writes
the client credentials, update.sh resolves the endpoints from the discovery
document and PUTs them into /api/settings. A break-glass local admin stays for
when Authentik is down. Multi-host is the agent on :9001 per host.

komodo: scaffold only — komodo.json plus a README that specifies what
install.sh and update.sh must do. GPL, no edition split, but it needs a
database and models builds and stacks, so it is the alternative rather than
the teaching example.

Neither has been run on a live TAPPaaS yet; both are catalogued as incomplete.
2026-08-23 09:45:01 +02:00
..
komodo.json Add portainer and komodo as parallel container-management modules 2026-08-23 09:45:01 +02:00
README.md Add portainer and komodo as parallel container-management modules 2026-08-23 09:45:01 +02:00

Komodo — build and deployment system across the lab hosts

Primary audience: TAPPaaS operator comparing container managers.

Komodo is a GPL-3.0 build-and-deploy system for containers: a central Core (web UI, API, database) plus a stateless Periphery agent on every managed host. It does what portainer does — create, start, stop, inspect containers across several machines — and adds git-driven builds, stacks and procedures. Its documentation is pointed about the licensing difference: no node limit, no API limit, no business edition.

Status: scaffold. komodo.json is authored; install.sh, update.sh and test.sh are not written yet — this file specifies what they must do. The module is here so the two candidates can be compared honestly, not because it is ready to install.

Why it is a parallel module and not the one in the deck

Komodo wins on licensing and loses on size. It needs a database (MongoDB, or FerretDB as the FOSS-native stand-in) alongside Core, and it models builds, stacks, repos and procedures — a lot of surface to walk a room through in one evening. portainer is one container against a socket, which is why the teaching session uses that. If the CE/BE split ever bites — most likely over group-to-team mapping — this is the way out.

Shape

Piece Where Port
Komodo Core (UI + API) this VM, container 9120
Database (FerretDB or Mongo) this VM, container internal only
Periphery agent every managed host 8120

Komodo's own docs warn that Periphery must be restricted to the Core's address rather than accepting connections from anywhere — that is a firewall rule, not a default.

install.sh — what it must do

  • Thin wrapper, exactly as in podman and portainer: exec update.sh "$@"
  • Nothing is install-only for this module — every step below is idempotent and belongs in the update path
  • By the time it runs: cluster:vm has built the Debian 13 VM, templates:debian has apt-upgraded it and installed the guest agent, network:proxy has published https://komodo.<domain>, and identity:identity has created the OIDC application and written /etc/secrets/komodo.env

update.sh — what it must do

  • Locate the VM — find the hosting node via pvesh (HA-safe), resolve the IP through the Proxmox guest agent, wait for SSH; identical to the other two modules
  • Install the engine — podman, podman-compose, curl, jq; enable the rootful podman.socket (Periphery needs the Docker-compatible API) and podman-restart.service
  • Lay down the compose file — Komodo ships compose/ferretdb.compose.yaml; pin the image tags rather than tracking latest, and keep FerretDB over MongoDB so the stack stays FOSS-licensed end to end
  • Generate the secrets once — KOMODO_PASSKEY (shared with every Periphery agent) and the database credentials, written to /etc/secrets/komodo-core.env at 0600 and never regenerated on a later run
  • Write /config/config.toml — the Core config the container mounts; this is where OIDC lives:
    • read OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_DISCOVERY_URI from /etc/secrets/komodo.env (put there by identity:identity)
    • set oidc_enabled, the provider URL, client id and secret, and the redirect that matches oidcRedirectPaths in komodo.json
    • disable local password login only after a successful OIDC sign-in has been confirmed, so a misconfiguration cannot lock everyone out
  • Bring the stack up — podman-compose up -d, then wait for :9120 to answer
  • Install Periphery locally — the Core VM manages itself as the first server, agent bound to 127.0.0.1:8120
  • Be idempotent — recreate containers only when a pinned image digest actually changed; never rewrite an existing passkey or database credential; re-running must be a no-op on an unchanged system
  • Print next steps — the URL, where the passkey lives, and the one-liner for adding a Periphery agent on another lab host

test.sh — what it must do

  • VM reachable via the guest agent
  • rootful podman.socket active
  • Core and database containers running
  • :9120 answers, and the API reports a version
  • OIDC is the configured login method, not local passwords

Dependencies

Same as portainer: cluster:vm, templates:debian, backup:vm, network:proxy, identity:identity.

Sizing

2 vCPU / 4 GB RAM / 40 GB disk — more than Portainer, because of the database and because Komodo builds images as well as running them.