Skip to content

feat(run-spaceapp): support rootless Podman as a container engine (#63) - #1

Merged
dayton536 merged 2 commits into
mainfrom
cursor/rootless-podman-d2d4
Oct 27, 2026
Merged

dayton536 merged 2 commits into
mainfrom
cursor/rootless-podman-d2d4

Conversation

@dayton536

@dayton536 dayton536 commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Fixes oll4com#63

Problem and user impact

run-spaceapp could only install and operate SpaceApp through Docker. People on Fedora, RHEL, and other hosts that ship rootless Podman, and people who will not run a root Docker daemon, could not install SpaceApp at all.

Change

Docker stays the default. Nothing changes for an existing Docker installation.

  • install --engine docker|podman (and "engine" in --answers) is saved in config.json and used by later lifecycle commands: up, down, status, logs, update, rollback, backup, restore, doctor, repair, uninstall, provider install, credentials, owner, and workspace.
  • If Docker is missing and Podman 5+ with podman compose is ready, an interactive install asks before using it. --non-interactive selects it. Podman 4.x is rejected. Windows Podman is refused; Linux rootless and macOS Podman machine are the supported paths.
  • Compose stays on the published images and the existing template features (profiles, file secrets, depends_on health conditions, init, mem_limit/cpus, shared socket volumes, --wait on the checkpoint database, and exec/run --user 10001:10001). The command is podman compose (Docker Compose v2 or podman-compose).
  • Workspace bind mounts on Podman get bind.selinux: z. spaceapp-cli (and per-user CLI services) set userns_mode: keep-id:uid=10001,gid=10001 so container UID 10001 is the host user. Those services omit no-new-privileges because the image entrypoint uses gosu to drop from root to UID 10001, and no-new-privileges makes that switch fail with "operation not permitted". Other services keep no-new-privileges.
  • macOS compares podman machine inspect CPU, memory, and disk with the selected profile and prints a podman machine set command that only grows the disk.
  • doctor and support-bundle report the engine, version, rootless or rootful mode, cgroup version, and whether the cpu and memory controllers are delegated.
  • Switching engines on an existing installation is refused. uninstall --purge-data removes volumes but keeps config.json and backups/. Same-root migration deletes only config.json. A new home needs the backup directory copied in, and the old runtime stopped first so port 127.0.0.1:4911 is free. Backups omit browser profiles, google-oauth.json, and Telegram secrets.
  • .github/workflows/platform-matrix.yml gains a rootless-podman job on ubuntu-latest that requires Podman 5, a rootless podman info, a Compose provider, a real podman run, and the launcher suite.

Verification

  • Relevant automated tests pass.
  • Linux, macOS, and/or Windows coverage is listed.
  • UI changes include real browser console/network evidence.
  • Every commit has a Signed-off-by: line (Developer Certificate of Origin 1.1), and the contribution is licensed under the MIT License (see CONTRIBUTING.md).
  • No credentials, tokens, personal memory, customer data, private paths, or runtime state are included.
  • Documentation and changelog are updated when behavior changes.
  • Security, migration, resource, and rollback effects are described.

Commands run in this environment:

  • npm test -w run-spaceapp — 219 passed, 0 failed
  • npm run check -w run-spaceapp — passed
  • npm run verify:export-provenance — ok, 4948 files, 422 sanitized, 0 problems
  • node --test scripts/tests/verify-export-provenance.test.mjs — 3 passed

The edited docs and provenance script are public-repository files, so PUBLIC_EXPORT_MANIFEST.json did not need a new hash. Provenance still reports 0 problems.

Security, migration, and rollback

Named volumes are not shared between Docker and Podman, so an in-place engine change is refused. --access host-root stays Linux + Docker only. Dropping no-new-privileges is limited to the Podman CLI service so gosu can drop to UID 10001; the entrypoint still switches user before the CLI host runs. Set SPACEAPP_HOME before migration commands. The launcher has no --root flag; an unset SPACEAPP_HOME would make $SPACEAPP_HOME/config.json expand to /config.json.

Open in Web Open in Cursor 

dayton536 and others added 2 commits October 27, 2026 23:19
Docker stays the default. --engine podman, and a ready Podman 5 when Docker
is absent, persists the engine and runs lifecycle commands through podman
compose. Workspace mounts get SELinux :z and keep-id so uid 10001 maps to
the host user; the CLI service drops no-new-privileges so gosu can still
switch to that uid. Host-root and in-place engine switches are refused.

Signed-off-by: Dayton Allen <daytonballen@gmail.com>
Co-authored-by: dayton536 <dayton536@users.noreply.github.com>
The runtime Dockerfile already packs undici 6.29.1. The public distribution
test still expected 6.28.1, so the public suite failed on main.

Signed-off-by: Dayton Allen <daytonballen@gmail.com>
Co-authored-by: dayton536 <dayton536@users.noreply.github.com>
@dayton536
dayton536 merged commit 725028e into main Oct 27, 2026
6 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[$600] Support rootless Podman as a container engine in the run-spaceapp launcher

1 participant