#!/bin/sh set -e # ============================================================================= # Docker Entrypoint Script # ============================================================================= # Handles runtime setup before starting the application: # - Waits for database and cache dependencies # - Decodes SF_PRIVATE_KEY_BASE64 to file if provided # - Runs Prisma migrations if RUN_MIGRATIONS=true # ============================================================================= echo "🚀 Starting Customer Portal Backend..." echo " Version: ${APP_VERSION:-unknown}" echo " Node: $(node --version)" PRISMA_VERSION="${PRISMA_VERSION:-7.1.0}" export PRISMA_SCHEMA_PATH="/app/prisma/schema.prisma" # ============================================================================= # Salesforce Private Key Handling # ============================================================================= if [ -n "$SF_PRIVATE_KEY_BASE64" ]; then echo "📝 Decoding Salesforce private key..." mkdir -p /app/secrets echo "$SF_PRIVATE_KEY_BASE64" | base64 -d > /app/secrets/sf-private.key chmod 600 /app/secrets/sf-private.key export SF_PRIVATE_KEY_PATH=/app/secrets/sf-private.key echo "✅ Salesforce private key configured" fi # ============================================================================= # Wait for Dependencies # ============================================================================= # Maximum wait time in seconds MAX_WAIT="${MAX_WAIT:-120}" wait_for_service() { local host="$1" local port="$2" local name="$3" local waited=0 echo "⏳ Waiting for $name ($host:$port)..." while ! nc -z "$host" "$port" 2>/dev/null; do waited=$((waited + 2)) if [ $waited -ge "$MAX_WAIT" ]; then echo "❌ Timeout waiting for $name after ${MAX_WAIT}s" return 1 fi sleep 2 done echo "✅ $name is ready (waited ${waited}s)" return 0 } # Wait for database if DATABASE_URL is set # Extract host:port from postgresql://user:pass@host:port/db if [ -n "$DATABASE_URL" ]; then DB_HOST=$(echo "$DATABASE_URL" | sed -E 's|.*@([^:/]+):([0-9]+)/.*|\1|') DB_PORT=$(echo "$DATABASE_URL" | sed -E 's|.*@([^:/]+):([0-9]+)/.*|\2|') if [ -n "$DB_HOST" ] && [ -n "$DB_PORT" ]; then if ! wait_for_service "$DB_HOST" "$DB_PORT" "database"; then echo "⚠️ Starting without database connection - some features may not work" fi fi fi # Wait for Redis if REDIS_URL is set # Extract host:port from redis://host:port/db or redis://:password@host:port/db if [ -n "$REDIS_URL" ]; then # Handle both redis://host:port and redis://:password@host:port formats REDIS_HOST=$(echo "$REDIS_URL" | sed -E 's|redis://([^:@]+@)?([^:/]+):([0-9]+).*|\2|') REDIS_PORT=$(echo "$REDIS_URL" | sed -E 's|redis://([^:@]+@)?([^:/]+):([0-9]+).*|\3|') if [ -n "$REDIS_HOST" ] && [ -n "$REDIS_PORT" ]; then if ! wait_for_service "$REDIS_HOST" "$REDIS_PORT" "cache"; then echo "⚠️ Starting without Redis connection - some features may not work" fi fi fi # ============================================================================= # Database Migrations # ============================================================================= if [ "$RUN_MIGRATIONS" = "true" ] && [ -n "$DATABASE_URL" ]; then echo "🗄️ Running database migrations..." # Set Prisma schema path for migration export PRISMA_SCHEMA_PATH="/app/prisma/schema.prisma" # Change to app directory where schema is located cd /app if pnpm dlx prisma@"${PRISMA_VERSION}" migrate deploy; then echo "✅ Migrations complete" else echo "⚠️ Migration failed - check database connectivity" # Continue anyway in case migrations are already applied fi fi # ============================================================================= # Start Application # ============================================================================= echo "🌐 Starting server on port ${PORT:-4000}..." echo " Environment: ${NODE_ENV:-development}" echo " Log level: ${LOG_LEVEL:-info}" echo "" # Execute the main command (node dist/main.js) exec "$@"