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. |
||
|---|---|---|
| .. | ||
| komodo.json | ||
| README.md | ||
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.jsonis authored;install.sh,update.shandtest.share 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:vmhas built the Debian 13 VM,templates:debianhas apt-upgraded it and installed the guest agent,network:proxyhas publishedhttps://komodo.<domain>, andidentity:identityhas 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 rootfulpodman.socket(Periphery needs the Docker-compatible API) andpodman-restart.service - Lay down the compose file — Komodo ships
compose/ferretdb.compose.yaml; pin the image tags rather than trackinglatest, 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.envat0600and 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_URIfrom/etc/secrets/komodo.env(put there byidentity:identity) - set
oidc_enabled, the provider URL, client id and secret, and the redirect that matchesoidcRedirectPathsinkomodo.json - disable local password login only after a successful OIDC sign-in has been confirmed, so a misconfiguration cannot lock everyone out
- read
- Bring the stack up —
podman-compose up -d, then wait for:9120to 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.socketactive - Core and database containers running
:9120answers, 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.