services: # ── Identity init containers ─────────────────────────────────────────────── # Each agent0 container has a corresponding *-init service that runs once on # startup, pulls the agent's persona from the gnommoweb Content API, and # writes it to the shared volume. The main agent container depends on its # init service completing successfully before starting. # # To re-pull identity after an edit in gnommoweb admin: # docker compose up --force-recreate dobby-init dobby (etc.) dobby-init: image: python:3.12-alpine volumes: - ./agents/dobby:/a0/usr - ./scripts:/scripts:ro environment: AGENT_ID: ${DOBBY_AGENT_ID:-} AGENT_TYPE: agent0 CONTENT_API_URL: ${API_URL} CONTENT_API_KEY: ${CONTENT_API_KEY} command: ["python3", "/scripts/pull-agent-identity.py"] restart: "no" gemma-init: image: python:3.12-alpine volumes: - ./agents/gemma:/a0/usr - ./scripts:/scripts:ro environment: AGENT_ID: ${GEMMA_AGENT_ID:-} AGENT_TYPE: agent0 CONTENT_API_URL: ${API_URL} CONTENT_API_KEY: ${CONTENT_API_KEY} command: ["python3", "/scripts/pull-agent-identity.py"] restart: "no" gunnar-init: image: python:3.12-alpine volumes: - ./agents/gunnar:/a0/usr - ./scripts:/scripts:ro environment: AGENT_ID: ${GUNNAR_AGENT_ID:-} AGENT_TYPE: agent0 CONTENT_API_URL: ${API_URL} CONTENT_API_KEY: ${CONTENT_API_KEY} command: ["python3", "/scripts/pull-agent-identity.py"] restart: "no" rind-init: image: python:3.12-alpine volumes: - ./agents/rind:/a0/usr - ./scripts:/scripts:ro environment: AGENT_ID: ${RIND_AGENT_ID:-} AGENT_TYPE: agent0 CONTENT_API_URL: ${API_URL} CONTENT_API_KEY: ${CONTENT_API_KEY} command: ["python3", "/scripts/pull-agent-identity.py"] restart: "no" abyssinthia-init: image: python:3.12-alpine volumes: - ./agents/abyssinthia:/a0/usr - ./scripts:/scripts:ro environment: AGENT_ID: ${ABYSSINTHIA_AGENT_ID:-} AGENT_TYPE: agent0 CONTENT_API_URL: ${API_URL} CONTENT_API_KEY: ${CONTENT_API_KEY} command: ["python3", "/scripts/pull-agent-identity.py"] restart: "no" # ── Agent Zero instances ─────────────────────────────────────────────────── dobby: image: agent0ai/agent-zero:latest container_name: dobby ports: - "50001:80" # direct local access for debugging volumes: - ./agents/dobby:/a0/usr - ${HOME}/.ssh:/root/.ssh restart: unless-stopped depends_on: dobby-init: condition: service_completed_successfully environment: AUTH_LOGIN: ${AUTH_LOGIN} AUTH_PASSWORD: ${AUTH_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway" gemma: image: agent0ai/agent-zero:latest container_name: gemma ports: - "50002:80" volumes: - ./agents/gemma:/a0/usr - ${HOME}/.ssh:/root/.ssh restart: unless-stopped depends_on: gemma-init: condition: service_completed_successfully environment: AUTH_LOGIN: ${AUTH_LOGIN} AUTH_PASSWORD: ${AUTH_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway" gunnar: image: agent0ai/agent-zero:latest container_name: gunnar ports: - "50003:80" volumes: - ./agents/gunnar:/a0/usr - ${HOME}/.ssh:/root/.ssh restart: unless-stopped depends_on: gunnar-init: condition: service_completed_successfully environment: AUTH_LOGIN: ${AUTH_LOGIN} AUTH_PASSWORD: ${AUTH_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway" rind: image: agent0ai/agent-zero:latest container_name: rind ports: - "50005:80" volumes: - ./agents/rind:/a0/usr - ${HOME}/.ssh:/root/.ssh restart: unless-stopped depends_on: rind-init: condition: service_completed_successfully environment: AUTH_LOGIN: ${AUTH_LOGIN} AUTH_PASSWORD: ${AUTH_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway" abyssinthia: image: agent0ai/agent-zero:latest container_name: abyssinthia ports: - "50006:80" volumes: - ./agents/abyssinthia:/a0/usr - ${HOME}/.ssh:/root/.ssh restart: unless-stopped depends_on: abyssinthia-init: condition: service_completed_successfully environment: AUTH_LOGIN: ${AUTH_LOGIN} AUTH_PASSWORD: ${AUTH_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway" # ── Hermes agent ─────────────────────────────────────────────────────────── gerhard: image: nousresearch/hermes-agent:latest container_name: gerhard volumes: - ./agents/gerhard-hermes:/opt/data - ./agents/gerhard-workspace:/workspace - ./shared/knowledge:/knowledge - ../gutasktool:/opt/gutasktool - ${HOME}/.ssh:/root/.ssh restart: unless-stopped env_file: .env environment: HERMES_UID: ${HERMES_UID:-1000} HERMES_GID: ${HERMES_GID:-1000} HERMES_HOME: /opt/data extra_hosts: - "host.docker.internal:host-gateway" command: ["gateway", "run"] gerhard-dashboard: image: nousresearch/hermes-agent:latest container_name: gerhard-dashboard ports: - "50007:9119" # web dashboard at localhost:50007 volumes: - ./agents/gerhard-hermes:/opt/data restart: unless-stopped depends_on: - gerhard environment: HERMES_UID: ${HERMES_UID:-1000} HERMES_GID: ${HERMES_GID:-1000} extra_hosts: - "host.docker.internal:host-gateway" command: ["dashboard", "--host", "0.0.0.0", "--no-open", "--insecure", "--tui"] # ── Plugins ──────────────────────────────────────────────────────────────── postgres: image: postgres:16-alpine container_name: festinger-postgres restart: unless-stopped environment: POSTGRES_USER: festinger POSTGRES_PASSWORD: festinger POSTGRES_DB: festinger volumes: - festinger-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U festinger"] interval: 5s timeout: 5s retries: 10 festinger: build: context: ./plugins/festinger container_name: festinger ports: - "11435:11434" # exposed on host as 11435 to avoid conflict with real Ollama restart: unless-stopped depends_on: postgres: condition: service_healthy environment: POSTGRES_DSN: "postgresql://festinger:festinger@postgres:5432/festinger" extra_hosts: - "host.docker.internal:host-gateway" # ── Tunnel ───────────────────────────────────────────────────────────────── glitch-tunnel: build: context: . dockerfile: Dockerfile.tunnel container_name: glitch-tunnel restart: always volumes: - ./tunnel:/run/tunnel:ro depends_on: - dobby - gemma - gunnar - rind - abyssinthia - gerhard-dashboard volumes: festinger-pgdata: