282 lines
8.0 KiB
Plaintext
Raw Permalink Normal View History

2026-01-12 03:36:55 +00:00
version: '3.9'
services:
# SurrealDB - Multi-model database
surrealdb:
image: surrealdb/surrealdb:latest
container_name: vapora-surrealdb
command: start --bind 0.0.0.0:8000 file:///data/database.db
ports:
- "8000:8000"
volumes:
- surrealdb_data:/data
environment:
SURREAL_LOG: debug
RUST_LOG: debug
networks:
- vapora
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
{% if nats.enabled %}
# NATS JetStream - Message broker for agent coordination
nats:
image: nats:latest
container_name: vapora-nats
command: -js -m 8222 -D
ports:
- "4222:4222"
- "8222:8222"
volumes:
- nats_data:/data
networks:
- vapora
healthcheck:
test: ["CMD", "nc", "-z", "localhost", "4222"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
{% endif %}
{% if llm_router.providers.ollama_enabled %}
# Ollama - Local LLM provider
ollama:
image: ollama/ollama:latest
container_name: vapora-ollama
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
environment:
OLLAMA_HOST: "0.0.0.0:11434"
networks:
- vapora
profiles:
- llm
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
{% endif %}
# VAPORA Backend - REST API and orchestration
backend:
build:
context: .
dockerfile: crates/vapora-backend/Dockerfile
container_name: vapora-backend
ports:
- "{{ backend.port }}:{{ backend.port }}"
environment:
DEPLOYMENT_MODE: "{{ deployment_mode }}"
WORKSPACE_NAME: "{{ workspace_name }}"
BACKEND_HOST: "{{ backend.host }}"
BACKEND_PORT: "{{ backend.port }}"
BACKEND_WORKERS: "{{ backend.workers }}"
BACKEND_REQUEST_TIMEOUT: "{{ backend.request_timeout }}"
DATABASE_URL: "{{ backend.database.url }}"
DATABASE_USER: "{{ backend.database.username }}"
DATABASE_PASSWORD: "{{ backend.database.password }}"
DATABASE_POOL_SIZE: "{{ backend.database.pool_size }}"
STORAGE_PATH: "{{ backend.storage.path }}"
LOG_LEVEL: "{{ monitoring.log_level }}"
JWT_SECRET: "{{ security.jwt_secret }}"
PROMETHEUS_ENABLED: "{{ monitoring.prometheus_enabled|lower }}"
{% if nats.enabled %}
NATS_ENABLED: "true"
NATS_URL: "{{ nats.url }}"
{% else %}
NATS_ENABLED: "false"
{% endif %}
CLAUDE_ENABLED: "{{ llm_router.providers.claude_enabled|lower }}"
OPENAI_ENABLED: "{{ llm_router.providers.openai_enabled|lower }}"
OLLAMA_ENABLED: "{{ llm_router.providers.ollama_enabled|lower }}"
OLLAMA_URL: "{{ llm_router.providers.ollama_url }}"
volumes:
- vapora_storage:/var/lib/vapora/storage
- ./vapora.toml:/etc/vapora/config/vapora.toml:ro
networks:
- vapora
depends_on:
surrealdb:
condition: service_healthy
{% if nats.enabled %}
nats:
condition: service_healthy
{% endif %}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{ backend.port }}/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# VAPORA Agents - Task orchestration and execution
agents:
build:
context: .
dockerfile: crates/vapora-agents/Dockerfile
container_name: vapora-agents
ports:
- "{{ agents.port }}:{{ agents.port }}"
environment:
AGENTS_HOST: "{{ agents.host }}"
AGENTS_PORT: "{{ agents.port }}"
AGENTS_MAX_INSTANCES: "{{ agents.max_instances }}"
AGENTS_HEARTBEAT_INTERVAL: "{{ agents.heartbeat_interval }}"
LEARNING_ENABLED: "{{ agents.learning.enabled|lower }}"
RECENCY_WINDOW_DAYS: "{{ agents.learning.recency_window_days }}"
KNOWLEDGE_GRAPH_ENABLED: "{{ agents.knowledge_graph.enabled|lower }}"
KNOWLEDGE_GRAPH_RETENTION_DAYS: "{{ agents.knowledge_graph.retention_days }}"
{% if agents.nats.enabled %}
NATS_ENABLED: "true"
NATS_URL: "nats://nats:4222"
{% else %}
NATS_ENABLED: "false"
{% endif %}
LOG_LEVEL: "{{ monitoring.log_level }}"
networks:
- vapora
depends_on:
backend:
condition: service_healthy
{% if agents.nats.enabled %}
nats:
condition: service_healthy
{% endif %}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{ agents.port }}/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# VAPORA LLM Router - Multi-provider LLM orchestration
llm-router:
build:
context: .
dockerfile: crates/vapora-llm-router/Dockerfile
container_name: vapora-llm-router
ports:
- "{{ llm_router.port }}:{{ llm_router.port }}"
environment:
LLM_ROUTER_HOST: "{{ llm_router.host }}"
LLM_ROUTER_PORT: "{{ llm_router.port }}"
COST_TRACKING_ENABLED: "{{ llm_router.cost_tracking.enabled|lower }}"
BUDGET_ENFORCEMENT_ENABLED: "{{ llm_router.budget_enforcement.enabled|lower }}"
BUDGET_WINDOW: "{{ llm_router.budget_enforcement.window }}"
CLAUDE_ENABLED: "{{ llm_router.providers.claude_enabled|lower }}"
OPENAI_ENABLED: "{{ llm_router.providers.openai_enabled|lower }}"
GEMINI_ENABLED: "{{ llm_router.providers.gemini_enabled|lower }}"
OLLAMA_ENABLED: "{{ llm_router.providers.ollama_enabled|lower }}"
OLLAMA_URL: "{{ llm_router.providers.ollama_url }}"
ROUTING_STRATEGY: "{{ llm_router.routing.strategy }}"
LOG_LEVEL: "{{ monitoring.log_level }}"
networks:
- vapora
depends_on:
backend:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{ llm_router.port }}/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# VAPORA Frontend - React/WASM UI
frontend:
build:
context: .
dockerfile: crates/vapora-frontend/Dockerfile
container_name: vapora-frontend
ports:
- "{{ frontend.port }}:{{ frontend.port }}"
environment:
FRONTEND_HOST: "{{ frontend.host }}"
FRONTEND_PORT: "{{ frontend.port }}"
API_URL: "http://backend:{{ backend.port }}"
ENABLE_WASM: "{{ frontend.enable_wasm|lower }}"
networks:
- vapora
depends_on:
backend:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{ frontend.port }}/"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
{% if monitoring.prometheus_enabled %}
# Prometheus - Metrics collection and alerting
prometheus:
image: prom/prometheus:latest
container_name: vapora-prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
networks:
- vapora
restart: unless-stopped
# Grafana - Metrics visualization
grafana:
image: grafana/grafana:latest
container_name: vapora-grafana
ports:
- "3001:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: "admin"
GF_SECURITY_ADMIN_USER: "admin"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
networks:
- vapora
depends_on:
- prometheus
restart: unless-stopped
{% endif %}
volumes:
surrealdb_data:
driver: local
vapora_storage:
driver: local
{% if nats.enabled %}
nats_data:
driver: local
{% endif %}
{% if llm_router.providers.ollama_enabled %}
ollama_data:
driver: local
{% endif %}
{% if monitoring.prometheus_enabled %}
prometheus_data:
driver: local
grafana_data:
driver: local
{% endif %}
networks:
vapora:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16