Setting Up an Agent
This guide walks you through configuring a fully functional Agent — from choosing your AI model to enabling persistence, skills, and context. By the end, you'll have a production-ready Agent running on Kubernetes.
Make sure KubeOpenCode is installed on your cluster. See Getting Started for installation instructions.
Overview
An Agent in KubeOpenCode is a persistent, running AI service on Kubernetes. Configuring one involves:
- Model & Provider — Which AI model powers the agent (most important)
- Images — The runtime environment (init container + executor)
- Workspace — Where the agent works
- Features — Persistence, standby, skills, context, and more
Step 1: Configure the AI Model
This is the most critical step. KubeOpenCode runs OpenCode under the hood, so model configuration follows the OpenCode config format. You provide this via the Agent's config field as an inline YAML object.
Minimal Configuration
apiVersion: kubeopencode.io/v1alpha1
kind: Agent
metadata:
name: my-agent
spec:
workspaceDir: /workspace
serviceAccountName: kubeopencode-agent
config:
$schema: https://opencode.ai/config.json
model: anthropic/claude-sonnet-4-5
small_model: anthropic/claude-haiku-4-5
The config field is serialized to a config file inside the container. The OPENCODE_CONFIG environment variable is set automatically — you don't need to do anything else.
Model Format
Models use the format provider/model-id:
| Provider | Example Model ID | API Key Env Var |
|---|---|---|
| Anthropic | anthropic/claude-sonnet-4-5 | ANTHROPIC_API_KEY |
google/gemini-2.5-pro | GOOGLE_API_KEY | |
| OpenAI | openai/gpt-5.1-codex | OPENAI_API_KEY |
| DeepSeek | deepseek/deepseek-chat | DEEPSEEK_API_KEY |
| OpenCode Zen (free) | opencode/big-pickle | (none required) |
For the full list of 75+ supported providers, see the OpenCode Providers documentation.
For model selection and configuration options, see the OpenCode Models documentation.
Providing API Keys
Most providers require an API key. Use the credentials field to mount a Kubernetes Secret as environment variables:
apiVersion: v1
kind: Secret
metadata:
name: ai-credentials
namespace: test
type: Opaque
stringData:
ANTHROPIC_API_KEY: "sk-ant-xxxxx"
---
apiVersion: kubeopencode.io/v1alpha1
kind: Agent
metadata:
name: my-agent
spec:
workspaceDir: /workspace
serviceAccountName: kubeopencode-agent
config:
$schema: https://opencode.ai/config.json
model: anthropic/claude-sonnet-4-5
small_model: anthropic/claude-haiku-4-5
credentials:
- name: anthropic
secretRef:
name: ai-credentials
When no key or mountPath is specified, all keys in the Secret are injected as environment variables. This is the simplest way to provide API keys.
Advanced Config Options
The config field supports the full OpenCode configuration schema. Common options:
config:
$schema: https://opencode.ai/config.json
model: anthropic/claude-sonnet-4-5
small_model: anthropic/claude-haiku-4-5
share: disabled
autoupdate: false
provider:
anthropic:
options:
baseURL: https://your-proxy.example.com/v1
For full configuration reference, see the OpenCode Config documentation.
Step 2: Choose Your Images
KubeOpenCode uses a two-container pattern:
| Container | Field | Role |
|---|---|---|
| Init Container | agentImage | Contains the OpenCode CLI binary; copies it to a shared /tools volume at startup |
| Worker Container | executorImage | Your development environment — runs the AI agent using /tools/opencode |
At pod startup, the init container copies the OpenCode binary from agentImage to the shared /tools volume. The worker container (executorImage) then uses /tools/opencode to run the AI agent. This separation means you can update OpenCode independently from your development environment.
Available Images
| Image | Type | Description |
|---|---|---|
opencode | Init Container | OpenCode CLI binary |
devbox | Worker (Executor) | Universal development environment with Go, Node.js, Python, kubectl, helm |
attach | Task Pod (agentRef) | Lightweight image for --attach mode |
echo | Testing | Minimal Alpine image for E2E testing |
Default Images
If you don't specify images, KubeOpenCode uses these defaults:
- OpenCode init:
ghcr.io/kubeopencode/kubeopencode-agent-opencode:latest - Devbox executor:
ghcr.io/kubeopencode/kubeopencode-agent-devbox:latest - Attach:
ghcr.io/kubeopencode/kubeopencode-agent-attach:latest
For most users, the defaults work out of the box — you don't need to set agentImage or executorImage.
Image Resolution
When configuring an Agent, the controller resolves images as follows:
| Configuration | Init Container | Worker Container | Task Pod (agentRef) |
|---|---|---|---|
| All three images set | agentImage | executorImage | attachImage |
agentImage + executorImage | agentImage | executorImage | Default attach image |
Only agentImage set (legacy) | Default OpenCode image | agentImage | Default attach image |
| Neither set | Default OpenCode image | Default devbox image | Default attach image |
Attach Image
The attachImage field specifies the lightweight image used for Task Pods when running tasks via agentRef (connecting to a persistent Agent). This image contains only the OpenCode CLI binary and is used for the opencode run --attach command:
spec:
attachImage: ghcr.io/kubeopencode/kubeopencode-agent-attach:latest
If not specified, the default attach image is used.
System Containers and Extra Environment Variables
The podSpec field supports adding system container overrides and extra environment variables. This is useful for:
- OpenShift SCC compatibility: Override
HOMEforgit-initcontainers that need a writable home directory - Private npm registries: Inject authentication tokens into all containers
- Corporate CA bundles: Mount certificates into specific init containers
spec:
podSpec:
# Extra env vars injected into ALL containers (init + worker)
extraEnv:
- name: NODE_OPTIONS
value: "--max-old-space-size=4096"
# Per-container-type overrides for system containers
systemContainers:
gitInit:
extraEnv:
- name: HOME
value: /tmp
gitSync:
extraEnv:
- name: HOME
value: /tmp
extraVolumeMounts:
- name: corp-ca
mountPath: /etc/ssl/corp
readOnly: true
The systemContainers field has keys for each container type:
openCodeInit— Copies the OpenCode binary to/toolscontextInit— Copies ConfigMap content into the workspacegitInit— Clones Git repositories (allgit-init-*containers)gitSync— Periodically syncs Git repos (HotReload sidecars)pluginInit— Installs OpenCode plugins via npm
See Pod Configuration for detailed examples.
Custom Executor Images
The default devbox image includes Go, Node.js, and Python. If your project needs a different runtime (Rust, Java, Ruby, etc.), build a custom executor image:
FROM ghcr.io/kubeopencode/kubeopencode-agent-devbox:latest
# Add your language runtime
RUN apt-get update && apt-get install -y \
rustc cargo
# Add project-specific tools
RUN pip install your-framework
Then reference it in your Agent:
spec:
executorImage: your-registry.example.com/custom-devbox:v1.0
Building Agent Images
For local development (Kind clusters):
# Build OpenCode init container
make agent-build AGENT=opencode
# Build executor containers
make agent-build AGENT=devbox
# Customize registry and version
make agent-build AGENT=devbox IMG_REGISTRY=docker.io IMG_ORG=myorg VERSION=v1.0.0
For remote/production clusters (OpenShift, EKS, GKE, etc.):
# Multi-arch build and push
make agent-buildx AGENT=opencode
make agent-buildx AGENT=devbox
For detailed guidance on building custom agent images, see the Agent Developer Guide.
Step 3: Set the Workspace Directory
The workspaceDir field defines where the agent works inside the container. This is where code gets cloned, files get created, and the agent does its work.
spec:
workspaceDir: /workspace
Relationship with Context: When you add Git contexts, they are cloned into subdirectories of workspaceDir. For example, a Git context with mountPath: my-repo will be available at /workspace/my-repo.
Relationship with Persistence: If you enable workspace persistence, the workspaceDir is backed by a PersistentVolumeClaim. Files in this directory survive pod restarts.
Step 4: Enable Agent Features
With model, images, and workspace configured, your Agent is ready to run. The following features are optional but highly recommended for production use.
Persistence
By default, Agent pods use ephemeral storage (EmptyDir) — everything is lost on restart. Enable persistence to preserve:
- Sessions — Conversation history (OpenCode's SQLite database)
- Workspace — Cloned repos, generated files, build artifacts
spec:
persistence:
sessions:
size: "1Gi" # Conversation history survives restarts
workspace:
size: "10Gi" # Workspace files survive restarts
Both fields are optional — you can persist sessions only, workspace only, or both. The controller automatically creates a PersistentVolumeClaim (PVC) for each, using your cluster's default StorageClass. To use a specific StorageClass, set storageClassName:
spec:
persistence:
workspace:
storageClassName: "fast-ssd"
size: "10Gi"
See Persistence & Lifecycle for the full explanation of how Kubernetes storage works with KubeOpenCode.
Standby (Auto Suspend/Resume)
Save cluster resources by automatically suspending idle Agents:
spec:
standby:
idleTimeout: "30m" # Suspend after 30 minutes with no active Tasks
When a new Task arrives, the Agent resumes automatically. Active web terminal or CLI sessions prevent auto-suspend.
You can also manually suspend/resume an Agent:
# Suspend
kubectl patch agent my-agent --type merge -p '{"spec":{"suspend":true}}'
# Resume
kubectl patch agent my-agent --type merge -p '{"spec":{"suspend":false}}'
See Persistence & Lifecycle — Suspend/Resume for details.
Context
Contexts provide knowledge to the agent — codebases, documentation, configuration. KubeOpenCode supports multiple context types:
spec:
contexts:
# Clone a Git repository into the workspace
- name: my-codebase
description: "Main application codebase"
type: Git
git:
repository: https://github.com/your-org/your-repo.git
ref: main
mountPath: code/ # Available at /workspace/code/
# Inline text context (written to .kubeopencode/context.md)
- name: coding-standards
description: "Team coding guidelines"
type: Text
text: |
Always use TypeScript strict mode.
Follow the repository's existing patterns.
# Reference a ConfigMap
- name: project-config
description: "Shared project configuration"
type: ConfigMap
configMap:
name: project-docs
key: guidelines.md
Context vs Workspace: Contexts are inputs — they provide information the agent needs. The workspace is the working area — it's where the agent reads contexts and creates output.
Git contexts support auto-sync to keep code up-to-date without pod restarts:
contexts:
- name: my-repo
type: Git
git:
repository: https://github.com/your-org/repo.git
ref: main
sync:
enabled: true
interval: "5m"
policy: HotReload # Update in-place, no restart
mountPath: repo/
See Flexible Context System for all context types and examples.
Skills
Skills are reusable AI capabilities defined as SKILL.md files. They teach the agent how to do things (as opposed to contexts, which tell the agent what it knows).
spec:
skills:
- name: community-skills
git:
repository: https://github.com/anthropics/skills.git
ref: main
path: skills/
names: # Optional: pick specific skills
- frontend-design
- skill-creator
KubeOpenCode automatically clones the skill repos and injects the paths into the OpenCode config. See Skills for private repos and advanced usage.
Plugins
Plugins extend Agent behavior at a deeper level — custom tools, auth providers, message interception, event handling, and more. They are OpenCode TypeScript plugins declared on the Agent spec. The controller creates a plugin-init container that runs npm install to download plugins into a shared volume — the executor container loads them without needing npm:
spec:
plugins:
- name: "cc-safety-net"
- name: "@nicholasgriffintn/opencode-plugin-otel"
options:
endpoint: "http://otel-collector:4318"
The controller installs plugins to /plugins/node_modules/ and merges file:// paths into the OpenCode plugin array. Plugin credentials are provided via spec.credentials. See Plugins for options, templates, and field reference.
Concurrency & Quota
Control how many Tasks can run simultaneously and limit task creation rate:
spec:
maxConcurrentTasks: 3 # Max 3 tasks running at once
quota:
maxTaskStarts: 20 # Max 20 tasks per hour
windowSeconds: 3600
See Concurrency & Quota for details.
Complete Example
Here's a production-ready Agent combining all the key features:
apiVersion: v1
kind: Secret
metadata:
name: ai-credentials
namespace: my-team
type: Opaque
stringData:
ANTHROPIC_API_KEY: "sk-ant-xxxxx"
---
apiVersion: kubeopencode.io/v1alpha1
kind: Agent
metadata:
name: team-agent
namespace: my-team
spec:
# Profile: human-readable description (informational only)
profile: "Full-stack development agent for the platform team"
# Step 1: AI Model Configuration
config:
$schema: https://opencode.ai/config.json
model: anthropic/claude-sonnet-4-5
small_model: anthropic/claude-haiku-4-5
share: disabled
autoupdate: false
credentials:
- name: anthropic
secretRef:
name: ai-credentials
# Step 2: Images (optional — defaults work for most cases)
# agentImage: ghcr.io/kubeopencode/kubeopencode-agent-opencode:latest
# executorImage: ghcr.io/kubeopencode/kubeopencode-agent-devbox:latest
# Step 3: Workspace
workspaceDir: /workspace
serviceAccountName: kubeopencode-agent
# Step 4: Features
persistence:
sessions:
size: "1Gi"
workspace:
size: "10Gi"
standby:
idleTimeout: "30m"
maxConcurrentTasks: 3
contexts:
- name: platform-repo
description: "Platform service codebase"
type: Git
git:
repository: https://github.com/your-org/platform.git
ref: main
sync:
enabled: true
interval: "5m"
policy: HotReload
mountPath: platform/
skills:
- name: team-skills
git:
repository: https://github.com/your-org/ai-skills.git
ref: main
path: skills/
Using AgentTemplate for Team Sharing
If multiple Agents share common configuration (images, credentials, model), extract it into an AgentTemplate:
apiVersion: kubeopencode.io/v1alpha1
kind: AgentTemplate
metadata:
name: team-base
namespace: my-team
spec:
agentImage: ghcr.io/kubeopencode/kubeopencode-agent-opencode:latest
executorImage: ghcr.io/kubeopencode/kubeopencode-agent-devbox:latest
workspaceDir: /workspace
serviceAccountName: kubeopencode-agent
config:
$schema: https://opencode.ai/config.json
model: anthropic/claude-sonnet-4-5
small_model: anthropic/claude-haiku-4-5
credentials:
- name: anthropic
secretRef:
name: ai-credentials
---
apiVersion: kubeopencode.io/v1alpha1
kind: Agent
metadata:
name: frontend-agent
namespace: my-team
spec:
templateRef:
name: team-base
profile: "Frontend development specialist"
# Override or extend template settings
contexts:
- name: frontend-repo
type: Git
git:
repository: https://github.com/your-org/frontend.git
ref: main
mountPath: frontend/
persistence:
sessions:
size: "1Gi"
standby:
idleTimeout: "1h"
Agent fields override template fields for scalars. For lists (contexts, credentials), the Agent replaces the template list entirely.
See Agent Templates for merge behavior details.
Submitting Tasks to Your Agent
Once your Agent is running, submit Tasks to it:
kubectl apply -n my-team -f - <<EOF
apiVersion: kubeopencode.io/v1alpha1
kind: Task
metadata:
name: fix-login-bug
spec:
agentRef:
name: team-agent
description: "Fix the login timeout bug in src/auth/handler.go"
EOF
# Watch progress
kubectl get task -n my-team -w
Further Reading: Repo-as-Agent Pattern
The KubeOpenCode team's own agent — kubeopencode-agent — follows the Repo-as-Agent pattern: a dedicated Git repository that is the agent, containing its identity, cross-repo context, team knowledge, skills, and scheduled workflows. The Agent you configure with KubeOpenCode is designed to work this way.
Read more about this pattern and how we built it: Whatever You Want to Build, Build an Agent First.
Next Steps
- Features — Deep dive into all Agent capabilities
- Security — RBAC, credential management, and network proxy
- Architecture — System design and complete API reference