Deploying Your Agent
You've been using agentvisor serve throughout this tutorial for local development. Now let's build a production image and deploy it with AgentVisor™.
What You'll Learn
- Building a production image with
agentvisor build - Running and deploying the built image
- Managing environment variables in production
Overview
AgentVisor has two deployment form factors:
| Form Factor | Command | Use Case |
|---|---|---|
| Development | agentvisor serve | Local iteration, testing, debugging |
| Production | agentvisor build → deploy | Kubernetes, docker-compose, cloud |
Building Your Image
Build a self-contained Docker image with agentvisor build:
# Build the image
agentvisor build ./my-agent -t my-agent:v1
The built image includes:
- Host runtime with gVisor sandbox
- Guest base image with Python
- Your agent code and dependencies
Push directly to a registry:
agentvisor build ./my-agent -t myregistry/my-agent:v1 --push
Deploying
When running with agentvisor serve earlier in this tutorial, the default localhost:7233 worked because the process ran directly in your shell. Inside a docker run container, localhost refers to the container itself — not your host. You need to point it at the Temporal instance running on your host instead:
- macOS / Windows (Docker Desktop):
host.docker.internal:7233 - Linux: your host's bridge IP, e.g.
172.17.0.1:7233
Built images require a valid Manetu license key at runtime. Set AGENTVISOR_LICENSE_KEY via -e or a secrets manager. See the Licensing guide for container patterns (Docker Compose, Kubernetes Secrets) and https://manetu.com/agentvisor to obtain a key.
The built image runs like any Docker container:
docker run --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
-e AGENTVISOR_LICENSE_KEY="${AGENTVISOR_LICENSE_KEY}" \
-e AGENTVISOR_TEMPORAL_TARGET=host.docker.internal:7233 \
-v $(pwd)/policies:/etc/agentvisor/policies:ro \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/etc/agentvisor/policies/domain.yml \
my-agent:v1
--security-opt seccomp=unconfined --security-opt apparmor=unconfined?AgentVisor uses gVisor internally to sandbox the AI agent process. gVisor's rootless mode creates a user namespace via CLONE_NEWUSER, which two host mechanisms can block:
- seccomp: Docker's default
RuntimeDefaultprofile may block the syscall - AppArmor: Ubuntu 24.04+ and many cloud Kubernetes distributions (GKE, AKS) enforce AppArmor policies that restrict unprivileged user namespaces by default
Both flags allow that syscall without granting any other elevated privileges.
Policy files are not bundled into the built image — they must be provided at runtime via volume mounts as shown above. During development with agentvisor serve, policies are automatically discovered from your local filesystem, but production images require explicit configuration.
See Docker Deployment and Kubernetes Deployment for complete deployment configurations including compose files, Kubernetes manifests, and privilege mode options.
Environment Variables in Production
When you build with agentvisor build, .env files are automatically excluded from the image — this prevents accidentally baking secrets into container images.
In the sandboxed environment, agent processes do not inherit host environment variables. You must explicitly provide them through one of these methods:
Mount a .env file at runtime:
docker run --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
-e AGENTVISOR_TEMPORAL_TARGET=host.docker.internal:7233 \
-v /path/to/secrets.env:/etc/agentvisor/secrets.env:ro \
-e AGENTVISOR_GUEST_ENVIRONMENT_FILES=/etc/agentvisor/secrets.env \
my-agent:v1
For API keys, AgentVisor offers Credential Brokering — a more secure approach where real credentials never enter the sandbox. The agent only sees symbolic tokens, and the host substitutes real credentials on outbound requests.
See Environment Configuration for the full reference including multiple env files, file format, and security best practices.
Runtime Configuration in Production
In development, agentvisor serve automatically discovers agentvisor.yaml and policy files from your local filesystem (see Configuring AgentVisor for search paths). In production, you need to provide these explicitly.
Mount both your config file and policies into the container:
docker run --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
-e AGENTVISOR_TEMPORAL_TARGET=host.docker.internal:7233 \
-v $(pwd)/agentvisor.yaml:/etc/agentvisor/agentvisor.yaml:ro \
-v $(pwd)/policies:/etc/agentvisor/policies:ro \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/etc/agentvisor/policies/domain.yml \
my-agent:v1
The default search path picks up /etc/agentvisor/agentvisor.yaml automatically, so no extra environment variable is needed for the config file. You can also override any config file setting with environment variables — they always take precedence.
As an alternative to mounting policy files, you can use an HTTP PDP (Policy Decision Point) for centralized policy management:
docker run --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
-e AGENTVISOR_TEMPORAL_TARGET=host.docker.internal:7233 \
-v $(pwd)/agentvisor.yaml:/etc/agentvisor/agentvisor.yaml:ro \
-e AGENTVISOR_AUTHZ_TYPE=http \
-e AGENTVISOR_AUTHZ_HTTP_URL=http://policy-engine:8080 \
my-agent:v1
Next Steps
You've completed the Tutorial! Continue exploring:
- Production Deployment for the full hardening checklist including security, monitoring, and high availability
- Sandbox Modes — Docker and gVisor isolation, choosing the right mode
- Concepts — Architecture, sandboxing, policy enforcement
- Guides — LangGraph agents, human-in-the-loop, streaming
- Examples — Real-world agent patterns from basic to advanced
- CLI Reference — Full
agentvisor buildoptions