Skip to content

Config reference (ffleet.toml)

Every ffleet.toml setting. This file is a per-project, personal dev-tool preference — not team config. ffleet init writes it by default under ~/.forge-fleet/{project-id}/ffleet.toml ("home mode"), so nothing needs to be committed into the repo it configures. In-repo ("local mode") is supported as an explicit opt-in.

Most CLI flags mirror a key here; where they overlap the flag wins for that run (see config precedence). The canonical, fully-commented template is ffleet.toml.example at the repo root.

What init sets, and everything else

ffleet init runs a short wizard for the settings most worth choosing up front — the default coding agent, the base image (python or go variant), the git mode, and whether sandboxes get host Docker access (DooD). Each question is pre-selected at its default, so pressing enter through them keeps today's behavior; your choices are written as active keys. Every other setting is written commented-out at its default, so the generated file doubles as a menu — uncomment and edit what you need.

init -y accepts every default without prompting. Non-default values for any other setting are configured by editing the generated ffleet.toml.

init is create-only: it never overwrites an existing config. To change settings later, edit the ffleet.toml directlyinit prints its path when it writes it, and re-running init on a configured project just points you back at that file.

Global keys

Key Type Default Meaning
project_name string — (required) Logical project name; used to name containers and worktrees.
source_dir string Absolute path to the source repo. Required in home mode; in local mode it's derived from where this file lives (set it only if the file isn't colocated with the repo).
worktree_root string — (required) Where per-environment worktrees are created (absolute, or relative to the repo root). Inside the checkout (e.g. .forge-fleet/worktrees) or a separate folder under $HOME.
image string ghcr.io/grzegorz-aniol/forge-fleet-python:latest Docker image the agent container runs. Use ghcr.io/grzegorz-aniol/forge-fleet-go:latest for the Go-dev variant.
git_mode string auto Git integration: auto | off | worktree | clone. off needs no git repo — ffleet up then runs in-place over the project root (no worktree, no --here). See git modes.
git_local_main bool false Base the worktree on the local main branch and keep completion local-only (no push/PR).
docker_host_bind bool false Let the agent inside the container drive the host Docker daemon (binds the host docker socket; agent-started containers become siblings). See DooD.
uv_cache_dir string ~/.cache/uv Shared uv cache mounted into the container for faster installs.
extra_mounts list Extra bind mounts as source:target[:ro\|:rw]. Target must be an absolute container path; a relative source resolves against the repo root; ~ expands to the host home. An optional :ro/:rw suffix sets the mode (default read-write).
extra_hosts list — (may be omitted) Host-to-address mappings passed to docker run --add-host, each host:address. host-gateway resolves to the host itself.
docker_env_file string Additional env file passed to docker run --env-file (runtime secrets/keys). A relative path resolves against this config file's own directory.
copy_files list Gitignored files to snapshot from the main repo into each new worktree (globs allowed), so e.g. .env appears at the same relative path inside. One-time copy at creation, not a live link.
default string Which coding-agent ffleet up runs when none is named on the CLI. Must be one of the [section] names below (e.g. claude, codex).
pm string github Issue tracker for -t templates: github (via gh CLI) | linear (needs LINEAR_API_KEY) | none (don't fetch; raw ref exposed as {id}). On any fetch failure ffleet warns and continues as pm=none.
check_image_period_days int or "off" 30 How often ffleet up checks whether a newer image exists in the registry (see image freshness check). Any positive integer sets the period in days; "off" disables the check entirely.

Image freshness check (check_image_period_days)

Whenever ffleet up actually builds or (re)starts a container, and at least check_image_period_days have elapsed since the last check for this project, it does a best-effort comparison of the configured image against its remote counterpart. It compares two registry manifests: the one the tag resolves to right now, and the one behind the digest the local copy was pulled under. They differ only when the tag has actually moved, so the answer doesn't depend on which image store (classic or containerd) your Docker daemon uses:

  • Interactive session — if a newer image is found, ffleet prompts before pulling and pulls only on explicit approval, then starts the container from the freshly pulled image. The pull reports Docker's own outcome, so you can see whether anything was downloaded or the local copy was already current.
  • ffleet up -y / --yes — warn-only: ffleet prints a notice that a newer image exists but never prompts and never pulls. Pull it yourself with docker pull <image> (or run ffleet up interactively).

The check never blocks or fails ffleet up: if the registry is unreachable, or the image was built locally and so has no registry digest to compare, ffleet silently skips the comparison and starts the container as usual. The last-check timestamp is stored per project in ~/.forge-fleet/registry.json (not in ffleet.toml), so a project that was never checked is treated as due on its next up. Set check_image_period_days = "off" to disable the whole flow.

[git] — identity injected into the container

Both keys must be set together; otherwise identity resolves from host git config.

Key Type Meaning
user_name string Git author/committer name inside the container.
user_email string Git author/committer email inside the container.

[claude] / [codex] — per-coding-agent config

Key Type Default Meaning
dir string ~/.claude / ~/.codex Host directory mounted as the agent's config/credentials, so it's authenticated inside the container.
auth string auto (Claude) Credential source ffleet injects. See the table below.
cmd string the section name Override the binary invoked in the container (e.g. claude).
extra_args list Flags appended to the agent's launch command, after ffleet's own flags (e.g. ["--agent", "myagent"]).

[claude].auth values

Value Behaviour
auto Try keychain, then token, then api-key, then credentials-file; first available wins (default).
keychain macOS only; pin the Keychain-derived credential (fails fast if the lookup fails).
token Pin CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token).
api-key Pin ANTHROPIC_API_KEY (API billing, not subscription).
credentials-file Pin the ~/.claude mount's .credentials.json (Linux only).
external Skip the auth preflight entirely — you provide credentials another way (e.g. docker_env_file).

See container configuration for how these mounts and credentials fit together.

[templates.<id>] — prompt templates

Looked up by ffleet up -t <id> <ref>: ffleet fetches issue <ref> from the configured pm source, derives the slug from the issue title, and renders prompt_template with the issue's fields.

Key Type Meaning
prompt_template string Template rendered with {number}, {title}, {body}, {url}, {id} (raw ref), plus any extra key=value tokens passed on the CLI.
subagent string Optional subagent for envs seeded from this template. Translated to the agent's own subagent flag (Claude only: --agent <name>; using it with another agent errors). The up --subagent NAME flag is the per-invocation, template-independent equivalent and overrides this key when both are set — see starting.

Full walkthrough: advanced/templates.md.

Environment variables and dotenv

Most ffleet.toml keys have an environment-variable equivalent, and Forge Fleet also loads a dotenv file from the current working directory if present. An env var (or dotenv entry) overrides the matching ffleet.toml key; a CLI flag overrides both (see config precedence).

Dotenv discovery order in the current working directory (only the first existing file is loaded):

  1. .env.forge-fleet
  2. .forge-fleet/.env

Env var mapping:

Identity (project_name, source_dir, worktree_root) is config-only: it is read straight from ffleet.toml and has no env-var or CLI-flag override. Run ffleet init to create the config; without it, the env commands fail with a no ffleet config found — run 'ffleet init' error.

Env var Maps to
SLUG slug positional argument
IMAGE_NAME --image
CODING_AGENT --coding-agent (on up; set only when first creating an env). The legacy AGENT / --agent names still work, each with a one-time deprecation notice.
CLAUDE_DIR --claude-dir
CLAUDE_AUTH --claude-auth (auto, keychain, token, api-key, credentials-file, external)
CODEX_DIR --codex-dir
UV_CACHE_DIR --uv-cache-dir
EXTRA_MOUNTS --extra-mounts (source:target,source:target)
EXTRA_HOSTS --extra-hosts (host:address,host:address; each becomes a docker run --add-host, e.g. host.docker.internal:host-gateway)
DOCKER_ENV_FILE --docker-env-file
GIT_MODE --git-mode (auto, off, worktree, clone)
GIT_LOCAL_MAIN local-branch mode when first creating an env (true/false)
DOCKER_HOST_BIND --docker-host-bind (true/false)
FORGE_FLEET_GIT_USER_NAME explicit git identity name override
FORGE_FLEET_GIT_USER_EMAIL explicit git identity email override
LINEAR_API_KEY Linear personal API key, read directly when pm = "linear"; no CLI flag equivalent

Example .env.forge-fleet:

IMAGE_NAME=forge-fleet:latest
CODING_AGENT=claude
CLAUDE_DIR=~/.claude
CODEX_DIR=~/.codex
UV_CACHE_DIR=~/.cache/uv
EXTRA_MOUNTS=~/.agents:/home/buddy/.agents,~/.ssh:/home/buddy/.ssh:ro
DOCKER_ENV_FILE=/path/to/docker.env
GIT_MODE=auto
DOCKER_HOST_BIND=false
FORGE_FLEET_GIT_USER_NAME=Jane Developer
FORGE_FLEET_GIT_USER_EMAIL=jane@example.com
# Only needed when pm = "linear":
LINEAR_API_KEY=lin_api_xxxxxxxx

EXTRA_MOUNTS format rules:

  • comma-separated entries: <source>:<target>[:ro|:rw]
  • source supports ~ expansion
  • relative source is resolved from the current working directory
  • target must be an absolute container path (start with /)
  • an optional trailing :ro or :rw sets the mount mode (default is read-write); any other trailing segment is rejected
  • entries are bind-mounted as -v <source>:<target> (read-write) or -v <source>:<target>:ro (read-only)
  • if an extra mount uses the same target as an existing mount, the later extra mount can shadow the earlier one

Config discovery order

For a given directory, Forge Fleet locates the ffleet.toml to use in this order:

  1. an explicit config path (FFLEET_CONFIG env var)
  2. an explicit project config dir (FFLEET_PROJECT_DIR env var)
  3. the ~/.forge-fleet/registry.json lookup by the directory's project id
  4. legacy in-repo search: ffleet.toml, then .forge-fleet/ffleet.toml

The project id is derived from git structure — the main checkout's git rev-parse --git-common-dir plus its origin remote, or a path hash when there is no remote — never from the current directory's name. That's why every worktree of a project resolves to the same config.