Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/platform-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,37 @@ jobs:
- run: npm run check -w run-spaceapp
- run: npm run pack:dry-run -w run-spaceapp
- run: node packages/run-spaceapp/bin/spaceapp.mjs --version

rootless-podman:
name: Rootless Podman (ubuntu-latest)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "22.23.0"
cache: npm

- name: Install workspace dependencies on supported hosts
if: runner.arch != 'ARM64'
run: npm ci

- name: Install source workspace for the intentional x64 package rejection test
if: runner.arch == 'ARM64'
run: npm ci --force

- name: Probe the runner Podman and run the launcher suite
run: |
if ! command -v podman >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y podman
fi
podman --version
podman info --format 'rootless={{.Host.Security.Rootless}} version={{.Version.Version}} cgroup={{.Host.CgroupVersion}}' || true
node --test packages/run-spaceapp/tests/podman.test.mjs
npm test -w run-spaceapp
npm run check -w run-spaceapp
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Coordinate multi-step tasks conversationally through the Room Agent or speak nat
- **Hardware**:
- Minimum (`small` profile): 4 CPU cores, 8 GB-class RAM (at least 7 GiB reported by the operating system), 6.5 GiB free disk.
- `large` profile (adds the managed browser): 8 CPU cores, 15 GiB RAM, 11 GiB free disk.
- **Docker**: If Docker is not installed, the installer automatically installs official Docker Desktop (Windows/macOS) or Docker Engine (Linux).
- **Docker or Rootless Podman 5+**: If Docker is not installed, the installer automatically installs official Docker Desktop (Windows/macOS) or Docker Engine (Linux), or you can use rootless **Podman 5+** via `npx --yes run-spaceapp@latest install --engine podman` (note: `--access host-root` is only supported on Linux with Docker and is refused under `--engine podman`).

### Run the Installation Command

Expand Down
22 changes: 20 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,26 @@ data, credentials, workspaces, secrets, and persistent volumes, run:
npx --yes run-spaceapp@latest install --access isolated
```

Host-root is supported only on Linux; the launcher refuses it on macOS and
Windows.
Host-root is supported only on Linux with Docker (`--engine docker`); the launcher refuses it on macOS, Windows, and rootless Podman (`--engine podman`).

## Rootless Podman (`--engine podman`)

SpaceApp supports rootless **Podman 5+** as a first-class container engine:

```bash
npx --yes run-spaceapp@latest install --engine podman
```

If Docker is not installed and a working Podman 5+ runtime with `podman compose` is already on `PATH`, `run-spaceapp install` offers to use Podman automatically. Passing `--engine podman` skips the Docker installation flow, verifies `podman --version` (5+), `podman compose version`, and `podman info`, and records `"engine": "podman"` in `config.json`.

- **Podman 5+ requirement**: Podman 4.x is rejected with upgrade instructions. The supported Compose provider is `podman compose` from Podman 5 or newer, backed by Docker Compose v2 or `podman-compose`. Podman 4.x is not supported.
- **Workspaces & SELinux**: Registered workspace bind mounts include `:z` SELinux shared labels. `spaceapp-cli` uses `userns_mode: "keep-id:uid=10001,gid=10001"` so container UID `10001` maps to your host user. The published images start as root and `gosu` down to that user, so the Podman CLI service is written without `no-new-privileges` (that option makes the switch fail with "operation not permitted"). Other services keep `no-new-privileges`.
- **macOS**: `install --engine podman` checks the running Podman machine's CPU, memory, and disk against the selected profile and prints a `podman machine set` command when the machine is too small. Disk size is only increased.
- **Windows**: Podman is not supported. Use Docker Desktop.
- **`--answers`**: `"engine": "podman"` in the answers file selects Podman the same way `--engine podman` does. When Docker is missing, an interactive install asks before using Podman; `--non-interactive` selects it.
- **`--access host-root` limitation**: `--access host-root` is refused when `--engine podman` is selected because rootless user namespaces remap host UIDs. Use `--access isolated` and `spaceapp workspace add <path>`.
- **Engine migration**: Switching engines (`docker` ↔ `podman`) on an existing installation is refused so named-volume data is never silently orphaned. Run `spaceapp backup`, uninstall with `--purge-data` (or choose a new `SPACEAPP_HOME`), install with the other `--engine`, then run `spaceapp restore`.
- **doctor**: Reports the engine, Podman version, rootless or rootful mode, cgroup version, and whether the `cpu` and `memory` controllers are delegated. `support-bundle` records the same facts and no secrets.

The `npx` command is the universal one-command installer. To retain a global
launcher for later operations, optionally run `npm install -g run-spaceapp`;
Expand Down
20 changes: 19 additions & 1 deletion packages/run-spaceapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,28 @@ before enabling it:
npx --yes run-spaceapp@latest install --access host-root
```

Host-root is supported only on Linux. Run
Host-root is supported only on Linux with Docker (`--engine docker`). Rootless Podman (`--engine podman`) refuses `--access host-root` because rootless user namespaces remap host UIDs. Run
`npx --yes run-spaceapp@latest install --access isolated` to remove the host
mount while keeping SpaceApp data and volumes.

### Rootless Podman (`--engine podman`)

On Fedora, RHEL, CentOS, Silverblue/Kinoite, Debian, Ubuntu, and macOS Podman machine, you can run SpaceApp on **Podman 5+** without installing Docker or joining the root-equivalent `docker` group. Windows Podman is not supported.

```bash
npx --yes run-spaceapp@latest install --engine podman
```

When Docker is absent and a working `podman` (version 5+) with `podman compose` is detected on `PATH`, the launcher offers to use Podman automatically. Passing `--engine podman` selects Podman explicitly, persists `"engine": "podman"` in `config.json`, and runs all lifecycle commands (`up`, `down`, `update`, `reinstall`, `uninstall`, `backup`, `restore`, `logs`, `ps`, `doctor`, `workspace`, `provider`, and `owner`) through `podman compose`.

- **Requirement**: Podman **5.0 or newer** with `podman compose` (Docker Compose v2 or `podman-compose`) and `slirp4netns` or `pasta` for rootless networking. Podman 4.x is rejected.
- **Rootless Workspace Permissions & SELinux**: Under `--engine podman`, registered workspaces receive `:z` SELinux relabeling (`bind.selinux: "z"`) and `spaceapp-cli` sets `userns_mode: "keep-id:uid=10001,gid=10001"` so container UID `10001` maps to the host user without `sudo setfacl`. That service omits `no-new-privileges` because the image entrypoint uses `gosu` to drop from root to UID 10001, which `no-new-privileges` blocks under `keep-id`.
- **macOS Podman machine**: The installer compares `podman machine inspect` CPU, memory, and disk with the profile and tells you how to grow the machine when it is too small.
- **Answers**: `--answers '{"engine":"podman","confirm":true,...}'` selects Podman without a separate `--engine` flag. If Docker is absent, `--non-interactive` selects a ready Podman 5; an interactive install asks first.
- **Limitation (`--access host-root`)**: `--access host-root` is not supported with `--engine podman` because rootless user namespaces cannot read/write arbitrary root-owned host paths. Use `--access isolated` and `spaceapp workspace add <path>` instead.
- **Diagnostics**: `doctor` and `support-bundle` report the engine, version, rootless or rootful mode, cgroup version, and `cpu`/`memory` controller delegation. A missing controller is a warning, not a late resource-limit failure.
- **Switching Engines**: Switching container engines (`--engine docker` ↔ `--engine podman`) on an existing installation is refused because Docker and Podman do not share named volumes. To migrate, run `spaceapp backup`, uninstall with `--purge-data` (or choose a new `SPACEAPP_HOME`), install with the target `--engine`, and run `spaceapp restore`.

Provider API keys are read from masked standard input and written to
restrictive files outside Git. OAuth and device-code credentials remain in
isolated Docker provider state. Neither credential source is included in
Expand Down
Loading
Loading