version: '3.8' services: # PostgreSQL Database postgres: image: postgres:16-alpine container_name: msp-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-mspmonitor} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} POSTGRES_DB: ${POSTGRES_DB:-msp_monitor} volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mspmonitor}"] interval: 10s timeout: 5s retries: 5 networks: - msp-network # Redis Cache redis: image: redis:7-alpine container_name: msp-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - redis_data:/data ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - msp-network # MSP Monitor Dashboard (Next.js App) dashboard: build: context: .. dockerfile: docker/Dockerfile container_name: msp-dashboard restart: unless-stopped environment: - NODE_ENV=production - DATABASE_URL=postgresql://${POSTGRES_USER:-mspmonitor}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-msp_monitor}?schema=public - REDIS_URL=redis://redis:6379 - JWT_SECRET=${JWT_SECRET} - MESHCENTRAL_URL=${MESHCENTRAL_URL} - MESHCENTRAL_USER=${MESHCENTRAL_USER} - MESHCENTRAL_PASS=${MESHCENTRAL_PASS} - MESHCENTRAL_DOMAIN=${MESHCENTRAL_DOMAIN:-default} - LIBRENMS_URL=${LIBRENMS_URL} - LIBRENMS_TOKEN=${LIBRENMS_TOKEN} - HEADWIND_URL=${HEADWIND_URL} - HEADWIND_TOKEN=${HEADWIND_TOKEN} - SMTP_HOST=${SMTP_HOST} - SMTP_PORT=${SMTP_PORT:-587} - SMTP_USER=${SMTP_USER} - SMTP_PASS=${SMTP_PASS} - SMTP_FROM=${SMTP_FROM} - NEXT_PUBLIC_APP_URL=${APP_URL:-http://localhost:3000} ports: - "3000:3000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - msp-network # Background Worker (Jobs) worker: build: context: .. dockerfile: docker/Dockerfile container_name: msp-worker restart: unless-stopped command: ["node", "dist/server/jobs/worker.js"] environment: - NODE_ENV=production - DATABASE_URL=postgresql://${POSTGRES_USER:-mspmonitor}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-msp_monitor}?schema=public - REDIS_URL=redis://redis:6379 - MESHCENTRAL_URL=${MESHCENTRAL_URL} - MESHCENTRAL_USER=${MESHCENTRAL_USER} - MESHCENTRAL_PASS=${MESHCENTRAL_PASS} - MESHCENTRAL_DOMAIN=${MESHCENTRAL_DOMAIN:-default} - LIBRENMS_URL=${LIBRENMS_URL} - LIBRENMS_TOKEN=${LIBRENMS_TOKEN} - HEADWIND_URL=${HEADWIND_URL} - HEADWIND_TOKEN=${HEADWIND_TOKEN} - SMTP_HOST=${SMTP_HOST} - SMTP_PORT=${SMTP_PORT:-587} - SMTP_USER=${SMTP_USER} - SMTP_PASS=${SMTP_PASS} - SMTP_FROM=${SMTP_FROM} depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - msp-network # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: msp-nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/ssl:/etc/nginx/ssl:ro - certbot_data:/var/www/certbot:ro depends_on: - dashboard networks: - msp-network # Certbot for SSL certbot: image: certbot/certbot container_name: msp-certbot volumes: - ./nginx/ssl:/etc/letsencrypt - certbot_data:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" networks: - msp-network volumes: postgres_data: redis_data: certbot_data: networks: msp-network: driver: bridge