# ════════════════════════════════════════════════════════════ # مُصادَق (Musadaq) — Docker Compose # ════════════════════════════════════════════════════════════ # Services: NestJS API (3300) + PostgreSQL (5300) + Redis (6400) # Usage: docker compose up -d # ════════════════════════════════════════════════════════════ services: # ── NestJS API ───────────────────────────────────────── api: build: context: . dockerfile: Dockerfile container_name: musadaq-api restart: unless-stopped ports: - "${PORT:-3300}:${PORT:-3300}" environment: NODE_ENV: ${NODE_ENV:-development} PORT: ${PORT:-3300} DB_HOST: db DB_PORT: 5432 DB_USER: ${DB_USER} DB_PASS: ${DB_PASS} DB_NAME: ${DB_NAME} REDIS_HOST: redis REDIS_PORT: 6379 JWT_SECRET: ${JWT_SECRET} JWT_EXPIRY: ${JWT_EXPIRY} JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET} JWT_REFRESH_EXPIRY: ${JWT_REFRESH_EXPIRY} ENCRYPTION_KEY: ${ENCRYPTION_KEY} JOFOTARA_SANDBOX_URL: ${JOFOTARA_SANDBOX_URL} JOFOTARA_PROD_URL: ${JOFOTARA_PROD_URL} JOFOTARA_ENV: ${JOFOTARA_ENV} GEMINI_API_KEY: ${GEMINI_API_KEY} GEMINI_MODEL: ${GEMINI_MODEL} STORAGE_PATH: /app/uploads RESEND_API_KEY: ${RESEND_API_KEY} EMAIL_FROM: ${EMAIL_FROM} ALLOWED_ORIGINS: ${ALLOWED_ORIGINS} DOMAIN: ${DOMAIN} volumes: - invoice_uploads:/app/uploads depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - musadaq-network healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:${PORT:-3300}/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"] interval: 30s timeout: 10s retries: 3 start_period: 40s # ── PostgreSQL 16 ────────────────────────────────────── db: image: postgres:16-alpine container_name: musadaq-db restart: unless-stopped ports: - "${DB_PORT:-5300}:5432" environment: POSTGRES_USER: ${DB_USER:-musadaq_user} POSTGRES_PASSWORD: ${DB_PASS:-dev_password_min_32_chars_long_here!} POSTGRES_DB: ${DB_NAME:-musadaq_db} volumes: - postgres_data:/var/lib/postgresql/data networks: - musadaq-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-musadaq_user} -d ${DB_NAME:-musadaq_db}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # ── Redis 7 ──────────────────────────────────────────── redis: image: redis:7-alpine container_name: musadaq-redis restart: unless-stopped ports: - "${REDIS_PORT:-6400}:6379" command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data networks: - musadaq-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # ── Volumes ──────────────────────────────────────────────── volumes: postgres_data: driver: local redis_data: driver: local invoice_uploads: driver: local # ── Network ──────────────────────────────────────────────── networks: musadaq-network: driver: bridge