Dify / start.sh
Pommsn's picture
Update start.sh
e76908e verified
#!/bin/bash
echo "πŸš€ Starting Dify All-in-One..."
set -x
cd /app/api
# 1. Database Migration (with timeout)
echo "πŸ—„οΈ Database migration..."
echo "πŸ“Š DB_TYPE=${DB_TYPE:-'not set'}"
echo "πŸ“Š DB_HOST=${DB_HOST:-'not set'}"
echo "πŸ“Š SQLALCHEMY_DATABASE_URI is $([ -n \"$SQLALCHEMY_DATABASE_URI\" ] && echo 'SET' || echo 'NOT SET')"
flask db upgrade 2>&1 || echo "⚠️ Migration failed or already done"
echo "πŸ—„οΈ Migration attempt complete"
# 2. Start Nginx FIRST (port 7860)
echo "🚦 Starting Nginx..."
nginx
# 3. Start API (port 5001)
echo "🧠 Starting API..."
# ULTIMATE FIX: Disable CSRF and patch cookies at app level
cat << 'APPWRAPPER_EOF' > /app/api/app_wrapper.py
"""
Ultimate HF Spaces Fix: Disable CSRF validation entirely and patch cookie settings.
CSRF isn't needed on HF Spaces because:
1. It's a single-user deployment
2. The proxy already handles some security
3. We need the app to work!
"""
import sys
import os
# Set environment variables BEFORE importing Flask app
os.environ['WTF_CSRF_ENABLED'] = 'false'
os.environ['CSRF_ENABLED'] = 'false'
os.environ['WTF_CSRF_CHECK_DEFAULT'] = 'false'
os.environ['SESSION_COOKIE_SAMESITE'] = 'None'
os.environ['SESSION_COOKIE_SECURE'] = 'true'
os.environ['CSRF_COOKIE_HTTPONLY'] = 'false'
sys.stderr.write("πŸ”§ CSRF DISABLE: Environment variables set\n")
sys.stderr.flush()
# Now import the Flask app
from app import app as flask_app
# Patch Flask config directly
flask_app.config.update(
WTF_CSRF_ENABLED=False,
WTF_CSRF_CHECK_DEFAULT=False,
CSRF_ENABLED=False,
SESSION_COOKIE_SAMESITE='None',
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
CSRF_COOKIE_HTTPONLY=False,
REMEMBER_COOKIE_SAMESITE='None',
REMEMBER_COOKIE_SECURE=True,
)
sys.stderr.write("πŸ”§ CSRF DISABLE: Flask config patched\n")
sys.stderr.flush()
# Try to disable Flask-WTF CSRF if it exists
try:
from flask_wtf.csrf import CSRFProtect
# Find and disable any CSRF protection instance
for key in list(flask_app.extensions.keys()):
if 'csrf' in key.lower():
sys.stderr.write(f"πŸ”§ Found CSRF extension: {key}\n")
# Disable CSRF for all views
flask_app.config['WTF_CSRF_ENABLED'] = False
sys.stderr.write("πŸ”§ CSRF DISABLE: Flask-WTF disabled\n")
except Exception as e:
sys.stderr.write(f"⚠️ Flask-WTF not found or error: {e}\n")
sys.stderr.flush()
# Try to find and patch Flask-Login cookie settings
try:
if hasattr(flask_app, 'login_manager'):
flask_app.login_manager.session_protection = None
sys.stderr.write("πŸ”§ Flask-Login: session_protection disabled\n")
except Exception as e:
sys.stderr.write(f"⚠️ Flask-Login patch error: {e}\n")
sys.stderr.flush()
# Cookie patching middleware for responses
class CookieFixMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
def custom_start_response(status, headers, exc_info=None):
new_headers = []
for name, value in headers:
if name.lower() == 'set-cookie':
import re
# Remove HttpOnly (so JS can read CSRF token)
value = value.replace('; HttpOnly', '').replace(';HttpOnly', '')
# Force SameSite=None
value = re.sub(r'SameSite=\w+', 'SameSite=None', value)
if 'SameSite=' not in value:
value += '; SameSite=None'
# Add Secure flag (required for SameSite=None)
if '; Secure' not in value:
value += '; Secure'
# CRITICAL: __Host- prefix requires Path=/
if '__Host-' in value and 'Path=' not in value:
value += '; Path=/'
# Remove any Domain attribute (__Host- prefix requirement)
value = re.sub(r'; Domain=[^;]+', '', value)
sys.stderr.write(f"πŸͺ Cookie: {value[:80]}...\n")
sys.stderr.flush()
new_headers.append((name, value))
return start_response(status, new_headers, exc_info)
return self.app(environ, custom_start_response)
# Wrap the app
app = CookieFixMiddleware(flask_app)
sys.stderr.write("βœ… APP WRAPPER READY: CSRF disabled + Cookie patching active!\n")
sys.stderr.flush()
APPWRAPPER_EOF
echo "πŸ”§ App wrapper with CSRF disable created!"
# Run Gunicorn with the patched app
gunicorn --bind 127.0.0.1:5001 --workers 1 --timeout 360 --forwarded-allow-ips='*' app_wrapper:app &
API_PID=$!
API_PID=$!
# 4. Start Web (port 3000) with correct API URLs
echo "🌐 Starting Web..."
cd /app/web
# Critical: Set environment
export NODE_ENV=production
export PORT=3000
export HOSTNAME=0.0.0.0
# API URLs
export NEXT_PUBLIC_API_PREFIX=/console/api
export NEXT_PUBLIC_PUBLIC_API_PREFIX=/api
export NEXT_PUBLIC_SENTRY_DSN=
export NEXT_TELEMETRY_DISABLED=1
# Edition and deploy env
export NEXT_PUBLIC_EDITION=${NEXT_PUBLIC_EDITION:-"SELF_HOSTED"}
export NEXT_PUBLIC_DEPLOY_ENV=${NEXT_PUBLIC_DEPLOY_ENV:-"PRODUCTION"}
export EDITION=${NEXT_PUBLIC_EDITION}
export DEPLOY_ENV=${NEXT_PUBLIC_DEPLOY_ENV}
# Security / Cookies (Critical for HF Spaces)
export SECRET_KEY=${SECRET_KEY:-"dify-secret-key-random-123456"}
export SESSION_COOKIE_SAMESITE="None"
export SESSION_COOKIE_SECURE="true"
export COOKIE_HTTPONLY="false"
export SESSION_COOKIE_HTTPONLY="true"
export CSRF_COOKIE_HTTPONLY="false"
export REMEMBER_COOKIE_SAMESITE="None"
export REMEMBER_COOKIE_SECURE="true"
export REMEMBER_COOKIE_HTTPONLY="true"
export REFRESH_TOKEN_COOKIE_SAMESITE="None"
export REFRESH_TOKEN_COOKIE_SECURE="true"
export REFRESH_TOKEN_COOKIE_HTTPONLY="true"
# Fix for invalid or missing user-agent in some environments
export FLASK_RUN_EXTRA_FILES=""
# Console URLs - must be set!
export CONSOLE_API_URL=${CONSOLE_API_URL:-"https://pommsn-dify.hf.space"}
export CONSOLE_WEB_URL=${CONSOLE_WEB_URL:-"https://pommsn-dify.hf.space"}
export APP_API_URL=${APP_API_URL:-"https://pommsn-dify.hf.space"}
export APP_WEB_URL=${APP_WEB_URL:-"https://pommsn-dify.hf.space"}
export SERVICE_API_URL=${SERVICE_API_URL:-"https://pommsn-dify.hf.space"}
# Server-side access to URLs (just in case)
export NEXT_PUBLIC_API_URL=${CONSOLE_API_URL}
# Fix for standalone mode (Required for 1.10.x and 1.11.x)
export NEXT_SHARP_PATH=/app/web/node_modules/sharp
export __NEXT_PRIVATE_STANDALONE_CONFIG=true
# Ensure internal API URL is set for SSR
export NEXT_PUBLIC_API_URL=${CONSOLE_API_URL}
echo "πŸ“Š CONSOLE_API_URL=${CONSOLE_API_URL}"
echo "πŸ“Š NODE_ENV=${NODE_ENV}"
node server.js &
WEB_PID=$!
echo "βœ… All services started!"
wait