# Local full copy of production CRM for development and pre-deploy testing. # Uses the same images and structure as the production server, but without Traefik. # # Usage: # docker compose -f docker-compose.local.yml -p crm-local up -d --build # docker compose -f docker-compose.local.yml -p crm-local down # # Project name is "crm-local" to avoid conflicts with production "crm" containers. services: app: build: context: . dockerfile: Dockerfile env_file: - .env.local environment: - NODE_ENV=production - APP_HTTPS_PROXY=false - OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://ollama:11434} - DOC_WORKER_URL=${DOC_WORKER_URL:-http://document-worker:3000} ports: - "5000:5000" volumes: - crm_data:/app/data - crm_uploads:/app/uploads restart: unless-stopped healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:5000/api/health || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 300s depends_on: db: condition: service_healthy required: false minio: condition: service_healthy required: false # Ресурсные лимиты (шаг 0.4) mem_limit: 1g cpus: 1.5 pids_limit: 256 db: # Тег запинен: pgvector 0.8.4 + PostgreSQL 16 (совпадает с локальным стендом) image: pgvector/pgvector:0.8.4-pg16 environment: POSTGRES_DB: ${POSTGRES_DB:-appdb} POSTGRES_USER: ${POSTGRES_USER:-appuser} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-appuser} -d ${POSTGRES_DB:-appdb}"] interval: 5s timeout: 5s retries: 10 start_period: 10s # Ресурсные лимиты (шаг 0.4) mem_limit: 768m cpus: 0.75 pids_limit: 128 minio: # Тег запинен: совпадает с версией на продакшене (RELEASE.2025-09-07T16-13-09Z) image: minio/minio:RELEASE.2025-09-07T16-13-09Z command: server /data --console-address :9001 ports: - "9000:9000" - "9001:9001" environment: # Креды MinIO — только из .env.local, дефолтов нет: в production обязательно сменить minioadmin/minioadmin MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY is required} MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY is required} volumes: - minio_data:/data restart: unless-stopped healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 10s timeout: 5s retries: 10 start_period: 15s # Ресурсные лимиты (шаг 0.4) mem_limit: 256m cpus: 0.5 pids_limit: 64 webdav: # Тег запинен: совпадает с версией на продакшене (rclone v1.74.0) image: rclone/rclone:1.74.0 entrypoint: /bin/sh command: > -c "rclone serve webdav --addr :8080 --user $${WEBDAV_USER:-admin} --pass $${WEBDAV_PASSWORD:?WEBDAV_PASSWORD is required} --no-checksum :s3:$${MINIO_BUCKET:-files} --s3-provider=Minio --s3-access-key-id=$${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY is required} --s3-secret-access-key=$${MINIO_SECRET_KEY} --s3-endpoint=http://minio:9000 --s3-no-check-bucket" ports: - "8080:8080" environment: WEBDAV_USER: ${WEBDAV_USER:-admin} WEBDAV_PASSWORD: ${WEBDAV_PASSWORD:-} MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY is required} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-} MINIO_BUCKET: ${MINIO_BUCKET:-files} restart: unless-stopped depends_on: minio: condition: service_healthy # Ресурсные лимиты (шаг 0.4) mem_limit: 64m cpus: 0.25 pids_limit: 32 ollama: # Тег запинен: совпадает с версией на продакшене (ollama 0.30.10) image: ollama/ollama:0.30.10 profiles: - with-ollama ports: - "11434:11434" volumes: - ollama_data:/root/.ollama restart: unless-stopped healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:11434/api/tags || exit 1"] interval: 10s timeout: 5s retries: 12 start_period: 30s # Ресурсные лимиты (шаг 0.4) mem_limit: 2g cpus: 2.0 pids_limit: 64 document-worker: build: context: . dockerfile: docker/Dockerfile.documents env_file: - .env.local environment: - PORT=3000 volumes: - crm_data:/app/data restart: unless-stopped healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 30s # Ресурсные лимиты (шаг 0.4) mem_limit: 1g cpus: 1.0 pids_limit: 256 volumes: crm_data: crm_uploads: postgres_data: minio_data: ollama_data: