name: {{ compose_project_name | default('openclaw-docker') }}

services:
  # --- Infrastructure Services ---

  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    container_name: {{ container_prefix | default('openclaw') }}-litellm
    restart: unless-stopped
    env_file: litellm.env
    environment:
      - LITELLM_LOG=INFO
      - MCP_LOG_URL=http://alhazen-mcp:3000/log-llm-call
    ports:
      - "127.0.0.1:4000:4000"
    networks:
      - openclaw-internal
      - openclaw-external
    volumes:
      - ./litellm-config.yaml:/app/config.yaml:ro
      - {{ repo_dir }}/local_resources/skilllog/litellm_callback.py:/app/litellm_callback.py:ro
    command: ["--config", "/app/config.yaml", "--port", "4000"]
    extra_hosts:
      - "host.docker.internal:host-gateway"
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=100m
    mem_limit: 1g
    cpus: 1.0

  squid:
    image: docker.io/ubuntu/squid:latest
    container_name: {{ container_prefix | default('openclaw') }}-squid
    restart: unless-stopped
    ports:
      - "127.0.0.1:3128:3128"
    volumes:
      - ./squid.conf:/etc/squid/squid.conf:ro
      - ./allowlist.txt:/etc/squid/allowlist.txt:ro
    networks:
      - openclaw-internal
      - openclaw-external

  # --- OpenClaw Agent ---
  # IMPORTANT: The agent gets openclaw-external for direct internet (Telegram, etc.)
  # but does NOT use Squid proxy. The @anthropic-ai/sdk in Node.js honors HTTP_PROXY
  # but ignores NO_PROXY, so routing through Squid breaks internal LiteLLM calls.
  # Instead, the agent talks to LiteLLM directly via the internal network.

  openclaw:
    build:
      context: ./openclaw-build
    container_name: {{ container_prefix | default('openclaw') }}-agent
    restart: unless-stopped
    ports:
      - "127.0.0.1:18789:18789"
    networks:
      - openclaw-internal
      - openclaw-external
    volumes:
      - ./openclaw-data:/home/node/.openclaw
      - ./openclaw-data/gateway.crt:/home/node/.openclaw/gateway.crt:ro
      - ./openclaw-data/gateway.key:/home/node/.openclaw/gateway.key:ro
      - ./openclaw-ssh:/home/node/.ssh
      - ./workspace:/opt/openclaw/workspace
    working_dir: /home/node
    env_file: .env
    environment:
      - NODE_ENV=production
      - ANTHROPIC_API_BASE=http://litellm:4000
      - ANTHROPIC_API_KEY=${LITELLM_MASTER_KEY}
      - OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
      - OPENCLAW_GATEWAY_CERT=/home/node/.openclaw/gateway.crt
      - OPENCLAW_GATEWAY_KEY=/home/node/.openclaw/gateway.key
      - SEARXNG_URL=http://searxng:8080
    depends_on:
      - litellm
      - searxng
    shm_size: '256m'
    security_opt:
      - no-new-privileges:true

  searxng:
    image: docker.io/searxng/searxng:latest
    container_name: {{ container_prefix | default('alhazen') }}-searxng
    restart: unless-stopped
    volumes:
      - ./searxng:/etc/searxng:rw
    networks:
      - openclaw-internal
      - openclaw-external
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    mem_limit: 512m
    cpus: 0.5

  # --- Alhazen Services ---

{% if target_type != 'macmini' %}
  typedb:
    image: docker.io/typedb/typedb:3.8.0
    container_name: {{ container_prefix | default('alhazen') }}-typedb
    restart: unless-stopped
    volumes:
      - ./typedb-data:/var/lib/typedb/data
      - {{ repo_dir }}/local_resources/typedb:/schema:ro
    healthcheck:
      test: ["CMD-SHELL", "timeout 3 bash -c 'echo > /dev/tcp/localhost/1729' 2>/dev/null || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    networks:
      - openclaw-internal
    ports:
      - "127.0.0.1:{{ typedb_host_port | default('1729') }}:1729"
    security_opt:
      - no-new-privileges:true
    mem_limit: 2g
    cpus: 2.0

  typedb-init:
    image: python:3.11-slim
    container_name: {{ container_prefix | default('alhazen') }}-typedb-init
    depends_on:
      typedb:
        condition: service_healthy
    volumes:
      - {{ repo_dir }}/local_resources/typedb:/schema:ro
      - {{ repo_dir }}/local_skills:/local_skills:ro
      - {{ repo_dir }}/scripts:/scripts:ro
    environment:
      - TYPEDB_HOST=typedb
      - TYPEDB_PORT=1729
      - TYPEDB_DATABASE=alhazen_notebook
    entrypoint: ["/bin/bash", "-c"]
    command:
      - |
        pip install typedb-driver -q
        python /scripts/db_init.py \
          /schema/alhazen_notebook.tql \
          /schema/namespaces/skilllog.tql \
          $(find /local_skills -name 'schema.tql' | sort | tr '\n' ' ')
    networks:
      - openclaw-internal
    restart: "no"

  alhazen-mcp:
    build:
      context: {{ repo_dir }}
      dockerfile: Dockerfile.mcp
    container_name: {{ container_prefix | default('alhazen') }}-mcp
    restart: unless-stopped
    environment:
      - TYPEDB_HOST=typedb
      - TYPEDB_PORT=1729
      - TYPEDB_DATABASE=alhazen_notebook
      - MCP_PORT=3000
    depends_on:
      typedb:
        condition: service_healthy
    networks:
      - openclaw-internal
    ports:
      - "127.0.0.1:{{ mcp_host_port | default('3000') }}:3000"
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=50m
    mem_limit: 1g
    cpus: 1.0

{% endif %}
  alhazen-dashboard:
    build:
      context: {{ repo_dir }}
      dockerfile: dashboard/Dockerfile
    container_name: {{ container_prefix | default('alhazen') }}-dashboard
    restart: unless-stopped
    environment:
      - TYPEDB_HOST={{ 'alhazen-typedb' if target_type == 'macmini' else 'typedb' }}
      - TYPEDB_PORT=1729
      - TYPEDB_DATABASE=alhazen_notebook
{% if target_type != 'macmini' %}
    depends_on:
      - typedb
{% endif %}
    networks:
      - openclaw-internal
{% if target_type == 'macmini' %}
      - alhazen-network
{% endif %}
    ports:
      - "127.0.0.1:{{ dashboard_host_port | default('3001') }}:3000"
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=50m
    mem_limit: 512m
    cpus: 1.0

networks:
  openclaw-internal:
    driver: bridge
    internal: true
    ipam:
      config:
        - subnet: 172.28.0.0/16

  openclaw-external:
    driver: bridge

{% if target_type == 'macmini' %}
  alhazen-network:
    external: true
    name: skillful-alhazen_alhazen-network
{% endif %}
