Skip to content

Docker Compose

8. Docker Compose Design

8.1 Phase 1 — Agent Only (no gateway)

services:
  moby:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./agents/moby:/agent:ro
      - ${MOBYCLAW_HOME:-~/.mobyclaw}:/home/agent/.mobyclaw
    env_file:
      - .env
    restart: unless-stopped
    networks:
      - mobyclaw
    deploy:
      resources:
        limits:
          memory: 2g
          cpus: "1.0"

networks:
  mobyclaw:
    driver: bridge

8.3 Compose Override Generation

User-specific configuration (credentials and workspaces) is injected via docker-compose.override.yml, which is auto-generated by the CLI on every mobyclaw up. This file is gitignored and treated as a derived artifact — never hand-edited.

Mechanism:

mobyclaw up
  ├─ Read ~/.mobyclaw/credentials.env
  ├─ Read ~/.mobyclaw/workspaces.conf
  ├─ Generate docker-compose.override.yml
  │     ├─ env_file: for credentials (if any key=value lines exist)
  │     └─ volumes:  for workspaces (if any name=path lines exist)
  └─ docker compose up (picks up override automatically)

Generated override example:

# AUTO-GENERATED by mobyclaw — do not edit manually
services:
  moby:
    env_file:
      - /Users/you/.mobyclaw/credentials.env
    volumes:
      - /Users/you/projects/myapp:/workspace/myapp
      - /Users/you/Documents/notes:/workspace/notes

Design decisions: - Override, not inline in docker-compose.yml — The base compose file stays static and git-committed. Per-user config lives in the override. Docker Compose merges them automatically. - Regenerated every time — The override is rebuilt from credentials.env and workspaces.conf on each up. This means edits to those config files take effect immediately on next restart. - Graceful degradation — If both files are empty/missing/comment-only, no override is generated and the base compose works as-is. - Absolute paths — The override uses absolute paths to credentials.env because Docker Compose resolves env_file paths relative to the compose file location, not the user's home.

Why docker-compose.override.yml (not -f flag)? Docker Compose automatically loads docker-compose.override.yml when it exists in the same directory. No need for extra -f flags. The CLI's docker compose -f docker-compose.yml still picks it up.

Phase 1 is one container. moby has ~/.mobyclaw/ bind-mounted and uses cagent's built-in filesystem tools to read/write memory directly. No separate memory or workspace services yet.

8.2 Phase 2 — Full Stack with Gateway

services:
  moby:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./agents/moby:/agent:ro
      - ${MOBYCLAW_HOME:-~/.mobyclaw}:/home/agent/.mobyclaw
    env_file:
      - .env
    environment:
      - ANTHROPIC_API_KEY         # LLM keys only
      - OPENAI_API_KEY
    restart: unless-stopped
    networks:
      - mobyclaw

  gateway:
    build:
      context: ./gateway
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - ${MOBYCLAW_HOME:-~/.mobyclaw}:/data/.mobyclaw
    env_file:
      - .env
    environment:
      - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-}
      - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-}
      - SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:-}
      - WHATSAPP_AUTH=${WHATSAPP_AUTH:-}
      - MOBYCLAW_HEARTBEAT_INTERVAL=${MOBYCLAW_HEARTBEAT_INTERVAL:-30m}
    depends_on:
      - moby
    restart: unless-stopped
    networks:
      - mobyclaw

networks:
  mobyclaw:
    driver: bridge