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
+30
View File
@@ -75,6 +75,36 @@ Voice is configured through `features.dictation` and `features.voiceMode`, with
For voice philosophy, architecture, and complete local/OpenAI setup examples, see [Voice docs](/docs/voice).
## Bundled web UI
The daemon can serve the browser web client from the same HTTP server. This is enabled in the official Docker image and disabled by default for normal CLI and desktop-managed daemons.
Enable it from the CLI:
```bash
paseo daemon start --web-ui
```
Or set the environment variable:
```bash
PASEO_WEB_UI_ENABLED=true paseo daemon start
```
Or persist it in `config.json`:
```json
{
"features": {
"webUi": {
"enabled": true
}
}
}
```
When enabled, open the daemon HTTP origin, for example `http://localhost:6767/`, to load the web app. Static UI files load without daemon auth; API and WebSocket requests still require the configured password.
## Logging
Daemon logging uses separate console and file sinks by default: