#!/bin/bash set -e echo "Starting Dify services..." # Database connection check based on type if [ "${DATABASE_TYPE}" = "sqlite" ]; then echo "Using SQLite database at ${SQLITE_PATH}" mkdir -p $(dirname "${SQLITE_PATH}") touch "${SQLITE_PATH}" else check_postgres() { local max_attempts=30 local attempt=1 while [ $attempt -le $max_attempts ]; do echo "Checking PostgreSQL connection to ${DB_HOST}:${DB_PORT} (attempt $attempt/$max_attempts)..." if pg_isready -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USERNAME}" -d "${DB_DATABASE}"; then return 0 fi attempt=$((attempt + 1)) sleep 5 done return 1 } if ! check_postgres; then echo "Failed to connect to PostgreSQL, falling back to SQLite..." export DATABASE_TYPE="sqlite" mkdir -p $(dirname "${SQLITE_PATH}") touch "${SQLITE_PATH}" fi fi # Redis connection check function with HF Spaces compatibility check_redis() { local max_attempts=30 local attempt=1 # Ensure Redis is installed if ! command -v redis-server >/dev/null 2>&1; then echo "Redis server not found, installing..." apt-get update && apt-get install -y redis-server fi # For HF Spaces, start local Redis by default if [ "${REDIS_TYPE}" = "local" ] || [ "${SPACE_ID}" != "" ]; then echo "Starting local Redis server..." mkdir -p /data/redis redis-server --daemonize yes --dir /data/redis --port 6379 --requirepass "${REDIS_PASSWORD:-difyai123456}" export REDIS_HOST=localhost sleep 2 if redis-cli -h localhost -p 6379 -a "${REDIS_PASSWORD:-difyai123456}" ping > /dev/null 2>&1; then echo "Local Redis server started successfully" return 0 fi fi while [ $attempt -le $max_attempts ]; do if redis-cli -h "${REDIS_HOST}" -p "${REDIS_PORT}" -a "${REDIS_PASSWORD}" ping > /dev/null 2>&1; then echo "Redis is ready!" return 0 fi echo "Redis is unavailable (attempt $attempt/$max_attempts) - retrying..." attempt=$((attempt + 1)) sleep 5 if [ $attempt -eq $max_attempts ]; then echo "Falling back to local Redis..." export REDIS_TYPE="local" export REDIS_HOST=localhost mkdir -p /data/redis redis-server --daemonize yes --dir /data/redis --port 6379 --requirepass "${REDIS_PASSWORD:-difyai123456}" sleep 2 if redis-cli -h localhost -p 6379 -a "${REDIS_PASSWORD:-difyai123456}" ping > /dev/null 2>&1; then echo "Local Redis server started successfully" return 0 fi fi done return 1 } # Try to connect to Redis check_redis || { echo "Failed to connect to Redis after all attempts" exit 1 } # Install Python dependencies if not in pre-built image if [ "${INSTALL_DEPENDENCIES}" = "true" ]; then cd /app/api echo "Installing Python dependencies..." if [ -f "requirements.txt" ]; then pip install --no-cache-dir -r requirements.txt elif [ -f "../requirements.txt" ]; then pip install --no-cache-dir -r ../requirements.txt else echo "Using pre-installed dependencies from Docker image" fi else echo "Using pre-installed dependencies from Docker image" fi # Ensure we're in the correct directory for database operations cd /app/api # Initialize database if needed if [ ! -f ".db_initialized" ]; then echo "Running database migrations..." FLASK_APP=app.py flask db upgrade if [ $? -eq 0 ]; then touch .db_initialized echo "Database initialization completed successfully" else echo "Database initialization failed" exit 1 fi fi # Start services echo "Starting API server on port 7860..." gunicorn --bind 0.0.0.0:7860 \ --workers 1 \ --worker-class gevent \ --timeout 200 \ --preload \ app:app & # Start Next.js web server cd /app/web echo "Starting Next.js server on port 3000..." # Ensure standalone directory exists if [ ! -d ".next/standalone" ]; then echo "Error: Next.js standalone build not found" exit 1 fi # Copy static files if they exist if [ -d ".next/static" ]; then mkdir -p .next/standalone/.next cp -r .next/static .next/standalone/.next/ fi # Copy public files if they exist if [ -d "public" ]; then cp -r public .next/standalone/ fi cd .next/standalone echo "Starting Next.js standalone server..." NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ node server.js & # Wait for both processes wait # Add to entrypoint.sh export MALLOC_ARENA_MAX=2 export NODE_OPTIONS="--max-old-space-size=2048"