services: postgres: image: pgvector/pgvector:pg16 container_name: jarvis-postgres environment: POSTGRES_DB: jarvis POSTGRES_USER: jarvis POSTGRES_PASSWORD: ${DB_PASSWORD:-ChangeMe123!} volumes: - postgres_data:/var/lib/postgresql/data - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql ports: - "5432:5432" networks: - jarvis-net healthcheck: test: ["CMD-SHELL", "pg_isready -U jarvis"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped redis: image: redis:7-alpine container_name: jarvis-redis command: redis-server --appendonly yes volumes: - redis_data:/data ports: - "6379:6379" networks: - jarvis-net healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped # NOTE: milvus/etcd are placeholders - milvusdb/milvus:v0.4.0 does not exist # and this config format (etcd-only, no MinIO) doesn't match modern Milvus # standalone anyway. Not started yet; needs a proper Phase 3 design. milvus: image: milvusdb/milvus:v0.4.0 container_name: jarvis-milvus environment: ETCD_ENDPOINTS: etcd:2379 COMMON_STORAGETYPE: local volumes: - milvus_data:/var/lib/milvus ports: - "19530:19530" - "9091:9091" depends_on: etcd: condition: service_healthy networks: - jarvis-net restart: unless-stopped etcd: image: quay.io/coreos/etcd:v3.5.5 container_name: jarvis-etcd environment: - ETCD_AUTO_COMPACTION_MODE=revision - ETCD_AUTO_COMPACTION_RETENTION=1000 - ETCD_QUOTA_BACKEND_BYTES=4294967296 volumes: - etcd_data:/etcd ports: - "2379:2379" networks: - jarvis-net healthcheck: test: ["CMD", "etcdctl", "endpoint", "health"] interval: 10s timeout: 5s retries: 5 command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd restart: unless-stopped ollama: image: ollama/ollama:latest container_name: jarvis-ollama environment: - OLLAMA_HOST=0.0.0.0:11434 volumes: - ollama_data:/root/.ollama ports: - "11434:11434" networks: - jarvis-net restart: unless-stopped n8n: image: n8nio/n8n:latest container_name: jarvis-n8n environment: - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_USER=jarvis - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD:-ChangeMe123!} - DB_POSTGRESDB_DATABASE=n8n - N8N_HOST=n8n.${DOMAIN:-localhost} - N8N_PORT=5678 - N8N_PROTOCOL=https - WEBHOOK_TUNNEL_URL=https://n8n.${DOMAIN:-localhost}/ - GENERIC_TIMEZONE=Europe/Berlin volumes: - n8n_data:/home/node/.n8n ports: - "5678:5678" depends_on: postgres: condition: service_healthy networks: - jarvis-net - proxy-network labels: - "traefik.enable=true" - "traefik.docker.network=proxy-network" - "traefik.http.routers.jarvis-n8n.rule=Host(`n8n.${DOMAIN:-localhost}`)" - "traefik.http.routers.jarvis-n8n.entrypoints=websecure" - "traefik.http.routers.jarvis-n8n.tls=true" - "traefik.http.routers.jarvis-n8n.tls.certresolver=netcup" - "traefik.http.services.jarvis-n8n.loadbalancer.server.port=5678" restart: unless-stopped jarvis-api: image: python:3.11-slim container_name: jarvis-api working_dir: /app command: > bash -c "pip install -q -r requirements.txt && uvicorn main:app --host 0.0.0.0 --port 8000 --reload" environment: - DATABASE_URL=postgresql://jarvis:${DB_PASSWORD:-ChangeMe123!}@postgres:5432/jarvis - REDIS_URL=redis://redis:6379 - MILVUS_HOST=milvus - MILVUS_PORT=19530 - OLLAMA_HOST=http://ollama:11434 - OLLAMA_EMBED_MODEL=nomic-embed-text - N8N_URL=http://n8n:5678 - CLAUDE_API_KEY=${CLAUDE_API_KEY:-} - CLAUDE_MODEL=claude-sonnet-5 - API_KEY_ADMIN=${API_KEY_ADMIN:-} - NEXTCLOUD_CALDAV_URL=https://cloud.ffw-onza.de/remote.php/dav/calendars/jonny/ffw-onza-alle/ - NEXTCLOUD_USER=jonny - NEXTCLOUD_APP_PASSWORD=${NEXTCLOUD_APP_PASSWORD:-} - EMAIL_IMAP_HOST=mx2f35.netcup.net - EMAIL_IMAP_PORT=143 - EMAIL_SMTP_HOST=mx2f35.netcup.net - EMAIL_SMTP_PORT=465 - EMAIL_USER=kontakt@mbo-tech-it.de - EMAIL_PASSWORD=${EMAIL_PASSWORD:-} - LOG_LEVEL=info volumes: - ./api:/app ports: - "8000:8000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - jarvis-net - proxy-network labels: - "traefik.enable=true" - "traefik.docker.network=proxy-network" - "traefik.http.routers.jarvis-api.rule=Host(`api.${DOMAIN:-localhost}`)" - "traefik.http.routers.jarvis-api.entrypoints=websecure" - "traefik.http.routers.jarvis-api.tls=true" - "traefik.http.routers.jarvis-api.tls.certresolver=netcup" - "traefik.http.services.jarvis-api.loadbalancer.server.port=8000" restart: unless-stopped jarvis-web: build: context: ./web dockerfile: Dockerfile container_name: jarvis-web networks: - proxy-network labels: - "traefik.enable=true" - "traefik.docker.network=proxy-network" - "traefik.http.routers.jarvis-web.rule=Host(`${DOMAIN:-localhost}`)" - "traefik.http.routers.jarvis-web.entrypoints=websecure" - "traefik.http.routers.jarvis-web.tls=true" - "traefik.http.routers.jarvis-web.tls.certresolver=netcup" - "traefik.http.services.jarvis-web.loadbalancer.server.port=80" restart: unless-stopped networks: jarvis-net: driver: bridge proxy-network: external: true volumes: postgres_data: redis_data: milvus_data: etcd_data: ollama_data: n8n_data: