Skip to main content
Every Autonomy application follows this structure:
File Structure:
my-app/
|-- autonomy.yaml         # Zone configuration
|-- images/               # Container images
    |-- main/             # Main container image
    |   |-- Dockerfile    # Instructions to build the image
    |   |-- main.py       # Application entry point
    |
    |-- ...               # More images

autonomy.yaml

This configuration file defines a zone in your cluster in the Autonomy Computer. Think of a zone as your app’s dedicated infrastructure. The Autonomy Computer provisions everything needed to run it.
autonomy.yaml
name: hello
pods:
  - name: main-pod
    public: true
    containers:
      - name: main
        image: main
  • name: hello - The zone’s name (must be ≤ 10 characters, using only a to z or 0 to 9).
  • pods - List of pods to create in this zone (a pod is a group of containers that run together).
  • public: true - Serve the HTTP server on port 8000 of this pod on a public address over HTTPS.
  • containers - List of containers in the main-pod.
  • image: main - Create the main container using the image defined in images/main.

Environment variables and secrets

You can set environment variables in your containers:
autonomy.yaml
name: myapp
pods:
  - name: main-pod
    public: true
    containers:
      - name: main
        image: main
        env:
          - LOG_LEVEL: "INFO"
          - API_KEY: secrets.API_KEY
Create secrets.yaml for sensitive values:
secrets.yaml
API_KEY: sk-abc123xyz
Add secrets.yaml to .gitignore to keep it out of version control.

Multiple containers

Add multiple containers to a pod for tools agents need:
autonomy.yaml
name: myapp
pods:
  - name: main-pod
    public: true
    containers:
      - name: main
        image: main
      
      - name: mcp
        image: ghcr.io/build-trust/mcp-proxy
        env:
          - BRAVE_API_KEY: secrets.BRAVE_API_KEY
        args: ["--sse-port", "8001", "--pass-environment", "--",
               "npx", "-y", "@modelcontextprotocol/server-brave-search"]
Containers in the same pod:
  • Share the same network namespace.
  • Can communicate via localhost.
This pattern works for:
  • MCP servers (Model Context Protocol tools).
  • Python functions, simple binaries, or any TCP service your agents need.
  • Creating private links to enterprise data sources.

Multiple pods

Split your application across pods:
autonomy.yaml
name: myapp
pods:
  - name: main-pod
    public: true
    containers:
      - name: main
        image: main

  - name: runner-pod
    clones: 5
    containers:
      - name: runner
        image: runner
Use clones to run multiple copies of a pod for parallel processing.

Dockerfile

Autonomy provides two base images (both include the Autonomy Framework pre-installed):
  • Development variant (ghcr.io/build-trust/autonomy-python-dev) - Contains pip, uv, and apk package managers plus bash, ash, and sh shells.
  • Minimal variant (ghcr.io/build-trust/autonomy-python) - Removes shells and package managers for additional security and reduced size.
In simple Dockerfiles uses the minimal base image:
images/main/Dockerfile
FROM ghcr.io/build-trust/autonomy-python
COPY . .
ENTRYPOINT ["python", "main.py"]

Python dependencies

Use multi-stage builds to install packages using pip and requirements.txt:
images/main/Dockerfile
FROM ghcr.io/build-trust/autonomy-python-dev AS dev
COPY requirements.txt ./
RUN pip install -r requirements.txt

FROM ghcr.io/build-trust/autonomy-python
COPY --from=dev /app/venv venv
COPY . .
ENTRYPOINT ["python", "main.py"]
Create requirements.txt:
images/main/requirements.txt
httpx
markitdown
Or use uv with pyproject.toml:
images/main/Dockerfile
FROM ghcr.io/build-trust/autonomy-python-dev AS dev
COPY pyproject.toml ./
RUN uv pip install -r pyproject.toml

FROM ghcr.io/build-trust/autonomy-python
COPY --from=dev /app/venv venv
COPY . .
ENTRYPOINT ["python", "main.py"]
Create pyproject.toml:
images/main/pyproject.toml
[project]
name = "my-app"
version = "0.1.0"
dependencies = [
    "httpx",
    "markitdown",
]

System dependencies

For system packages like ffmpeg, use the development image as your base:
images/main/Dockerfile
FROM ghcr.io/build-trust/autonomy-python-dev

# Install system packages with apk (as root)
USER root
RUN apk add --no-cache ffmpeg
USER nonroot

# Install Python packages
COPY requirements.txt ./
RUN pip install -r requirements.txt

COPY . .
ENTRYPOINT ["python", "main.py"]
When you need system shared libraries, use ghcr.io/build-trust/autonomy-python-dev as your base image.

main.py

The entrypoint to your application:

One module

For a simple application with a single file:
images/main/main.py
from autonomy import Agent, Model, Node

async def main(node):
  await Agent.start(
    node=node,
    name="henry",
    instructions="You are Henry, an expert legal assistant",
    model=Model("claude-sonnet-4-v1")
  )

Node.start(main)
This Python module:
  1. Imports modules from the Autonomy Framework which provides Agent, Model, and Node.
  2. Defines an async main function that:
    • Starts an agent named “henry”.
    • Gives it instructions to act as a legal assistant.
    • Configures it to use Claude Sonnet 4 model.
  3. Starts an Autonomy Node - This creates the actor runtime that hosts your agent and invokes the main function. It also starts an HTTP server on port 8000 with a set of built-in APIs to interact with your agent.

Multiple modules

For larger applications, organize code into multiple modules:
images/main/
|-- Dockerfile
|-- main.py
|-- accounts/
    |-- __init__.py
    |-- balance_inquiry.py
    |-- statements.py
|-- transactions/
    |-- __init__.py
    |-- history.py
    |-- categorization.py
|-- budgeting/
    |-- __init__.py
    |-- analysis.py
    |-- recommendations.py
|-- investments/
    |-- __init__.py
    |-- portfolio.py
    |-- performance.py
Entry point:
images/main/main.py
from autonomy import Agent, Model, Node
from accounts.balance_inquiry import get_balance
from transactions.history import get_transactions

async def main(node):
  await Agent.start(
    node=node,
    name="finn",
    instructions="You are Finn, a personal financial assistant",
    model=Model("claude-sonnet-4-v1"),
    tools=[get_balance, get_transactions]
  )

Node.start(main)
This structure helps you:
  • Separate concerns.
  • Reuse code.
  • Test components independently.
  • Keep you code easy to manage as your application grows.