Podman
Run the OpenClaw Gateway in a rootless Podman container, managed by your current non-root user. The intended model is:- Podman runs the gateway container.
- Your host
openclawCLI is the control plane. - Persistent state lives on the host under
~/.openclawby default. - Day-to-day management uses
openclaw --container <name> ...instead ofsudo -u openclaw,podman exec, or a separate service user.
Prerequisites
- Podman in rootless mode
- OpenClaw CLI installed on the host
- Optional:
systemd --userif you want Quadlet-managed auto-start - Optional:
sudoonly if you wantloginctl enable-linger "$(whoami)"for boot persistence on a headless host
Quick start
Run onboarding inside the container
Run
./scripts/run-openclaw-podman.sh launch setup, then open http://127.0.0.1:18789/../scripts/podman/setup.shbuildsopenclaw:localin your rootless Podman store by default, or usesOPENCLAW_IMAGE/OPENCLAW_PODMAN_IMAGEif you set one.- It creates
~/.openclaw/openclaw.jsonwithgateway.mode: "local"if missing. - It creates
~/.openclaw/.envwithOPENCLAW_GATEWAY_TOKENif missing. - For manual launches, the helper reads only a small allowlist of Podman-related keys from
~/.openclaw/.envand passes explicit runtime env vars to the container; it does not hand the full env file to Podman.
OPENCLAW_PODMAN_QUADLET=1.
Optional build/setup env vars:
OPENCLAW_IMAGEorOPENCLAW_PODMAN_IMAGE— use an existing/pulled image instead of buildingopenclaw:localOPENCLAW_DOCKER_APT_PACKAGES— install extra apt packages during image buildOPENCLAW_EXTENSIONS— pre-install extension dependencies at build time
--userns=keep-id and bind-mounts your OpenClaw state into the container.
Onboarding:
http://127.0.0.1:18789/ and use the token from ~/.openclaw/.env.
Host CLI default:
Podman + Tailscale
For HTTPS or remote browser access, follow the main Tailscale docs. Podman-specific note:- Keep the Podman publish host at
127.0.0.1. - Prefer host-managed
tailscale serveoveropenclaw gateway --tailscale serve. - On macOS, if local browser device-auth context is unreliable, use Tailscale access instead of ad hoc local tunnel workarounds.
Systemd (Quadlet, optional)
If you ran./scripts/podman/setup.sh --quadlet, setup installs a Quadlet file at:
- Start:
systemctl --user start openclaw.service - Stop:
systemctl --user stop openclaw.service - Status:
systemctl --user status openclaw.service - Logs:
journalctl --user -u openclaw.service -f
Config, env, and storage
- Config dir:
~/.openclaw - Workspace dir:
~/.openclaw/workspace - Token file:
~/.openclaw/.env - Launch helper:
./scripts/run-openclaw-podman.sh
OPENCLAW_CONFIG_DIR->/home/node/.openclawOPENCLAW_WORKSPACE_DIR->/home/node/.openclaw/workspace
gateway.controlUi.allowedOrigins for 127.0.0.1 and localhost on the published gateway port so the local dashboard works with the container’s non-loopback bind.
Useful env vars for the manual launcher:
OPENCLAW_PODMAN_CONTAINER— container name (openclawby default)OPENCLAW_PODMAN_IMAGE/OPENCLAW_IMAGE— image to runOPENCLAW_PODMAN_GATEWAY_HOST_PORT— host port mapped to container18789OPENCLAW_PODMAN_BRIDGE_HOST_PORT— host port mapped to container18790OPENCLAW_PODMAN_PUBLISH_HOST— host interface for published ports; default is127.0.0.1OPENCLAW_GATEWAY_BIND— gateway bind mode inside the container; default islanOPENCLAW_PODMAN_USERNS—keep-id(default),auto, orhost
~/.openclaw/.env before finalizing container/image defaults, so you can persist these there.
If you use a non-default OPENCLAW_CONFIG_DIR or OPENCLAW_WORKSPACE_DIR, set the same variables for both ./scripts/podman/setup.sh and later ./scripts/run-openclaw-podman.sh launch commands. The repo-local launcher does not persist custom path overrides across shells.
Quadlet note:
- The generated Quadlet service intentionally keeps a fixed, hardened default shape:
127.0.0.1published ports,--bind laninside the container, andkeep-iduser namespace. - It still reads
~/.openclaw/.envfor gateway runtime env such asOPENCLAW_GATEWAY_TOKEN, but it does not consume the manual launcher’s Podman-specific override allowlist. - If you need custom publish ports, publish host, or other container-run flags, use the manual launcher or edit
~/.config/containers/systemd/openclaw.containerdirectly, then reload and restart the service.
Useful commands
- Container logs:
podman logs -f openclaw - Stop container:
podman stop openclaw - Remove container:
podman rm -f openclaw - Open dashboard URL from host CLI:
openclaw dashboard --no-open - Health/status via host CLI:
openclaw gateway status --deep
Troubleshooting
- Permission denied (EACCES) on config or workspace: The container runs with
--userns=keep-idand--user <your uid>:<your gid>by default. Ensure the host config/workspace paths are owned by your current user. - Gateway start blocked (missing
gateway.mode=local): Ensure~/.openclaw/openclaw.jsonexists and setsgateway.mode="local".scripts/podman/setup.shcreates this if missing. - Container CLI commands hit the wrong target: Use
openclaw --container <name> ...explicitly, or exportOPENCLAW_CONTAINER=<name>in your shell. openclaw updatefails with--container: Expected. Rebuild/pull the image, then restart the container or the Quadlet service.- Quadlet service does not start: Run
systemctl --user daemon-reload, thensystemctl --user start openclaw.service. On headless systems you may also needsudo loginctl enable-linger "$(whoami)". - SELinux blocks bind mounts: Leave the default mount behavior alone; the launcher auto-adds
:Zon Linux when SELinux is enforcing or permissive.