Skip to content

Configuration

VibePod merges configuration from four sources in order, with each layer overriding the previous:

  1. Built-in defaults
  2. Global config~/.config/vibepod/config.yaml
  3. Project config.vibepod/config.yaml in the current directory
  4. Environment variables — override specific keys at runtime

Run vp config path to print the exact paths in use, and vp config show to print the fully merged result.

Full reference

# Config format version (always 1)
version: 1

# Agent to run when no argument is given to `vp run`
# Alias `vibe` resolves to `devstral`.
default_agent: claude

# Pull the latest image before every run (default: true)
# Can be overridden per agent with agents.<agent>.auto_pull
auto_pull: true

# Remove untagged vibepod images after a pull (default: true)
# When a pull retags `latest`, the previous image stays behind untagged
# (`vibepod/claude   <none>`) and such images accumulate over time. With
# auto_clean every pull sweeps the whole `vibepod/` namespace, so leftovers
# from earlier pulls are cleared too. Tagged images, images of other
# namespaces, and images still used by a container are never removed — an
# image held by a container is picked up by a later sweep instead.
auto_clean: true

# Remove the container automatically when it stops (default: true)
auto_remove: true

# Primary Docker network created and used by VibePod
network: vibepod-network

# Log level: debug | info | warning | error
log_level: info

# Disable colour output
no_color: false

agents:
  claude:
    enabled: true
    image: vibepod/claude:latest
    auto_pull: null  # Per-agent override: true/false, or null to use global auto_pull
    env: {}       # Extra environment variables passed to the container
    volumes: []   # Reserved for future use
    ports: []     # Ports to publish on the host, `docker run -p` syntax
    init: []      # Optional shell commands run before agent startup
    overlay: true # Set false to ignore the project's .vibepod/overlay/ (see Project overlays)

  gemini:
    enabled: true
    image: vibepod/gemini:latest
    env: {}
    volumes: []
    ports: []
    init: []

  opencode:
    enabled: true
    image: vibepod/opencode:latest
    env: {}
    volumes: []
    ports: []
    init: []

  devstral:
    enabled: true
    image: vibepod/devstral:latest
    env: {}
    volumes: []
    ports: []
    init: []

  auggie:
    enabled: true
    image: vibepod/auggie:latest
    env: {}
    volumes: []
    ports: []
    init: []

  copilot:
    enabled: true
    image: vibepod/copilot:latest
    env: {}
    volumes: []
    ports: []
    init: []

  codex:
    enabled: true
    image: vibepod/codex:latest
    env: {}
    volumes: []
    ports: []
    init: []

  pi:
    enabled: true
    image: vibepod/pi:latest
    env: {}
    volumes: []
    ports: []
    init: []

  agy:
    enabled: true
    image: vibepod/agy:latest
    env: {}
    volumes: []
    ports: []
    init: []

  tau:
    enabled: true
    image: vibepod/tau:latest
    env: {}
    volumes: []
    ports: []
    init: []

  jcode:
    enabled: true
    image: vibepod/jcode:latest
    env: {}
    volumes: []
    init: []

# Connect agents to a local or remote LLM server (Ollama, vLLM, etc.)
llm:
  enabled: false
  base_url: ""       # Server endpoint URL
  api_key: ""        # Auth token (set to "ollama" for Ollama)
  model: ""          # Model name passed to the agent

logging:
  enabled: true
  image: vibepod/datasette:latest
  db_path: ~/.config/vibepod/logs.db
  ui_port: 8001         # Port for the Datasette UI

proxy:
  enabled: true
  image: vibepod/proxy:latest
  db_path: ~/.config/vibepod/proxy/proxy.db
  ca_dir: ~/.config/vibepod/proxy/mitmproxy
  ca_path: ~/.config/vibepod/proxy/mitmproxy/mitmproxy-ca-cert.pem

Environment variables

These variables override the corresponding config keys without editing any file:

Variable Config key Example
VP_DEFAULT_AGENT default_agent VP_DEFAULT_AGENT=vibe
VP_AUTO_PULL auto_pull VP_AUTO_PULL=true
VP_AUTO_CLEAN auto_clean VP_AUTO_CLEAN=false
VP_LOG_LEVEL log_level VP_LOG_LEVEL=debug
VP_NO_COLOR no_color VP_NO_COLOR=true
VP_DATASETTE_PORT logging.ui_port VP_DATASETTE_PORT=9001
VP_PROXY_ENABLED proxy.enabled VP_PROXY_ENABLED=false
VP_LLM_ENABLED llm.enabled VP_LLM_ENABLED=true
VP_LLM_BASE_URL llm.base_url VP_LLM_BASE_URL=http://localhost:11434
VP_LLM_API_KEY llm.api_key VP_LLM_API_KEY=ollama
VP_LLM_MODEL llm.model VP_LLM_MODEL=qwen3:14b
VP_CONFIG_DIR (config root) VP_CONFIG_DIR=/custom/path

Image overrides

Each agent image can be overridden individually:

Variable Agent
VP_IMAGE_CLAUDE claude
VP_IMAGE_GEMINI gemini
VP_IMAGE_OPENCODE opencode
VP_IMAGE_DEVSTRAL devstral
VP_IMAGE_AUGGIE auggie
VP_IMAGE_COPILOT copilot
VP_IMAGE_CODEX codex
VP_IMAGE_PI pi
VP_IMAGE_AGY agy
VP_IMAGE_TAU tau
VP_IMAGE_JCODE jcode
VP_DATASETTE_IMAGE datasette (logs UI)
VP_PROXY_IMAGE proxy
VP_SKILLS_ENGINE_IMAGE skills-engine (used by vp skills)

Set VP_IMAGE_NAMESPACE to change the prefix for all default images at once:

VP_IMAGE_NAMESPACE=myorg vp run claude
# pulls myorg/claude:latest

For end-to-end examples (extending a base image and assigning a brand-new image to an agent), see Agents > Image customization workflows.

Project-level config

Use vp config init in your repository to create .vibepod/config.yaml automatically when it does not already exist:

vp config init

If .vibepod/config.yaml already exists, this command exits without modifying it; run vp config init --force to replace the file.

This writes a minimal starter file:

version: 1

To copy a full agent block into the project config, pass the agent name:

vp config init claude

This adds agents.claude to .vibepod/config.yaml (creating the file if needed). If agents.claude is already present, the command exits without modifying the file.

Then add only the keys you want to override. Project config is merged on top of global config and defaults.

# .vibepod/config.yaml
default_agent: opencode
agents:
  opencode:
    env:
      OPENAI_BASE_URL: https://my-internal-proxy/v1
    init:
      - apt-get update
      - apt-get install -y ripgrep

agents.<agent>.init runs inside the container before the agent process starts. Commands run with /bin/sh -lc and set -e (startup stops on the first failed command).

Commit this file to share project defaults with your team.

Publishing ports

By default no user-defined ports are published, so anything the agent starts inside the container — a dev server, web UI, or debugger — is unreachable from the host. agents.<agent>.ports publishes container ports on the host using the same syntax as docker run -p:

# .vibepod/config.yaml
agents:
  claude:
    ports:
      - "8000:8000"            # host:container
      - "127.0.0.1:9229:9229"  # bind to a specific host interface
      - "6000:6000/udp"        # UDP
      - "3000"                 # container port on a random host port

Always quote port entries

YAML 1.1 parses unquoted host:container pairs as base-60 numbers: - 22:22 loads as the integer 1342 and would publish the wrong port. Out-of-range results (e.g. 3000:30180030) are rejected at startup, but in-range ones are not detectable — quote every entry.

Like other agent keys, a project-level ports list replaces the global one for that agent. The list applies to both vp run and vp task containers; note that two containers cannot publish the same host port at the same time, so a fixed host port limits you to one such container per agent.

The built-in proxy

VibePod starts a vibepod-proxy container alongside every agent. It acts as an HTTP(S) MITM proxy and logs all outbound requests to a SQLite database viewable in the Datasette UI (vp logs start).

The proxy is reachable inside the Docker network as http://vibepod-proxy:8080. It is not published on a host port.

To disable the proxy globally:

proxy:
  enabled: false

Or at runtime:

VP_PROXY_ENABLED=false vp run claude

Podman users

The proxy relies on container-name DNS resolution over the vibepod-network network. If you use Podman with the CNI backend, install the dnsname plugin (e.g. podman-plugins on Fedora, golang-github-containernetworking-plugin-dnsname on Debian/Ubuntu) and recreate the network. See Quickstart — Using Podman for full instructions.