Container Runtime
May 25, 2026 ยท View on GitHub
Perseus does not require containers, but it can run as an OCI-style local image
when a team wants a sidecar, a reproducible helper, or an isolated service
process. The image still uses the single-file runtime: perseus.py is copied
directly into the image and exposed as perseus.
Build
Use any Docker-compatible or OCI-compatible builder:
docker build -t perseus:local .
Podman and other compatible builders can use the same Dockerfile if they
support standard Dockerfile syntax.
Render A Mounted Workspace
The default compose service renders the repository's .perseus/context.md into
the named Perseus home volume:
docker compose run --rm render
For an ad hoc run, mount the workspace read-only and keep Perseus state in a separate volume:
docker run --rm \
--mount type=bind,source="$PWD",target=/workspace,readonly \
--mount type=volume,source=perseus-home,target=/perseus-home \
-e PERSEUS_HOME=/perseus-home \
perseus:local render /workspace/.perseus/context.md --output /perseus-home/rendered-context.md
On shells that do not expose PWD, replace source="$PWD" with the absolute
path to the workspace.
Authenticated Serve
perseus serve refuses non-loopback binds unless bearer auth is configured or
the user explicitly opts into insecure remote access. Inside a container, the
process binds 0.0.0.0 so the port can be published, while the compose example
publishes only to host loopback:
docker compose --profile serve up serve
The compose file mounts examples/container/config.yaml at
/perseus-home/config.yaml. Replace change-me-before-serving with a token
from:
docker run --rm perseus:local serve --generate-token
Clients must send:
Authorization: Bearer change-me-before-serving
Watch In A Container
For a foreground sidecar that keeps render outputs fresh without host scheduler
setup, run the same image with perseus watch:
docker run --rm \
--mount type=bind,source="$PWD",target=/workspace,readonly \
--mount type=volume,source=perseus-home,target=/perseus-home \
-e PERSEUS_HOME=/perseus-home \
perseus:local watch --source /workspace/.perseus/context.md \
--output /perseus-home/rendered-context.md \
--allow-outside-workspace
If the mounted workspace contains .perseus/pack.yaml, omit --source and
--output to refresh the pack's renders: targets.
Trust Notes
- Mount workspaces read-only unless Perseus is intentionally writing rendered output back into the project.
- Treat
/perseus-homeas stateful: it can contain config, auth tokens, cache, checkpoints, audit logs, Mneme data, inbox messages, and Pythia logs. - Do not mount the host container socket into the Perseus container.
- Keep published ports loopback-bound unless the token and network boundary are intentional.
read_only: trueand a/tmptmpfs are useful hardening defaults for serve mode. Keep/perseus-homewritable if you want audit logs and cache writes.- Local or OpenAI-compatible LLM endpoints must be configured explicitly and made reachable from the container network.