services: app: build: . ports: - "3000:3000" environment: APP_BASE_URL: http://localhost:3000 AUTH_SECRET: local-dev-secret-change-me DATABASE_URL: postgres://kinresolve:kinresolve@postgres:5432/kinresolve KINRESOLVE_DEPLOYMENT_MODE: self-hosted KINRESOLVE_DATASET_MODE: demo KINRESOLVE_ARCHIVE_ID: archive-default KINRESOLVE_EXPORT_REFRESH_ENABLED: "true" KINRESOLVE_DESKTOP_MEDIA_ENABLED: "false" KINRESOLVE_MEDIA_LEGAL_REVIEW_APPROVED: "false" KINRESOLVE_ANCESTRY_API_ENABLED: "false" KINRESOLVE_ANCESTRY_PARTNER_APPROVED: "false" KINRESOLVE_OBJECT_STORAGE_BACKEND: s3 S3_ENDPOINT: http://minio:9000 S3_PUBLIC_ENDPOINT: http://localhost:9000 S3_BUCKET: ${S3_BUCKET:-kinresolve} MINIO_ROOT_USER: ${MINIO_ROOT_USER:?MINIO_ROOT_USER must be set in .env} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set in .env} AI_BASE_URL: ${AI_BASE_URL:-https://api.openai.com/v1} AI_API_KEY: ${AI_API_KEY:-} AI_API_MODE: ${AI_API_MODE:-responses} AI_CHAT_MODEL: ${AI_CHAT_MODEL:-gpt-5-mini} AI_EMBEDDING_MODEL: ${AI_EMBEDDING_MODEL:-text-embedding-3-small} depends_on: postgres: condition: service_healthy provision: condition: service_completed_successfully minio-init: condition: service_completed_successfully provision: build: context: . target: worker command: sh -c "npm run db:migrate && npm run archive:provision -- --mode demo" restart: "no" environment: DATABASE_URL: postgres://kinresolve:kinresolve@postgres:5432/kinresolve KINRESOLVE_DEPLOYMENT_MODE: self-hosted KINRESOLVE_DATASET_MODE: demo KINRESOLVE_ARCHIVE_ID: archive-default depends_on: postgres: condition: service_healthy worker: build: context: . target: worker command: npm run worker restart: unless-stopped environment: DATABASE_URL: postgres://kinresolve:kinresolve@postgres:5432/kinresolve KINRESOLVE_DEPLOYMENT_MODE: self-hosted KINRESOLVE_DATASET_MODE: demo KINRESOLVE_ARCHIVE_ID: archive-default KINRESOLVE_EXPORT_REFRESH_ENABLED: "true" KINRESOLVE_DESKTOP_MEDIA_ENABLED: "false" KINRESOLVE_MEDIA_LEGAL_REVIEW_APPROVED: "false" KINRESOLVE_ANCESTRY_API_ENABLED: "false" KINRESOLVE_ANCESTRY_PARTNER_APPROVED: "false" KINRESOLVE_OBJECT_STORAGE_BACKEND: s3 KINRESOLVE_WORKER_ID: compose-worker KINRESOLVE_WORKER_MAX_JOBS_PER_RUN: 25 KINRESOLVE_WORKER_LEASE_DURATION_MS: 300000 KINRESOLVE_WORKER_POLL_INTERVAL_MS: 2000 KINRESOLVE_WORKER_MAINTENANCE_INTERVAL_MS: 900000 KINRESOLVE_WORKER_MAINTENANCE_LIMIT: 100 KINRESOLVE_MALWARE_SCANNER: clamd KINRESOLVE_CLAMD_HOST: clamav KINRESOLVE_CLAMD_PORT: 3310 KINRESOLVE_MALWARE_SCAN_TIMEOUT_MS: 30000 KINRESOLVE_MALWARE_SCAN_MAX_BYTES: 25165824 S3_ENDPOINT: http://minio:9000 S3_BUCKET: ${S3_BUCKET:-kinresolve} MINIO_ROOT_USER: ${MINIO_ROOT_USER:?MINIO_ROOT_USER must be set in .env} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set in .env} AI_BASE_URL: ${AI_BASE_URL:-https://api.openai.com/v1} AI_API_KEY: ${AI_API_KEY:-} AI_API_MODE: ${AI_API_MODE:-responses} AI_CHAT_MODEL: ${AI_CHAT_MODEL:-gpt-5-mini} AI_EMBEDDING_MODEL: ${AI_EMBEDDING_MODEL:-text-embedding-3-small} depends_on: postgres: condition: service_healthy provision: condition: service_completed_successfully minio-init: condition: service_completed_successfully clamav: condition: service_healthy clamav: image: clamav/clamav:1.4 restart: unless-stopped expose: - "3310" volumes: - clamav-data:/var/lib/clamav healthcheck: test: ["CMD-SHELL", "clamdscan --ping=1 >/dev/null 2>&1"] interval: 10s timeout: 5s retries: 30 start_period: 60s postgres: image: pgvector/pgvector:pg16 environment: POSTGRES_DB: kinresolve POSTGRES_USER: kinresolve POSTGRES_PASSWORD: kinresolve ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U kinresolve -d kinresolve"] interval: 2s timeout: 5s retries: 30 start_period: 5s minio: # MinIO removed minio/minio from Docker Hub (~2026-09-11); use Pigsty's # community rebuild instead (same entrypoint, bundles mc at /usr/bin/mc). image: pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:?MINIO_ROOT_USER must be set in .env} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set in .env} MINIO_API_CORS_ALLOW_ORIGIN: http://localhost:3000 ports: - "127.0.0.1:9000:9000" - "127.0.0.1:9001:9001" volumes: - minio-data:/data minio-init: # minio/mc was removed from Docker Hub too; reuse the image above for its # bundled mc. The entrypoint override keeps it from starting a server. image: pgsty/minio@sha256:b6bfe7239bfc83fb90d31612d9704d86039dd714f7904b3f1ad68f211e602372 depends_on: - minio environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:?MINIO_ROOT_USER must be set in .env} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set in .env} S3_BUCKET: ${S3_BUCKET:-kinresolve} entrypoint: > /bin/sh -c ' until mc alias set local http://minio:9000 "$${MINIO_ROOT_USER}" "$${MINIO_ROOT_PASSWORD}"; do sleep 1; done; mc mb --ignore-existing "local/$${S3_BUCKET}"; mc anonymous set none "local/$${S3_BUCKET}"; ' volumes: postgres-data: minio-data: clamav-data: