Portainer registers the OIDC provider through its own API and ships no podman-configure-oidc.service, so identity:identity only logged a spurious restart failure each update. Relies on the configureService="none" support just added upstream. |
||
|---|---|---|
| .. | ||
| DESIGN.md | ||
| INSTALL.md | ||
| install.sh | ||
| podman.json | ||
| README.md | ||
| test.sh | ||
| update.sh | ||
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 unset gives the internal default — every Active service zone plus home,
work, mgmt and the netbird overlay, but not the internet. Note the operator's admin-VPN
overlay (admin, 10.255.1.0/24) is not in that default, so a remote admin on the WireGuard
tunnel gets 403 too. Set proxyAllowedZones: ["internet"] to publish it — but read the
warning below first.
Publishing to the internet
proxyAllowedZones: ["internet"] removes the network restriction, leaving Authentik as the
gate. That is almost true, and the gap matters:
Enabling OAuth does not disable Portainer's internal login. POST /api/auth stays live and
still accepts the break-glass admin, whatever the UI shows — verified against the public
endpoint, which answers 422 Invalid credentials rather than refusing the path. So publishing
the console also publishes a username/password path for the local admin.
The password is 32 random base64 characters, so guessing it is not the threat; an authentication bypass in Portainer itself would be. If you want "gated by identity" to be literally true, promote an OIDC user to administrator and then delete the local admin — accepting that an Authentik outage then locks everyone out until the volume is restored.
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.