Drop the history and roadmap asides: which services predate the collection's
conventions, the unwired Open Web UI plan, the generic clone-and-troubleshoot
boilerplate. Services that publish ports or set `restart:` now simply say so.
couchbase, openvpn-as and traffmonetizer had two-line READMEs; give them the
ports, variables and storage the root README promises. traffmonetizer reads
${TOKEN} and had no .env.example, so add one.
paseo
Paseo — self-hosted daemon and web UI for running coding
agents. Built from a local Dockerfile that adds six agent CLIs, gh, Go,
Python, and shell tooling to the
official image, which ships none of it.
Setup
-
Set the variables from
.env.examplein Coolify or Dokploy. -
Point the domain at port
6767and deploy. -
Open the domain. At the pairing screen enter the host with the port, then the
PASEO_PASSWORDvalue:paseo.example.com:443 -
In a terminal inside Paseo, log in once per tool you use — see Agents — plus
gh auth login.
The port must be typed by hand. The UI rejects a bare hostname, and the
auto-connect hint does not help: the daemon builds it from the Host header,
browsers drop the default :443, and the UI discards a hint with no port. What
you see instead is its localhost:6767 placeholder, which in a browser means
your own machine.
If it stays on localhost:6767 after you enter the address, clear site data —
the old entry is cached in localStorage.
Environment
| Variable | Purpose |
|---|---|
PASEO_PASSWORD |
Web UI and API login, and the paseo user's sudo password. Generate with openssl rand -base64 24. |
PASEO_HOSTNAMES |
Domains allowed to reach the daemon, comma-separated. Your domain must be listed. |
PASEO_TRUSTED_PROXIES |
Set to uniquelocal, or the UI loads but never connects. |
PASEO_LABEL |
Container hostname, shown as the host label in the UI. Without it the label is a random container ID. |
GIT_NAME / GIT_EMAIL |
Git author and committer identity for agents and terminals. |
TZ |
Timezone for logs and agent shells. |
SHELL |
Shell for Paseo's terminals. Paseo reads $SHELL and falls back to /bin/sh, ignoring the login shell, so chsh has no effect. |
PASEO_TRUSTED_PROXIES matches the proxy's source IP, so hostnames are
rejected. The daemon trusts X-Forwarded-Proto from loopback only, but
Coolify's Traefik reaches it from the Docker bridge network — so it reads the
request as plain HTTP, tells the UI to use ws:// on an https:// page, and
the browser blocks that as mixed content. uniquelocal covers the private
ranges Docker uses. An exact CIDR works too, but Coolify assigns a fresh subnet
per project.
Networking
Listens on 6767, published nowhere — the platform maps the domain to it, so
localhost:6767 on the host refuses connections. See the
root README for why.
Agents
| Agent | Command | Package | Log in with |
|---|---|---|---|
| Claude Code | claude |
@anthropic-ai/claude-code |
claude |
| Codex | codex |
@openai/codex |
codex login |
| opencode | opencode |
opencode-ai |
opencode auth login |
| Copilot CLI | copilot |
@github/copilot |
/login inside copilot |
| Pi | pi |
@earendil-works/pi-coding-agent |
pi |
| Oh My Pi | omp |
@oh-my-pi/pi-coding-agent |
omp |
All six come from npm, so another provider is one more entry on the npm install line. Pi and Oh My Pi are separate projects sharing an ancestor; their
commands do not collide.
Storage
| Volume | Mount | Holds |
|---|---|---|
paseo-home |
/home/paseo |
Daemon state, agent configs, credentials (.claude, .codex, .config/*) |
paseo-workspace |
/workspace |
Code the agents work on |
Every agent CLI and gh keep their config under /home/paseo, so all logins
survive a redeploy — the base image points CLAUDE_CONFIG_DIR, CODEX_HOME
and the XDG_* variables into it. Dotfiles live there too, so a .zshrc or
oh-my-zsh install persists. Anything written outside $HOME (chsh,
apt install) is lost on rebuild.
Image
| Tool | Source | Why not apt |
|---|---|---|
| Agent CLIs (see above) | npm | — |
| Bun | Official bun.sh install script |
Debian does not package it |
gh |
GitHub's signed apt repo | Debian does not package it |
Go (GO_VERSION) |
Official go.dev tarball | Debian 12 ships 1.19 |
Python (PYTHON_VERSION) |
uv python install |
Debian 12 ships 3.11 |
less nano jq unzip zip lsof psmisc ugrep bfs zsh sudo |
apt | — |
Bump a language with a build arg, e.g. --build-arg GO_VERSION=1.27.1. uv
itself is installed too.
Constraints worth knowing before changing the Dockerfile:
$HOMEis/home/paseo, a volume that masks anything the build writes there. Hence/opt/pythonand/usr/local/gorather than the defaults, and hence npm rather than each vendor'scurl | bashinstaller, which writes to$HOME/.local. npm delivers the same native binaries regardless — every one of these packages is a thin launcher with the real binary as a per-platform optional dependency.- Bun exists for
ompalone, whose bin opens with#!/usr/bin/env bun. Node runs the other five. - The agent CLIs cannot auto-update, since
paseocannot write/usr/local. Claude Code shows a notice at startup. Rebuild to update. - The image stays root: the entrypoint chowns the volumes, then drops to the
paseouser (uid 1000) withgosu. entrypoint.shsets thepaseopassword fromPASEO_PASSWORDon every start, while still root./etc/shadowis not on a volume, so it reverts on each recreate. An emptyPASEO_PASSWORDleaves the account locked andsudounusable.sudoresetsPATHto itssecure_path, which excludes/usr/local/go/bin. Usesudo env PATH="$PATH" go ...or the full path.