Container Layout
This document describes the filesystem layout of AgentVisor™ container images.
If you need to use a different Linux distribution (e.g. Chainguard/Wolfi), see Custom Base Images for the image contract and reference Dockerfiles.
Overview
The agentvisor build command creates a combined container containing:
- Host runtime with gVisor
- Guest rootfs with agent code
- Python dependencies pre-installed
┌─────────────────────────────────────────────────────────────┐
│ Combined Container │
│ │
│ /usr/local/bin/ │
│ ├── agentvisor-host-runtime # Host process (entrypoint) │
│ └── runsc # gVisor sandbox runtime │
│ │
│ /opt/guest-rootfs/ # Complete guest filesystem │
│ ├── usr/local/bin/agentvisor-guest-runtime │
│ ├── app/agent/ # Your agent code │
│ ├── app/.venv/ # Agent Python dependencies │
│ └── ... # Full Linux rootfs │
│ │
│ /var/run/agentvisor/ # Runtime state (created at startup) │
│ ├── host.sock # gRPC socket for host<->guest │
│ ├── runtime/ # gVisor state directory │
│ └── bundles/ # OCI bundles for sandboxes │
└─────────────────────────────────────────────────────────────┘
Directory Structure
Host Layer
From the agentvisor-host base image:
/
├── usr/
│ └── local/
│ └── bin/
│ ├── agentvisor-host-runtime # Main host process
│ └── runsc # gVisor runtime
│
├── var/
│ └── run/
│ └── agentvisor/ # Runtime directory
│ ├── runtime/ # gVisor state
│ └── bundles/ # OCI bundles
│
├── etc/
│ └── ssl/certs/ # CA certificates
│
└── opt/
└── guest-rootfs/ # Guest filesystem
Guest Rootfs
At /opt/guest-rootfs/:
/opt/guest-rootfs/
├── app/
│ ├── agent/ # Your agent code (fixed path)
│ │ ├── agent.py # Entry point
│ │ ├── requirements.txt # Copied
│ │ └── ... # All your source files
│ └── .venv/ # Agent Python dependencies (pip-installed)
│ └── lib/
│ └── python3.12/
│ └── site-packages/
│
├── usr/
│ ├── local/
│ │ └── bin/
│ │ └── agentvisor-guest-runtime # Guest runtime proxy
│ └── lib/
│ └── python3.12/
│ └── site-packages/ # SDK + system packages (agent deps live in /app/.venv)
│
├── bin/ # Standard Linux binaries
├── lib/ # System libraries
├── etc/
│ ├── passwd
│ ├── group
│ └── ssl/certs/ # CA certificates
│
└── var/
└── run/
└── agentvisor/ # Bind-mounted at runtime
Runtime View
When the sandbox runs, the guest sees:
Guest Filesystem (inside sandbox):
/
├── app/
│ ├── agent/ # Your agent code
│ │ └── agent.py
│ └── .venv/ # Agent Python dependencies
├── usr/local/bin/
│ └── agentvisor-guest-runtime # HTTP proxy
├── var/run/agentvisor/
│ └── host.sock # Communication with host
└── ... # Rest of rootfs
Bind Mounts
| Host Path | Guest Path | Mode | Purpose |
|---|---|---|---|
/var/run/agentvisor | /var/run/agentvisor | rw | Socket communication |
/opt/guest-rootfs | / | ro | Root filesystem |
Build Process
Step 1: Load Host Image
Input: ghcr.io/manetu/agentvisor/agentvisor-host:latest
Output: Base with host-runtime + runsc
Step 2: Extract Guest Rootfs
Input: ghcr.io/manetu/agentvisor/agentvisor-guest:latest-python
(or agentvisor-guest:latest-minimal for exec mode)
Action: Extract full rootfs
Output: /tmp/build/guest-rootfs/
Step 3: Install Dependencies
Input: requirements.txt
Action: pip install into a venv at /app/.venv (--system-site-packages,
so agent deps can see the SDK installed in the base guest image)
Output: /opt/guest-rootfs/app/.venv/ populated
Step 4: Copy Agent Code
Input: Your agent directory
Action: Copy to /app/agent/ (respecting ignore patterns)
Output: /opt/guest-rootfs/app/agent/
Step 5: Create Final Image
Input: Host base + guest rootfs
Action: Add guest as layer at /opt/guest-rootfs
Output: Tagged image
Environment Variables
Set in the combined image:
| Variable | Value | Description |
|---|---|---|
AGENTVISOR_GUEST_ROOTFS_PATH | /opt/guest-rootfs | Guest filesystem path |
AGENT_ENTRYPOINT | agent.py | Entry point, derived from langgraph.json |
AGENTVISOR_GUEST_INTERPRETER | python3.12 | Interpreter identifier |
Customizing the Layout
Entry Point
The entry point is determined from langgraph.json:
{
"graphs": {
"agent": "./src/agent.py:graph"
}
}
Project Structure
Your project structure is preserved under /app/agent/:
my-agent/ → /opt/guest-rootfs/app/agent/
├── src/ → /opt/guest-rootfs/app/agent/src/
│ ├── agent.py → /opt/guest-rootfs/app/agent/src/agent.py
│ └── tools/ → /opt/guest-rootfs/app/agent/src/tools/
├── config/ → /opt/guest-rootfs/app/agent/config/
├── langgraph.json # Graph definitions
└── requirements.txt # Installed into /opt/guest-rootfs/app/.venv during build
Ignore Patterns
AgentVisor uses a .dockerignore file (placed at the root of your agent directory) to control which files are excluded from the guest image. This follows the standard Docker .dockerignore format.
Default ignores
The following patterns are always excluded, even without a .dockerignore file:
.git/,.gitignore__pycache__/,*.pyc,.pytest_cache/.venv/,venv/.envnode_modules/agentvisor.yaml,agentvisor.yml.dockerignore(the file itself)Dockerfile
User-defined patterns
Create a .dockerignore in your agent directory to exclude additional files. Patterns are additive — they are merged with the default ignores above.
# Host-side policy files (loaded by host runtime, not needed in guest)
policies/
# Documentation
README.md
docs/
# Test fixtures
tests/
*.log
# Build artifacts
.mypy_cache/
Supported pattern syntax
| Syntax | Example | Matches |
|---|---|---|
| Wildcards | *.log | Any .log file at any depth |
| Path patterns | policies/* | Files directly inside policies/ |
| Recursive glob | **/*.log | .log files at any depth |
| Prefix glob | docs/** | Everything under docs/ |
| Combined | docs/**/*.md | .md files at any depth under docs/ |
| Comments | # comment | Ignored |
| Blank lines | Ignored |
Leading and trailing slashes are stripped (/policies/ is treated as policies).
Negation patterns (!important.log) are not currently supported and will be ignored with a warning.
Inspecting Images
View Layers
docker history my-agent:v1
Explore Filesystem
# Create temporary container
docker create --name temp my-agent:v1
# List guest rootfs
docker export temp | tar -tf - | grep opt/guest-rootfs | head -50
# Extract specific file
docker export temp | tar -xOf - opt/guest-rootfs/app/agent/agent.py
# Cleanup
docker rm temp
Check Environment
docker inspect my-agent:v1 --format '{{json .Config.Env}}' | jq
Troubleshooting
Missing Dependencies
# Check installed packages (override the entrypoint, which is the host-runtime)
docker run --rm --entrypoint ls my-agent:v1 \
/opt/guest-rootfs/app/.venv/lib/python3.12/site-packages/
Missing Files
- Check
.dockerignorepatterns - Verify file exists in source directory
- Check file permissions
Wrong Entry Point
# Check environment
docker inspect my-agent:v1 --format '{{range .Config.Env}}{{println .}}{{end}}' | grep AGENT