-
Notifications
You must be signed in to change notification settings - Fork 0
container config
Each environment is a Docker container that Forge Fleet assembles from your
ffleet.toml and flags. This page explains the pieces so you can tune them.
image (or --image) selects the Docker image the agent runs in. Default:
ghcr.io/grzegorz-aniol/forge-fleet-python:latest (pulled from GHCR on first
use — no local build required). A Go-dev variant
(ghcr.io/grzegorz-aniol/forge-fleet-go:latest, also published to GHCR) overlays
a Go toolchain for developing the Go port. Pick or build an image that carries the
language runtimes and tools your project needs — the agent can only use what's in
the image (plus what it installs at runtime).
Because image is a config-derived setting, you can change it and pick it up on
the next revive: ffleet stop SLUG then ffleet up SLUG (see
what can change mid-life).
The two default images are built and pushed to GHCR from the public
ffleet-dist repo (its
publish-images workflow), where the Dockerfiles live:
-
ghcr.io/grzegorz-aniol/forge-fleet-python:latest— the base image (Debian bookworm-slim). It carries the agent toolbox: the Claude Code and Codex CLIs, Python 3 + uv, Node 22 (with corepack for pnpm/yarn), plusgit,gh(GitHub CLI), thedockerCLI (client only, for DooD),tmux,jq,make, and a C build toolchain. -
ghcr.io/grzegorz-aniol/forge-fleet-go:latest— a superset overlay of the base that adds the Go toolchain (for developing the Go port); the rest of the toolbox is identical.
Both run as a non-root user buddy (uid/gid 1000) with home
/home/buddy, and /workspace is owned by buddy. That is why credential and
cache mounts land under /home/buddy/... (e.g. ~/.claude →
/home/buddy/.claude), why extra_mounts into the container home use that
path, and why host Docker access adds buddy to the host docker group so it
can reach the socket (see DooD). If you build a custom image,
matching the buddy uid/gid 1000 keeps mounted-file ownership aligned with
your host user.
Several things get mounted into the container:
-
The workspace — the git worktree (or, in
--here/offmode, your current directory) is mounted at/workspace. This is where the agent does its work. -
uv_cache_dir— a shared uv cache (default~/.cache/uv) for faster Python installs across environments. -
extra_mounts— your own bind mounts,source:target[:ro|:rw](the only accepted modes areroandrw, default read-write); target is an absolute container path, a relative source resolves against the repo root,~expands to the host home. Use these for shared caches, SSH keys, etc. See secrets for when to mount vs. copy vs. env-file.
The agent must be logged in inside the container. Forge Fleet handles this by mounting the agent's host credential/config directory:
-
Claude Code —
[claude].dir(default~/.claude), plus a credentialauthsource (auto/keychain/token/api-key/credentials-file/external) that decides which credential ffleet injects. See the[claude].authtable. -
Codex —
[codex].dir(default~/.codex).
Override the mounts per run with --claude-dir / --codex-dir, and the Claude
source with --claude-auth. The upshot: because your host login is mounted in,
you don't re-authenticate per environment.
extra_hosts maps hostnames to addresses via docker run --add-host, letting
processes inside resolve names to the host or to arbitrary addresses. Each entry
is host:address; the special value host-gateway resolves to the host itself —
handy for reaching a service running on your machine:
extra_hosts = ["host.docker.internal:host-gateway"]docker_host_bind = true (or --docker-host-bind) binds the host Docker socket
so the agent can drive the host daemon — this is the Docker-outside-Docker setup;
see DooD.
Commits made inside the container use the [git] identity (user_name /
user_email) if both are set; otherwise identity falls back to your host git
config. Set both together or neither.
image = "ghcr.io/grzegorz-aniol/forge-fleet-python:latest"
uv_cache_dir = "~/.cache/uv"
extra_mounts = ["~/.ssh:/home/buddy/.ssh"]
extra_hosts = ["host.docker.internal:host-gateway"]
[claude]
dir = "~/.claude"
# auth = "auto"
[git]
user_name = "Jane Developer"
user_email = "jane@example.com"