Container deployment for Agent Zoo with authenticated Android/mobile gateway support.
  • Shell 57.9%
  • Python 25.5%
  • Dockerfile 16.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Clawlter Agent ac259739bf
All checks were successful
Container image / Build and smoke-test container image (pull_request) Successful in 1m15s
Container image / Build and smoke-test container image (push) Successful in 1m21s
fix(ci): inspect service UID through procfs
2026-08-11 04:02:19 +00:00
.forgejo/workflows feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
docker feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
docs docs: document gateway and Android deployment 2026-08-11 03:47:51 +00:00
scripts feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
tests fix(ci): inspect service UID through procfs 2026-08-11 04:02:19 +00:00
.dockerignore feat(container): add minimal Agent Zoo runtime 2026-08-11 02:46:10 +00:00
.env.example feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
.gitignore fix(build): prepare authenticated mirror sources 2026-08-11 02:53:01 +00:00
compose.yaml feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
config.example.yaml feat(container): add minimal Agent Zoo runtime 2026-08-11 02:46:10 +00:00
Dockerfile feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00
LICENSE docs: add deployment and upstream guide 2026-08-11 02:58:10 +00:00
README.md docs: document gateway and Android deployment 2026-08-11 03:47:51 +00:00
sources.env feat(gateway): add authenticated mobile deployment 2026-08-11 03:47:44 +00:00

Agent Zoo Docker

A small container deployment for Agent Zoo and its authenticated mobile gateway. The default Compose service runs azo-gateway, which launches and resumes headless Agent Zoo sessions and transparently proxies their canonical websocket frames.

The image pins and builds four mirrored server repositories:

  • agent-zoo — session runtime and websocket backend
  • agent-utils — agent pipeline abstractions
  • tmux-pilot — local process and session coordination
  • azo-gateway — authenticated project/session API and websocket proxy required by azo-mobile

The Android application and azo-tui remain client software and are not packaged in the image. The runtime also includes git, tmux, OpenSSH, and a normal shell so coding agents can work in /workspace.

Quick start

Prerequisites:

  1. Docker Engine with Compose v2.
  2. A Codex subscription authenticated by the Codex CLI. Run codex login on the Docker host and confirm ${HOME}/.codex/auth.json exists.
cp .env.example .env
docker compose up -d
docker compose ps
docker compose logs agent-zoo

The safe default publishes the gateway only on 127.0.0.1:8787. The startup log contains its bearer token, manual base URL, pairing URI, and QR code. When AZO_GATEWAY_TOKEN is blank, the entrypoint generates a strong token once and persists it at /data/.azo-gateway/token.

Agent Zoo state and gateway databases are persisted in agent-zoo-data; coding projects are persisted in agent-zoo-workspace.

docker compose down
docker compose up -d

Recreating the service keeps both volumes and the generated gateway token.

Connect the Android app

The mirrored azo-mobile source requires the matching standalone gateway. It does not connect directly to a raw ws://HOST:8765/session endpoint.

Set the gateway's published and advertised addresses in .env:

AZO_GATEWAY_BIND_ADDRESS=0.0.0.0
AZO_GATEWAY_PORT=8787
AZO_GATEWAY_ADVERTISE_HOST=192.0.2.10

Replace 192.0.2.10 with the Docker host's LAN or VPN address, then recreate the service:

docker compose up -d --force-recreate
docker compose logs agent-zoo

Scan the logged QR code, paste the azo://gateway/connect?... pairing URI, or enter http://192.0.2.10:8787 and the bearer token manually in the app.

The gateway authenticates project, filesystem, session, and proxied websocket routes. The bearer token controls every project and session under this gateway's Agent Zoo state root. Plain HTTP still exposes traffic to the network, so use it only on a trusted LAN or VPN. Use an authenticated TLS reverse proxy for untrusted networks; do not publish the gateway directly to the internet.

Codex subscription authentication

Bundled gpt-5.5-*-codex profiles read the Codex CLI OAuth file at ~/.codex/auth.json. Compose mounts ${CODEX_HOME} there. The mount is writable because Agent Zoo may refresh an expired OAuth token and atomically update the file.

Set AGENT_ZOO_UID and AGENT_ZOO_GID in .env to the host account that owns the Codex directory. Never commit auth.json, copy it into an image, or expose it through environment variables.

config.example.yaml selects the high-reasoning Codex profile, disables direct API-key profiles, starts in interactive pace, and uses headless terminal tools. It is mounted as /data/config.yaml, where gateway-launched Agent Zoo processes discover it through the normal layered configuration loader.

Runtime user and startup customization

The image follows the Hermes Agent startup model:

  1. Docker starts the entrypoint as container root.
  2. The entrypoint maps the agent-zoo account to AGENT_ZOO_UID:AGENT_ZOO_GID and prepares /data and /workspace.
  3. gosu permanently drops privileges before the gateway or backend starts.

The defaults are 1000:1000. The smoke suite also exercises 12345:12346, checks the effective service-process UID, and verifies persistent writes as that account. This accommodates rootless Docker or Podman mappings; ownership changes that a rootless engine rejects are warnings rather than fatal errors.

For quick experiments, a Compose override can install packages before invoking the normal entrypoint:

services:
  agent-zoo:
    entrypoint: [/usr/bin/tini, -g, --, /bin/bash, -lc]
    command:
      - |
        apt-get update
        apt-get install -y --no-install-recommends jq
        rm -rf /var/lib/apt/lists/*
        exec agent-zoo-entrypoint gateway

The final exec agent-zoo-entrypoint gateway is required so UID/GID mapping and privilege dropping still occur. Runtime installations repeat after every container recreation; use a small derived Dockerfile for permanent dependencies.

Raw backend mode

Protocol clients that do not need the mobile control plane can run one raw backend session:

docker run --rm \
  -p 127.0.0.1:8765:8765 \
  -v agent-zoo-data:/data \
  -v agent-zoo-workspace:/workspace \
  code.mehalter.com/clawlter/agent-zoo-docker:dev backend

Connect to ws://127.0.0.1:8765/session. This raw protocol has no authentication; keep it on loopback, a trusted private network, or behind an authenticated proxy. The Compose gateway is the recommended mobile and multi-session deployment.

Common operations

# Follow gateway and launched-backend logs
docker compose logs -f agent-zoo

# Verify the active gateway/backend health contract
docker compose exec agent-zoo agent-zoo-healthcheck

# Update after a new main build is published
docker compose pull
docker compose up -d

One gateway manages one Agent Zoo state root and can keep multiple sessions active. Use another Compose project with different ports and volumes for an independent state root.

Build and test locally

Image builds use authenticated Forgejo mirror checkouts prepared outside Docker. If the mirrored repositories are already sibling directories, no token is needed:

AGENT_ZOO_SOURCE_ROOT=/path/to/agent-zoo-landscape ./scripts/prepare-sources.sh
docker build -t agent-zoo-docker:local .
./tests/smoke.sh agent-zoo-docker:local
AGENT_ZOO_TEST_MODE=gateway ./tests/smoke.sh agent-zoo-docker:local
AGENT_ZOO_TEST_MODE=gateway \
  AGENT_ZOO_TEST_UID=12345 AGENT_ZOO_TEST_GID=12346 \
  ./tests/smoke.sh agent-zoo-docker:local

Otherwise set FORGEJO_TOKEN to a token with mirror read access and run ./scripts/prepare-sources.sh. The script exports only pinned commits into ignored .build-sources/; credentials never enter the Docker build context or image.

The backend smoke performs a real protocol-v1 websocket hello handshake. Gateway smoke verifies unauthenticated health, authenticated API access, project creation, backend launch, a proxied websocket hello, generated-token persistence across restart, the effective non-root service UID, configuration loading, and writable persistent paths. Every run uses isolated temporary Docker resources and cleans up only its own objects.

Source updates

sources.env pins full commit IDs for agent-zoo, agent-utils, tmux-pilot, and azo-gateway. Before updating, confirm the Forgejo mirrors have synchronized and review compatibility with azo-mobile. Build and test both service modes before publication.

The mirrors synchronize every eight hours and may lag GitHub. Their configured GitHub locations require access this environment does not have, so the authenticated Forgejo mirrors are the build source. See docs/upstream-landscape.md for the full 14-repository map and source-boundary notes.

Image publication

Pull requests build and smoke-test both service modes. Pushes to main publish:

code.mehalter.com/clawlter/agent-zoo-docker:dev

Forgejo Actions uses the account-level PACKAGE_TOKEN secret for registry publication.