File size: 4,829 Bytes
a4bef0b
 
 
12e3afc
 
46a883c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53d8b27
46a883c
 
 
 
 
 
8a398ad
 
3ec4c07
8f2f82d
7d9cc10
 
 
895529e
 
 
 
 
 
3ec4c07
 
 
895529e
 
3ec4c07
 
 
 
 
 
 
 
7d9cc10
3ec4c07
 
7d9cc10
 
 
 
 
 
 
 
 
3ec4c07
895529e
 
3ec4c07
 
 
 
 
7d9cc10
 
 
8f2f82d
 
7d9cc10
 
 
 
6612613
 
a311353
 
 
 
 
 
 
 
 
 
 
c400468
a311353
c400468
781b198
a311353
 
 
781b198
53d8b27
8f2f82d
f8b477a
8f2f82d
 
 
 
 
 
 
53d8b27
 
8f2f82d
e3a6f0b
 
a4bef0b
 
 
 
 
 
12e3afc
a4bef0b
12e3afc
070b654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12e3afc
070b654
 
 
 
a4bef0b
12e3afc
e26861f
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/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"