mirror of
https://github.com/tiennm99/composes.git
synced 2026-10-11 12:09:25 +00:00
feat(paseo): add paseo service with Claude Code preinstalled
The upstream image ships no agent CLIs, so build from a local Dockerfile that layers Claude Code on top. npm delivers the same native binary as the standalone installer, which cannot be used here: it writes to $HOME/.local, and $HOME is /home/paseo, a volume mount that masks anything baked in at build time. Runs as root by design -- the entrypoint chowns the mounted volumes and then drops to the unprivileged paseo user with gosu.
This commit is contained in:
1 parent
2de7bb68ab
commit
c1e10c3663
5 files changed
+90
No files matched your search
@@ -60,6 +60,7 @@ Each links to its own README for variables, ports, and storage.
|
||||
| [netdata](netdata/README.md) | Netdata monitoring agent |
|
||||
| [ollama](ollama/README.md) | Ollama, optionally with a web UI |
|
||||
| [openvpn-as](openvpn-as/README.md) | OpenVPN Access Server |
|
||||
| [paseo](paseo/README.md) | Paseo coding-agent daemon and web UI |
|
||||
| [tastyigniter](tastyigniter/README.md) | TastyIgniter restaurant ordering platform |
|
||||
| [traffmonetizer](traffmonetizer/README.md) | TraffMonetizer bandwidth-sharing client |
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copy to .env and fill in. Never commit .env.
|
||||
#
|
||||
# cp .env.example .env
|
||||
|
||||
# Password for the daemon API and web UI.
|
||||
# Generate one with: openssl rand -base64 24
|
||||
PASEO_PASSWORD=
|
||||
|
||||
# Comma-separated DNS names allowed to reach the daemon. The domain mapped in
|
||||
# Coolify/Dokploy must be listed here. IPs and localhost are always allowed.
|
||||
PASEO_HOSTNAMES=
|
||||
@@ -0,0 +1,13 @@
|
||||
# The official image ships no agent CLIs. Add Claude Code globally under
|
||||
# /usr/local, where the unprivileged paseo user can run it.
|
||||
#
|
||||
# npm here delivers the same native binary as the standalone installer -- it is
|
||||
# not a Node wrapper. Do not swap this for the `curl | bash` installer: that
|
||||
# writes to $HOME/.local, and $HOME is /home/paseo, a volume mount that masks
|
||||
# anything baked in at build time.
|
||||
#
|
||||
# Stays root: the entrypoint needs root to chown the mounted volumes, then
|
||||
# drops to paseo with gosu itself.
|
||||
FROM ghcr.io/getpaseo/paseo:latest
|
||||
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
@@ -0,0 +1,53 @@
|
||||
# paseo
|
||||
|
||||
[Paseo](https://paseo.sh) — a self-hosted daemon and web UI for running coding
|
||||
agents, from the [official image](https://paseo.sh/docs/docker).
|
||||
|
||||
Built from a local `Dockerfile` rather than the upstream image directly: the
|
||||
official image ships no provider CLIs, so this one layers Claude Code on top
|
||||
via `npm install -g @anthropic-ai/claude-code`. Add other providers
|
||||
(`@openai/codex`, `opencode-ai`) to that same line if you need them.
|
||||
|
||||
npm installs the same native binary as Anthropic's standalone installer, so
|
||||
there is nothing to gain by switching. The `curl | bash` installer is in fact
|
||||
the wrong choice here — it writes to `$HOME/.local`, and `$HOME` is
|
||||
`/home/paseo`, a volume mount that hides anything baked in at build time.
|
||||
|
||||
Claude Code cannot auto-update, since `paseo` can't write `/usr/local`; expect
|
||||
a one-time notice at startup. Rebuild the image to pick up a new version.
|
||||
|
||||
The image intentionally keeps running as root — its entrypoint chowns the
|
||||
mounted volumes and then drops to the unprivileged `paseo` user with `gosu`.
|
||||
|
||||
Coolify and Dokploy build the image themselves from the compose `build:`
|
||||
stanza; there is nothing to push.
|
||||
|
||||
## Environment
|
||||
|
||||
| Variable | Purpose |
|
||||
| --- | --- |
|
||||
| `PASEO_PASSWORD` | Auth for the daemon API and WebSocket |
|
||||
| `PASEO_HOSTNAMES` | Comma-separated DNS names allowed to reach the daemon, e.g. `paseo.example.com,.lan`. IPs and localhost always pass. |
|
||||
|
||||
Generate a password with `openssl rand -base64 24`. The proxied domain must
|
||||
appear in `PASEO_HOSTNAMES` or requests are rejected.
|
||||
|
||||
## Networking
|
||||
|
||||
Listens on `6767`. No ports are published — point the domain at that port in
|
||||
Coolify or Dokploy. See the [root README](../README.md) for why.
|
||||
|
||||
## Storage
|
||||
|
||||
Two named volumes:
|
||||
|
||||
| Volume | Mount | Holds |
|
||||
| --- | --- | --- |
|
||||
| `paseo-home` | `/home/paseo` | Daemon state, agent configs, credentials (`.codex`, `.claude`) |
|
||||
| `paseo-workspace` | `/workspace` | Code the agents work on |
|
||||
|
||||
Claude Code's own config lives under `/home/paseo/.claude`, so it persists in
|
||||
`paseo-home` — credentials survive a redeploy.
|
||||
|
||||
The daemon runs as uid/gid `1000:1000`; anything bind-mounted in its place must
|
||||
be writable by that user.
|
||||
@@ -0,0 +1,12 @@
|
||||
services:
|
||||
paseo:
|
||||
build: .
|
||||
environment:
|
||||
- PASEO_PASSWORD=${PASEO_PASSWORD}
|
||||
- PASEO_HOSTNAMES=${PASEO_HOSTNAMES}
|
||||
volumes:
|
||||
- 'paseo-home:/home/paseo'
|
||||
- 'paseo-workspace:/workspace'
|
||||
volumes:
|
||||
paseo-home:
|
||||
paseo-workspace:
|
||||
Reference in new issue
Block a user