# 🚀 Customer Portal - Plesk Docker Stack # Deploy via: Plesk → Docker → Stacks → Add Stack # Project name: customer-portal services: frontend: image: portal-frontend:latest container_name: portal-frontend network_mode: host environment: - NODE_ENV=production - PORT=3000 - HOSTNAME=0.0.0.0 - NEXT_PUBLIC_API_BASE=${NEXT_PUBLIC_API_BASE} - NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME} - NEXT_PUBLIC_APP_VERSION=${NEXT_PUBLIC_APP_VERSION} restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"] interval: 30s timeout: 10s start_period: 40s retries: 3 backend: image: portal-backend:latest container_name: portal-backend network_mode: host environment: - NODE_ENV=production - PORT=4000 - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - JWT_SECRET=${JWT_SECRET} - JWT_EXPIRES_IN=${JWT_EXPIRES_IN} - BCRYPT_ROUNDS=${BCRYPT_ROUNDS} - CORS_ORIGIN=${CORS_ORIGIN} - TRUST_PROXY=${TRUST_PROXY} - WHMCS_BASE_URL=${WHMCS_BASE_URL} - WHMCS_API_IDENTIFIER=${WHMCS_API_IDENTIFIER} - WHMCS_API_SECRET=${WHMCS_API_SECRET} - SF_LOGIN_URL=${SF_LOGIN_URL} - SF_CLIENT_ID=${SF_CLIENT_ID} - SF_PRIVATE_KEY_PATH=${SF_PRIVATE_KEY_PATH} - SF_USERNAME=${SF_USERNAME} - PORTAL_PRICEBOOK_ID=${PORTAL_PRICEBOOK_ID} - LOG_LEVEL=${LOG_LEVEL} - LOG_FORMAT=${LOG_FORMAT} - SENDGRID_API_KEY=${SENDGRID_API_KEY} - EMAIL_FROM=${EMAIL_FROM} - EMAIL_FROM_NAME=${EMAIL_FROM_NAME} - EMAIL_ENABLED=${EMAIL_ENABLED} - EMAIL_USE_QUEUE=${EMAIL_USE_QUEUE} - SENDGRID_SANDBOX=${SENDGRID_SANDBOX} - EMAIL_TEMPLATE_RESET=${EMAIL_TEMPLATE_RESET} - EMAIL_TEMPLATE_WELCOME=${EMAIL_TEMPLATE_WELCOME} - NODE_OPTIONS=${NODE_OPTIONS} volumes: - /var/www/vhosts/asolutions.jp/httpdocs/secrets:/app/secrets:ro restart: unless-stopped depends_on: database: condition: service_healthy cache: condition: service_healthy command: sh -c "pnpm prisma migrate deploy && node dist/main" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"] interval: 30s timeout: 10s start_period: 60s retries: 3 database: image: postgres:17-alpine container_name: portal-database network_mode: host environment: - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U portal -d portal_prod"] interval: 10s timeout: 5s retries: 5 cache: image: redis:7-alpine container_name: portal-cache network_mode: host volumes: - redis_data:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 volumes: postgres_data: driver: local redis_data: driver: local