services: # Redis cache service on custom port 6380 (instead of default 6379) redis: image: redis:7-alpine container_name: pulse-redis restart: unless-stopped ports: - "6380:6379" volumes: - redis_data:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 logging: driver: json-file options: max-size: "10m" max-file: "5" # PostgreSQL database for Autotask sync postgres: image: postgres:16-alpine container_name: pulse-postgres restart: unless-stopped ports: - "5432:5432" env_file: - .env.local environment: POSTGRES_DB: ${POSTGRES_DB:-pulse_autotask} POSTGRES_USER: ${POSTGRES_USER:-pulse_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./migrations:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-pulse_user} -d ${POSTGRES_DB:-pulse_autotask}"] interval: 10s timeout: 5s retries: 5 logging: driver: json-file options: max-size: "10m" max-file: "5" # Next.js application on port 3100 (instead of 3000) app: build: context: . dockerfile: Dockerfile container_name: pulse-app restart: unless-stopped ports: - "3100:3100" labels: - "traefik.enable=true" - "traefik.http.routers.pulse.rule=Host(`pulse.wulfconsulting.cloud`)" - "traefik.http.routers.pulse.entrypoints=websecure" - "traefik.http.routers.pulse.tls=true" - "traefik.http.routers.pulse.tls.certresolver=cloudflare" - "traefik.http.services.pulse.loadbalancer.server.port=3100" - "traefik.docker.network=frontend" networks: - default - frontend env_file: - .env.local environment: # Application settings NODE_ENV: production PORT: 3100 # Redis configuration REDIS_URL: redis://redis:6379 # Autotask API Configuration AUTOTASK_API_URL: ${AUTOTASK_API_URL} AUTOTASK_USERNAME: ${AUTOTASK_USERNAME} AUTOTASK_SECRET: ${AUTOTASK_SECRET} AUTOTASK_API_INTEGRATION_CODE: ${AUTOTASK_API_INTEGRATION_CODE} # Datto RMM API Configuration DATTO_RMM_API_URL: ${DATTO_RMM_API_URL} DATTO_RMM_API_KEY: ${DATTO_RMM_API_KEY} DATTO_RMM_API_SECRET: ${DATTO_RMM_API_SECRET} # Addigy API Configuration ADDIGY_API_URL: ${ADDIGY_API_URL} ADDIGY_API_TOKEN: ${ADDIGY_API_TOKEN} ADDIGY_ORG_ID: ${ADDIGY_ORG_ID} # Auvik API Configuration AUVIK_API_URL: ${AUVIK_API_URL} AUVIK_API_USER: ${AUVIK_API_USER} AUVIK_API_KEY: ${AUVIK_API_KEY} # SalesBldr API Configuration SALESBLDR_API_URL: ${SALESBLDR_API_URL} SALESBLDR_API_KEY: ${SALESBLDR_API_KEY} # Veeam VSPC Configuration VEEAM_VSPC_URL: ${VEEAM_VSPC_URL} VEEAM_VSPC_API_KEY: ${VEEAM_VSPC_API_KEY} VEEAM_RPO_SHADOW_MODE: "true" ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} # Zabbix API Configuration ZABBIX_API_URL: ${ZABBIX_API_URL} ZABBIX_API_TOKEN: ${ZABBIX_API_TOKEN} # ipinfo.io API token (optional) IPINFO_TOKEN: ${IPINFO_TOKEN:-} # Mimecast API Configuration MIMECAST_CLIENT_ID: ${MIMECAST_CLIENT_ID} MIMECAST_CLIENT_SECRET: ${MIMECAST_CLIENT_SECRET} MIMECAST_BASE_URL: ${MIMECAST_BASE_URL:-https://api.services.mimecast.com} MIMECAST_ACCOUNT_CODE: ${MIMECAST_ACCOUNT_CODE} # IT Glue Configuration ITGLUE_API_KEY: ${ITGLUE_API_KEY} # Backblaze B2 Storage (S3-compatible) B2_KEY_ID: ${B2_KEY_ID} B2_APP_KEY: ${B2_APP_KEY} B2_BUCKET: ${B2_BUCKET:-wulf-audits} B2_REGION: ${B2_REGION:-us-west-002} B2_ENDPOINT: ${B2_ENDPOINT:-s3.us-west-002.backblazeb2.com} # Webhook Configuration WEBHOOK_BASE_URL: ${WEBHOOK_BASE_URL:-https://pulse.wulfconsulting.cloud} AUTOTASK_WEBHOOK_SECRET: ${AUTOTASK_WEBHOOK_SECRET} # PostgreSQL Configuration POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_DB: ${POSTGRES_DB:-pulse_autotask} POSTGRES_USER: ${POSTGRES_USER:-pulse_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-your_secure_password_here_change_in_production} DATABASE_URL: postgresql://${POSTGRES_USER:-pulse_user}:${POSTGRES_PASSWORD:-your_secure_password_here_change_in_production}@postgres:5432/${POSTGRES_DB:-pulse_autotask} depends_on: redis: condition: service_healthy postgres: condition: service_healthy volumes: # Mount .env.local for development (remove in production) - ./.env.local:/app/.env.local:ro logging: driver: json-file options: max-size: "10m" max-file: "5" volumes: redis_data: driver: local postgres_data: driver: local networks: default: name: pulse-network frontend: external: true