makerfloss/src/containers/podman
Lars Rossen 04b4437c95 Merge portainer into podman: engine plus GUI in one module
Podman is the container foundation, Portainer CE is the web interface onto it,
running as a container on the very engine it manages. This is what the separate
portainer module already did, so it is retired rather than duplicated.

Two sockets on purpose: the rootful one is the Docker-compatible API Portainer
drives (it does not support rootless), the rootless user socket is for people
who ssh in and run containers by hand — which was the original podman module's
point and is worth keeping.

An explicit proxyDomain lets the module publish at the environment's own domain
instead of <module>.<environment-domain>, making it that environment's gateway.

DESIGN.md keeps the Cockpit identity analysis: it is the reason for the change,
and anyone proposing 'just put Cockpit behind forward-auth' should read it.
2026-08-25 09:30:11 +02:00
..
DESIGN.md Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
INSTALL.md Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
install.sh Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
podman.json Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
README.md Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
test.sh Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00
update.sh Merge portainer into podman: engine plus GUI in one module 2026-08-25 09:30:11 +02:00

Podman — container host with a Portainer console

Primary audience: TAPPaaS operator who wants a place to run OCI containers, and several people managing them.

A Debian 13 (trixie) VM running Podman as the container engine, with Portainer CE as its web interface. Portainer runs as a container on the very engine it manages: Podman is the foundation, Portainer is the GUI.

People sign in with their TAPPaaS identity over OIDC — no per-VM Linux accounts to hand out. From the console they create, start, stop, exec into and inspect containers, pull images and deploy compose stacks — on this VM, and on any other host in the zone running a Portainer agent.

Two engines, on purpose

Socket Who uses it Why
rootful /run/podman/podman.sock Portainer It drives the Docker-compatible API; Portainer does not support rootless
rootless user socket (tappaas) people who ssh in The safer way to run day-to-day containers by hand

Portainer's access to the rootful socket is root-equivalent on this VM. That is inherent to every container manager with socket access — treat the VM as a lab host and put nothing precious on it.

Why Portainer and not Cockpit

The first version of this module shipped Cockpit with cockpit-podman. It cannot meet either requirement: Cockpit is not an OIDC client and cannot be configured into one, it always needs a local Unix account (cockpit-bridge runs in a PAM session as the user), and its multi-host switcher is deprecated and disabled by default — the project states it "cannot be secure". The full analysis, including the two options that were rejected, is in DESIGN.md.

komodo is the GPL alternative that was weighed against Portainer.

Gateway role

Given an explicit proxyDomain, this module publishes at a name of your choosing rather than the usual <module>.<environment-domain>. Pointing it at the environment's own domain makes it that environment's front door:

module-manager module add podman --environment lab1 --proxyDomain lab1.makerfloss.eu

…and the console answers at https://lab1.makerfloss.eu with no extra DNS label.

Identity, and what CE cannot do

identity:identity creates the OIDC application in Authentik, binds it to the allowed groups — that binding is the access gate, since Authentik fails open without one — and writes OIDC_CLIENT_ID, OIDC_CLIENT_SECRET and OIDC_DISCOVERY_URI to /etc/secrets/podman.env. update.sh reads the discovery document and PUTs the endpoints into Portainer's /api/settings.

Mapping Authentik groups onto Portainer teams is a Business Edition feature. In CE everyone who passes the Authentik binding lands with the same access. For a shared lab that is the intent; if you need per-person isolation, CE will not give it to you.

Dependencies

Depends on Purpose
cluster:vm Creates the Debian 13 VM from the cloud image
templates:debian OS prep (apt update/upgrade + qemu-guest-agent)
backup:vm Scheduled VM backup to PBS
network:proxy The published HTTPS name, upstream on :9443
identity:identity OIDC application, group binding, client credentials

Placement

No zone0 is set, so the VM lands in the environment's zone (ADR-007 P5). proxyAllowedZones is deliberately unset, which gives the internal default — every Active service zone plus home, work, mgmt and the netbird overlay, but not the internet — so members reach the console from a client zone while Authentik decides who gets in.

Sizing

2 vCPU / 2 GB RAM / 32 GB disk. Podman and Portainer are small; the disk is for the images and volumes of whatever gets run here.

For installation steps see INSTALL.md.