Docker Image¶
The pre-built image¶
flaude ships a Docker image pre-configured for Claude Code execution:
The image includes:
- Claude Code — the CLI, pre-installed and ready to run
- git — for cloning repositories on machine startup
- gh CLI — the GitHub CLI, useful when Claude Code needs to create issues or PRs
- jq — JSON processor, useful for scripting
- entrypoint.sh — flaude's startup script that configures credentials and clones repos
This image is the default for all MachineConfig instances. You do not need Docker
installed locally to use it.
Building and pushing the image¶
If you want to push your own copy of the image (for example, to a different Fly app), use
ensure_image:
from flaude import ensure_image
async def build_and_push(app_name: str) -> None:
image = await ensure_image(app_name)
print(f"Image ready: {image}")
ensure_image runs three steps in sequence:
docker_build— builds the image and tags it asregistry.fly.io/<app_name>:latestdocker_login_fly— authenticates Docker with Fly's container registrydocker_push— pushes the image toregistry.fly.io
Building and pushing separately¶
from flaude import docker_build, docker_login_fly, docker_push
async def build_separately(app_name: str) -> None:
# Build the image
image = await docker_build(app_name)
print(f"Built: {image}")
# Authenticate (requires FLY_API_TOKEN in environment)
await docker_login_fly()
# Push to Fly registry
pushed = await docker_push(app_name)
print(f"Pushed: {pushed}")
Note
docker_build and docker_push require Docker to be installed and running locally.
docker_login_fly requires flyctl to be installed.
Customizing the image¶
You would customize the image when you need to:
- Install additional system packages (e.g.
libpq-devfor PostgreSQL tools) - Change the Node.js version (Claude Code is Node-based)
- Pre-install project-specific tools or language runtimes to reduce startup time
- Add custom entrypoint logic before repos are cloned
To customize, edit the Dockerfile in the flaude/ directory of the project, then build
and push your customized image:
from pathlib import Path
from flaude import ensure_image
async def push_custom_image(app_name: str) -> None:
# Point to your customized Dockerfile directory
image = await ensure_image(
app_name,
docker_context=Path("./my-custom-flaude"),
)
print(f"Custom image ready: {image}")
Then reference your custom image in MachineConfig:
from flaude import MachineConfig
config = MachineConfig(
image=f"registry.fly.io/{app_name}:latest",
claude_code_oauth_token="sk-ant-oat-...",
prompt="...",
repos=["..."],
)
Tip
Keep customizations minimal. The pre-built image is kept lean so machines start quickly. Adding large packages or runtimes increases VM cold-start time.