services: # Database postgres: image: postgres:15-alpine container_name: vulnmanager-db environment: POSTGRES_USER: ${POSTGRES_USER:-vulnmanager} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD env var must be set} POSTGRES_DB: ${POSTGRES_DB:-vulnmanager} volumes: - postgres_data:/var/lib/postgresql/data ports: - "127.0.0.1:${POSTGRES_PORT:-5432}:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-vulnmanager} -d ${POSTGRES_DB:-vulnmanager}"] interval: 10s timeout: 5s retries: 5 networks: - vulnmanager-net restart: unless-stopped # Backend (API + Worker) backend: image: vulnmanager-backend:latest build: context: . dockerfile: Dockerfile container_name: vulnmanager-backend env_file: - .env environment: TZ: ${TIMEZONE:-UTC} DATABASE_URL: postgresql://${POSTGRES_USER:-vulnmanager}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD env var must be set}@postgres:5432/${POSTGRES_DB:-vulnmanager} POSTGRES_HOST: postgres ports: - "127.0.0.1:${BACKEND_PORT:-8000}:8000" depends_on: postgres: condition: service_healthy volumes: - static_volume:/app/static networks: - vulnmanager-net restart: unless-stopped # Frontend (Next.js) frontend: image: vulnmanager-frontend:latest build: context: ./frontend dockerfile: Dockerfile target: runner container_name: vulnmanager-frontend environment: TZ: ${TIMEZONE:-UTC} # Browser-Public API URL (leave empty to use same-origin) NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-} ports: - "${FRONTEND_PORT:-3000}:3000" networks: - vulnmanager-net restart: unless-stopped volumes: postgres_data: static_volume: networks: vulnmanager-net: driver: bridge