Rootless Podman in CI Pipelines Prompt
Get rootless Podman building and running containers reliably inside GitLab CI or GitHub Actions runners, including nested-container and storage-driver constraints.
- Target user
- CI/CD and platform engineers migrating pipelines off Docker-in-Docker
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior CI/CD platform engineer who has debugged rootless container builds inside every flavor of ephemeral runner. I will provide some or all of: - The CI platform and runner topology: GitLab Runner (docker, kubernetes, or shell executor) or GitHub Actions (hosted or self-hosted) - The pipeline job definition and the image the job runs in - The failing output: subuid/subgid errors, `newuidmap` permission failures, overlay mount failures, `/dev/fuse` errors, cgroup errors, or unexplained slowness - Whether the job needs to build images, run them, or both, and whether it pushes to a registry - Any constraints: no privileged containers allowed, no host mounts, seccomp/AppArmor policy in force Your job: 1. **Establish the nesting model** — describe exactly how many container layers are in play (runner container, job container, container Podman builds or runs) and which capabilities and devices each layer actually needs. Separate what is required for *building* from what is required for *running*, because building needs far less privilege. 2. **Fix the user namespace prerequisites** — verify the job's user has entries in `/etc/subuid` and `/etc/subgid`, that `newuidmap`/`newgidmap` from `shadow-utils`/`uidmap` are installed and setuid, and give the Containerfile lines that provision these in a custom CI image. Show `podman unshare cat /proc/self/uid_map` as the confirmation check. 3. **Choose a storage driver deliberately** — compare `overlay` with the `fuse-overlayfs` mount program (needs `/dev/fuse`), native rootless overlay on a kernel that supports unprivileged overlayfs, and `vfs` as the always-works fallback. Quantify the cost: `vfs` copies every layer and will dominate build time and disk usage. Give the `storage.conf` or `--storage-driver`/`--storage-opt` settings for the chosen option. 4. **Reduce privilege to the minimum that works** — instead of reaching for `--privileged`, prescribe the narrowest combination that resolves the error: `--device /dev/fuse`, `--security-opt seccomp=unconfined`, `--security-opt label=disable`, or `--security-opt unmask=`. For each one, say which specific failure it addresses so it can be removed when unnecessary. 5. **Handle cgroups in ephemeral runners** — explain that rootless resource limits require cgroup v2 with delegation, which most job containers do not have, and recommend either running without resource flags in CI or switching the cgroup manager to `cgroupfs` where systemd is not PID 1. Note the container may need `--cgroups=disabled` in constrained nesting. 6. **Wire up registry authentication** — give the non-interactive `podman login` pattern using the CI token from stdin, where `auth.json` lands for a rootless user (`$XDG_RUNTIME_DIR/containers/auth.json`), and how to point `REGISTRY_AUTH_FILE` at a writable path in an ephemeral job. 7. **Make it fast** — recommend caching strategy across ephemeral runners: `--layers` with a persisted storage path where the executor allows it, remote layer cache via `--cache-to`/`--cache-from` against a registry, and ordering the Containerfile so dependency installs precede source copy. State honestly which of these the given executor can and cannot support. 8. **Emit the working job definition** — produce the complete, copy-paste CI job YAML for my platform, with the image, `before_script`/setup steps, environment variables, and the build/push commands. Output as: (a) nesting model and privilege analysis, (b) prerequisite fixes with verification commands, (c) storage driver decision and config, (d) minimal privilege flags with per-flag justification, (e) cgroup handling, (f) registry auth setup, (g) caching plan with honest limitations, (h) complete job YAML. Do not default to `--privileged` as a shortcut. If the environment genuinely cannot support rootless nesting without it, say so plainly and describe what a privileged CI job exposes, so the tradeoff is a decision rather than an accident.
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
Rootless Podman in CI fails in a way that rewards structure over intuition, because there are three or four container layers stacked on each other and the error message names only the innermost. Establishing the nesting model first — runner container, job container, the container being built or run — and separating what building needs from what running needs is what keeps the fix proportionate. Building needs far less privilege than running, and conflating the two is how jobs end up privileged for no reason.
The prerequisite and storage-driver steps handle the two failure classes that account for most of the noise. Missing /etc/subuid entries or a non-setuid newuidmap produce errors that look like permission problems and are actually provisioning problems, fixable in the CI image itself. Storage driver choice is a performance cliff rather than a correctness one: vfs works everywhere and is slow enough to change how a team feels about the pipeline, so the prompt requires the cost to be quantified rather than mentioned.
The refusal to default to --privileged is the point of the whole prompt. It is the flag that makes every error disappear, which is exactly why it gets pasted into pipelines that then run untrusted pull-request code with host-level access. Requiring per-flag justification means each permission can be removed later when the underlying cause is fixed, and requiring the model to say plainly when an environment genuinely cannot support rootless nesting makes the tradeoff a decision someone made rather than an accident nobody reviewed.
Related prompts
-
Podman Slow Build & Layer Cache Diagnosis Prompt
Find why Podman builds are slow or rebuilding every layer, and restructure the Containerfile and build flags so the cache actually hits.
-
Podman subuid/subgid & User Namespace Sizing Prompt
Allocate non-overlapping subuid/subgid ranges and pick a user namespace mapping strategy for a host running rootless Podman for multiple tenants.
-
Dockerfile to Buildah Build Script Conversion Prompt
Convert a Dockerfile into an equivalent scripted buildah build so image construction can use host tooling, secrets, and logic that Dockerfile syntax cannot express.
-
Rootless Podman Port Publishing & Network Topology Prompt
Plan port publishing, inter-container DNS, and the rootless network stack for Podman services, including privileged ports and source-IP preservation.
More Podman prompts & error guides
Browse every Podman prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.