| #!/bin/bash |
| set -e |
|
|
| echo "Starting Dify services..." |
|
|
| |
| 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 |
|
|
| |
| check_redis() { |
| local max_attempts=30 |
| local attempt=1 |
| |
| |
| 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 |
| |
| |
| 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 |
| } |
|
|
| |
| check_redis || { |
| echo "Failed to connect to Redis after all attempts" |
| exit 1 |
| } |
|
|
| |
| 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 |
|
|
| |
| cd /app/api |
|
|
| |
| 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 |
|
|
| |
| echo "Starting API server on port 7860..." |
| gunicorn --bind 0.0.0.0:7860 \ |
| --workers 1 \ |
| --worker-class gevent \ |
| --timeout 200 \ |
| --preload \ |
| app:app & |
|
|
| |
| cd /app/web |
| echo "Starting Next.js server on port 3000..." |
|
|
| |
| if [ ! -d ".next/standalone" ]; then |
| echo "Error: Next.js standalone build not found" |
| exit 1 |
| fi |
|
|
| |
| if [ -d ".next/static" ]; then |
| mkdir -p .next/standalone/.next |
| cp -r .next/static .next/standalone/.next/ |
| fi |
|
|
| |
| 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 |
|
|
| |
| export MALLOC_ARENA_MAX=2 |
| export NODE_OPTIONS="--max-old-space-size=2048" |