services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER must be set in .env} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env} POSTGRES_DB: ${POSTGRES_DB:?POSTGRES_DB must be set in .env} volumes: - pgdata:/var/lib/postgresql/data # 호스트 포트 노출 안 함 — app 컨테이너만 내부 네트워크로 접근. # 외부 DB 클라이언트(예: psql)가 필요하면 아래 주석 해제 (LAN 노출은 위험): # ports: # - "127.0.0.1:5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER}"] interval: 5s timeout: 5s retries: 5 migrate: profiles: ["tools"] image: node:22-alpine working_dir: /app environment: DATABASE_URL: postgresql://${POSTGRES_USER:?required}:${POSTGRES_PASSWORD:?required}@db:5432/${POSTGRES_DB:?required} volumes: - .:/app - migrate_node_modules:/app/node_modules depends_on: db: condition: service_healthy command: sh -c "npm ci && npx prisma migrate deploy" app: build: context: . dockerfile: Dockerfile restart: unless-stopped ports: # 127.0.0.1 바인딩 — 같은 머신에서만 접근 가능 (LAN 노출 방지) - "127.0.0.1:3000:3000" environment: DATABASE_URL: postgresql://${POSTGRES_USER:?required}:${POSTGRES_PASSWORD:?required}@db:5432/${POSTGRES_DB:?required} GEMINI_API_KEY: ${GEMINI_API_KEY:-} volumes: - uploads:/app/uploads depends_on: db: condition: service_healthy test: profiles: ["tools"] image: node:22-alpine working_dir: /app environment: CI: "true" volumes: - .:/app - test_node_modules:/app/node_modules command: sh -c "npm ci && npm test" volumes: pgdata: uploads: test_node_modules: migrate_node_modules: