services: # PostgreSQL with pgvector db: image: pgvector/pgvector:pg16 container_name: officeplane-db environment: POSTGRES_DB: officeplane POSTGRES_USER: officeplane POSTGRES_PASSWORD: officeplane ports: - "5433:5432" volumes: - db_data:/var/lib/postgresql/data - ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U officeplane"] interval: 5s timeout: 5s retries: 5 # Redis — task queue, document locks, SSE pub/sub redis: image: redis:7-alpine container_name: officeplane-redis ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 # Document conversion — DOCX/HTML/MD → PDF, plus merge/split/watermark gotenberg: image: gotenberg/gotenberg:8 container_name: officeplane-gotenberg restart: unless-stopped # Not exposed to the host — only api talks to it expose: - "3000" # Reasonable defaults; tighten if needed command: - gotenberg - --api-port=3000 - --api-timeout=60s - --libreoffice-restart-after=20 # FastAPI Backend api: build: context: . dockerfile: docker/Dockerfile container_name: officeplane-api ports: - "8001:8001" environment: - DATABASE_URL=postgresql://officeplane:officeplane@db:5432/officeplane - OFFICEPLANE_BROKER=${OFFICEPLANE_BROKER:-memory} - REDIS_URL=redis://redis:6379/0 - OPENAI_API_KEY=${OPENAI_API_KEY} - GOOGLE_API_KEY=${GOOGLE_API_KEY} - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} - OFFICEPLANE_AGENT_MODEL=${OFFICEPLANE_AGENT_MODEL:-deepseek/deepseek-v4-flash} - OFFICEPLANE_AGENT_TEMPERATURE=${OFFICEPLANE_AGENT_TEMPERATURE:-0.0} - OFFICEPLANE_INGESTION_MODE=${OFFICEPLANE_INGESTION_MODE:-text} - OFFICEPLANE_INGESTION_MODEL=${OFFICEPLANE_INGESTION_MODEL:-deepseek/deepseek-v4-flash} - OFFICEPLANE_INGESTION_VISION_PROVIDER=${OFFICEPLANE_INGESTION_VISION_PROVIDER:-gemini} - OFFICEPLANE_AGENT_MODEL_FLASH=${OFFICEPLANE_AGENT_MODEL_FLASH:-deepseek/deepseek-v4-flash} - OFFICEPLANE_AGENT_MODEL_PRO=${OFFICEPLANE_AGENT_MODEL_PRO:-deepseek/deepseek-v4-pro} - CONTENT_AGENT_MODEL=${CONTENT_AGENT_MODEL:-deepseek/deepseek-v4-flash} - CONTENT_AGENT_TIMEOUT=${CONTENT_AGENT_TIMEOUT:-600} - CONTENT_AGENT_WORKSPACE=/data/workspaces - GOTENBERG_URL=${GOTENBERG_URL:-http://gotenberg:3000} - OFFICEPLANE_IMAGE_PROVIDER=${OFFICEPLANE_IMAGE_PROVIDER:-placeholder} - OFFICEPLANE_PPTX_TEMPLATE=${OFFICEPLANE_PPTX_TEMPLATE:-/app/src/officeplane/assets/templates/styled-clinical.pptx} depends_on: db: condition: service_healthy gotenberg: condition: service_started # redis dependency only needed when OFFICEPLANE_BROKER=redis # redis: # condition: service_healthy volumes: - ./data:/data - ./src:/app/src:ro # Mount source code for hot reload (read-only) command: uvicorn officeplane.api.main:app --host 0.0.0.0 --port 8001 --reload # NextJS UI ui: build: context: . dockerfile: ui/Dockerfile container_name: officeplane-ui ports: - "3001:3000" environment: - DATABASE_URL=postgresql://officeplane:officeplane@db:5432/officeplane - NEXT_PUBLIC_API_URL=http://localhost:8001 - NEXT_PUBLIC_WS_URL=ws://localhost:8001 depends_on: db: condition: service_healthy api: condition: service_started volumes: db_data: redis_data: