Spaces:
Building
Building
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" |