File size: 6,740 Bytes
8dd2df5 7bfcdc2 aa9d504 563f9b6 2a61894 7bb08cb e69fcaa 7bfcdc2 91e3d95 7bfcdc2 e69fcaa 7bfcdc2 16781b9 e76908e 802decb e76908e 8faf0f7 e76908e 802decb e76908e 8faf0f7 802decb e76908e 8faf0f7 e76908e 802decb 8faf0f7 e76908e 8faf0f7 e76908e 802decb 8faf0f7 e76908e 802decb e76908e 8faf0f7 e76908e 8faf0f7 e76908e e69fcaa 7bfcdc2 e69fcaa 7bfcdc2 e69fcaa 56e9088 e69fcaa b03d607 16781b9 553a626 56e9088 1ac3a12 b03d607 1ac3a12 e985de5 d4fee68 e985de5 d4fee68 56e9088 d4fee68 1ac3a12 7bfcdc2 e69fcaa 5b80172 aa9d504 | 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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | #!/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 |