version: '3.8' services: # ─── PostgreSQL ────────────────────────────── postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: cloudhost POSTGRES_USER: cloudhost POSTGRES_PASSWORD: cloudhost_secret ports: - '5432:5432' volumes: - pg_data:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -U cloudhost'] interval: 5s timeout: 3s retries: 10 # ─── Redis ─────────────────────────────────── redis: image: redis:7-alpine restart: unless-stopped ports: - '6379:6379' volumes: - redis_data:/data healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 5s timeout: 3s retries: 10 # ─── Backend (NestJS) ─────────────────────── backend: build: context: ./backend dockerfile: Dockerfile restart: unless-stopped ports: - '4000:4000' depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: NODE_ENV: development PORT: 4000 # Database DB_HOST: postgres DB_PORT: 5432 DB_USERNAME: cloudhost DB_PASSWORD: cloudhost_secret DB_DATABASE: cloudhost # JWT JWT_SECRET: change-this-to-a-long-random-string JWT_REFRESH_SECRET: change-this-to-a-long-random-refresh-string JWT_EXPIRES_IN: 15m JWT_REFRESH_EXPIRES_IN: 7d # Redis REDIS_HOST: redis REDIS_PORT: 6379 # Container Registry REGISTRY_URL: registry.example.com REGISTRY_USERNAME: '' REGISTRY_PASSWORD: '' # Build BUILD_NAMESPACE: cloudhost-builds KANIKO_IMAGE: gcr.io/kaniko-project/executor:v1.23.2 # Platform FRONTEND_URL: http://localhost:3000 PLATFORM_DOMAIN: apps.localhost volumes: - /tmp/cloudhost-uploads:/app/uploads # ─── Frontend (Next.js) ───────────────────── frontend: build: context: ./frontend dockerfile: Dockerfile restart: unless-stopped ports: - '3000:3000' depends_on: - backend environment: NEXT_PUBLIC_API_URL: http://localhost:4000 volumes: pg_data: redis_data: