# ERP Nutzfahrzeuge — Production Docker Compose # Services: backend (FastAPI), frontend (Next.js), postgres, redis # Compatible with Coolify Docker Compose deployment services: # ============ Backend (FastAPI + uvicorn) ============ backend: build: context: ./backend dockerfile: Dockerfile container_name: erp-backend restart: unless-stopped expose: - "8000" environment: - DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB} - REDIS_URL=redis://redis:6379/0 - JWT_SECRET=${JWT_SECRET} - JWT_ALGORITHM=${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES=${JWT_ACCESS_TTL_MINUTES:-15} - JWT_REFRESH_TTL_DAYS=${JWT_REFRESH_TTL_DAYS:-7} - CORS_ORIGINS=${CORS_ORIGINS} - UPLOAD_DIR=/data/uploads - WEASYPRINT_OUTPUT_DIR=/tmp/contracts - APP_NAME=${APP_NAME:-ERP Nutzfahrzeuge} - APP_ENV=production - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} - OPENROUTER_BASE_URL=${OPENROUTER_BASE_URL:-https://openrouter.ai/api/v1} - OPENROUTER_OCR_MODEL=${OPENROUTER_OCR_MODEL:-qwen/qwen2.5-vl-72b-instruct} - MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50} - MOBILE_DE_API_KEY=${MOBILE_DE_API_KEY} - MOBILE_DE_SELLER_ID=${MOBILE_DE_SELLER_ID} - BZST_API_ENABLED=${BZST_API_ENABLED:-false} volumes: - uploads:/data/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health"] interval: 30s timeout: 5s retries: 3 start_period: 15s networks: - erp-network # ============ Frontend (Next.js standalone) ============ frontend: build: context: ./frontend dockerfile: Dockerfile args: - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:8000/api/v1} container_name: erp-frontend restart: unless-stopped expose: - "3000" environment: - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:8000/api/v1} - NODE_ENV=production - HOSTNAME=0.0.0.0 - PORT=3000 depends_on: backend: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/"] interval: 30s timeout: 5s retries: 3 start_period: 10s networks: - erp-network # ============ PostgreSQL 16 ============ postgres: image: postgres:16-alpine container_name: erp-postgres restart: unless-stopped environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 start_period: 10s networks: - erp-network # ============ Redis 7 ============ redis: image: redis:7-alpine container_name: erp-redis restart: unless-stopped command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redisdata:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 5s networks: - erp-network # ============ Volumes ============ volumes: uploads: driver: local pgdata: driver: local redisdata: driver: local # ============ Networks ============ networks: erp-network: driver: bridge