Run Paseo from an official Docker image (#1740)

* Add Docker images and agent Docker Mods

Ship official container images that run the Paseo daemon headless. One
Dockerfile parametrized by BASE_IMAGE covers Debian 12/13, Ubuntu 22.04/24.04
and Alpine; it bundles Node 22, the npm-published server + CLI, a vendored
s6-overlay as PID 1, and a small Docker Mods loader.

Agents are chosen at runtime via DOCKER_MODS (pipe-separated mod images). Each
mod is a FROM scratch image carrying only an install hook that runs
`npm install -g <agent-cli>`; the loader pulls the layers from the registry,
extracts them, and runs the hook before the daemon starts, so any requested
agent is on PATH when Paseo probes provider availability.

- docker/base: Dockerfile, install scripts, s6 services, mods loader
- docker/mods/*: claude-code, codex, copilot, opencode, pi
- docker/docker-compose.example.yml + docker/README.md
- .github/workflows/docker.yml: multi-arch (amd64/arm64) buildx matrix,
  publishes to ghcr.io/getpaseo on version tags
- docs/docker.md + CLAUDE.md docs index row

* feat(docker): print pairing QR and link on daemon startup

Add an s6 oneshot service that waits for the daemon to listen, then runs
`paseo daemon pair` so the pairing QR code and link surface in the container
logs. Best-effort: never blocks boot, skips gracefully when relay is disabled.
Opt out with PASEO_PAIRING_QR=0.

* build(docker): add Arch image support

* ci(docker): build Arch without Buildx

* docs(docker): document paseo env contract

* feat(docker): add opt-in sudo mode

* docs(docker): link env references

* fix(docker): create agent config dirs

* fix(docker): default home to /home/paseo

* docs(docker): document agent auth setup

* docs(docker): document relay port setup

* fix(docker): install Node from tarball

* docs: add Docker quick start

* docs(docker): remove legacy home example

* docs(docker): set container hostname

* fix(docker): prepare opencode storage

* fix(docker): allow paseo login shell

* fix docker opencode permissions

* ci(docker): use Node 24 actions

* fix(docker): install bzip2 runtime tools

* fix(docker): update Pi mod package

* fix(docker): quiet default daemon logs

* fix(docker): split home from state

Docker images now keep HOME at /home/paseo and store Paseo daemon state under /home/paseo/.paseo by default.

Existing volumes can keep the old layout by setting PASEO_HOME=/home/paseo.

* fix(docker): keep mods out of paseo home

* ci(docker): skip alpine arm64 builds

* fix(docker): address review findings

* fix(docker): verify s6 overlay downloads

* fix(docker): honor custom healthcheck port

* fix(docker): fail on mod extraction errors

* feat(docker): add official container image

Ship a focused daemon image with the bundled web UI enabled and document extending it with agent CLIs.

* ci(docker): publish images only on stable releases

* fix(docker): check daemon health over HTTP

---------

Co-authored-by: Herbrant <cdavide98carnemolla@gmail.com>
This commit is contained in:
Mohamed Boudra
2026-06-26 14:48:13 +08:00
committed by GitHub
co-authored by Herbrant
parent 28c5e55bd9
commit 2c9db5279c
16 changed files with 832 additions and 2 deletions
+17
View File
@@ -110,6 +110,22 @@ The password is stored as a bcrypt hash in `config.json`, the daemon never store
We still recommend the relay for mobile access, it combines authentication with end-to-end encryption out of the box. Password auth is primarily useful for direct LAN or VPN connections where you want access control without the relay.
## Docker self-hosting
The official Docker image runs the daemon and bundled web UI in one container. It binds to `0.0.0.0:6767` inside the container so Docker port publishing and reverse proxies work normally.
For Docker deployments:
- Set `PASEO_PASSWORD` before publishing the port to a LAN, VPN, or public address.
- Use HTTPS at your reverse proxy for browser access outside localhost.
- Set `PASEO_HOSTNAMES` for any DNS names you use to reach the container.
- Keep `/workspace` mounts scoped to repositories the agents should be able to read and write.
- Treat `/home/paseo` as sensitive, it can contain daemon state and provider credentials.
The image runs the daemon and launched agents as the non-root `paseo` user, but container user isolation is not a substitute for careful mounts. Agents can still access whatever code and credentials you mount into the container.
See [Docker](/docs/docker) for Compose and reverse proxy examples.
## Agent authentication
Paseo wraps agent CLIs (Claude Code, Codex, OpenCode) but does not manage their authentication. Each agent provider handles its own credentials:
@@ -126,4 +142,5 @@ Paseo never stores or transmits provider API keys. Agents run in your user conte
- **Treat the QR code like a password**, anyone with the pairing offer can connect to your daemon
- **Set a password** if you bind to a network address, it prevents unauthorized clients from controlling your agents
- **Never bind to 0.0.0.0 without a password**, without one, any device on your network can connect
- **Scope Docker mounts tightly**, agents can access mounted workspaces and provider credentials
- **Keep your daemon updated**, security improvements are released regularly