Spaces:
Paused
Paused
File size: 11,852 Bytes
d454b01 2509e3a 0f909e7 2509e3a 0f909e7 d454b01 2509e3a 5100142 2509e3a 5100142 d454b01 5100142 84736b9 d6428cd ba3d054 f3d1f3e b392634 965af9a 46a24dc 965af9a 984c120 965af9a b392634 2509e3a 0f909e7 d454b01 5100142 d454b01 334d2a0 d454b01 5100142 334d2a0 5100142 d454b01 5100142 334d2a0 5100142 0f909e7 5100142 d454b01 2509e3a d454b01 115355f d454b01 029ea4c 940e285 984c120 029ea4c 803cf0b 029ea4c 965af9a 029ea4c 46a24dc 029ea4c 20879c5 029ea4c 6fe053e 334d2a0 6fe053e 029ea4c 803cf0b f87affc 36811bc 6fe053e 334d2a0 029ea4c |
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 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
#!/bin/bash
set -e
# Use /tmp for all writable data
export DATA_DIR="/tmp/open-webui-data"
export HF_STORAGE_REPO="${HF_STORAGE_REPO:-nxdev-org/open-webui-storage}"
export SYNC_INTERVAL="${SYNC_INTERVAL:-300}"
# Set all HuggingFace and cache directories to /tmp
export HF_HOME="/tmp/hf_cache"
export HUGGINGFACE_HUB_CACHE="/tmp/hf_cache"
export TRANSFORMERS_CACHE="/tmp/hf_cache"
export SENTENCE_TRANSFORMERS_HOME="/tmp/hf_cache"
# Override Open WebUI environment variables
export STATIC_DIR="/tmp/static"
export UPLOAD_DIR="/tmp/uploads"
echo "Starting Open WebUI with HF Dataset persistence..."
echo "Data directory: $DATA_DIR"
echo "HF Repository: $HF_STORAGE_REPO"
echo "HF Cache: $HF_HOME"
# insytall uv, custom installer
mkdir -p /tmp/bin
export UV_CACHE_DIR="/tmp/uv_cache"
curl -LsSf https://astral.sh/uv/install.sh | env UV_UNMANAGED_INSTALL="/tmp/bin" UV_CACHE_DIR="/tmp/uv_cache" sh
#source /tmp/bin/env
export PATH="/tmp/bin:$PATH"
# set nvm cache directory
export NPM_CONFIG_CACHE=/tmp/.npm_cache
export XDG_CONFIG_HOME=/tmp/.config
# <--- ADD THIS LINE for Caddy's config
export XDG_DATA_HOME=/tmp/.local/share
# <--- ADD THIS LINE for Caddy's data/locks (equivalent to ~/.local/share)
# Ensure the custom config and data directories exist and are writable
# These will be created by 'appuser' if `USER appuser` is active, or by root if before.
# Since they are in /tmp, 'appuser' will have write permissions regardless if created by root.
mkdir -p ${XDG_CONFIG_HOME}/caddy \
${XDG_DATA_HOME}/caddy/locks
# Ensure the custom cache directory exists for npm (though /tmp generally is fine)
# It's good practice to create it, and it will be owned by `appuser` if `USER appuser` is active.
# No need to mkdir for UV_CACHE_DIR as uv will create it if needed.
mkdir -p ${NPM_CONFIG_CACHE}
source ${HOME}/add_bash_util.sh
source "${NVM_DIR}/nvm.sh"
node -v && npm -v
uv venv /tmp/.venv
source /tmp/.venv/bin/activate
uv pip install --no-cache-dir \
huggingface_hub \
datasets
# Create all necessary directories
mkdir -p "$DATA_DIR" "$HF_HOME" "$STATIC_DIR" "$UPLOAD_DIR"
# Copy static files to writable location
if [ -d "/app/backend/open_webui/static" ]; then
echo "Copying static files to writable location..."
cp -r /app/backend/open_webui/static/* "$STATIC_DIR/" 2>/dev/null || true
fi
# Test write permissions
if touch "$DATA_DIR/test" 2>/dev/null; then
rm "$DATA_DIR/test"
echo "Data directory is writable"
else
echo "Warning: Data directory may not be writable"
fi
# Check if HF_TOKEN is set
if [ -z "$HF_TOKEN" ]; then
echo "Warning: HF_TOKEN not set. Sync functionality will be limited."
else
echo "HF_TOKEN is set, proceeding with sync..."
fi
# Download existing data on startup
echo "Syncing data from Hugging Face..."
python3 ${HOME}/sync_storage.py download
# Function to handle graceful shutdown
cleanup() {
echo "Shutting down gracefully..."
# Upload final data state
if [ -n "$HF_TOKEN" ]; then
echo "Uploading final data state..."
python3 ${HOME}/sync_storage.py upload
fi
# Kill background processes
kill $SYNC_PID 2>/dev/null || true
kill $WEBUI_PID 2>/dev/null || true
exit 0
}
# Set up signal handlers
trap cleanup SIGTERM SIGINT
# Background sync function
background_sync() {
if [ -n "$HF_TOKEN" ]; then
while true; do
sleep $SYNC_INTERVAL
echo "Periodic sync to Hugging Face..."
python3 ${HOME}/sync_storage.py upload
done
else
echo "Skipping background sync - no HF_TOKEN"
while true; do
sleep 3600
done
fi
}
# Start background sync
background_sync &
SYNC_PID=$!
# Start Open WebUI
echo "Starting Open WebUI..."
# Set environment variables for Open WebUI
export WEBUI_SECRET_KEY="${WEBUI_SECRET_KEY:-$(openssl rand -hex 32)}"
# Start Open WebUI in background
# deactivate uv
deactivate && /app/backend/start.sh &
WEBUI_PID=$!
# Wait for Open WebUI process
# wait $WEBUI_PID
# readeck
mkdir -p $DATA_DIR/readeck-data
readeck_url=$(curl -X 'GET' 'https://codeberg.org/api/v1/repos/readeck/readeck/releases/latest' -H 'accept: application/json' | jq -r '.assets[] | .browser_download_url | select(. | endswith("linux-amd64"))')
echo download readeck from $readeck_url
wget -q $readeck_url -O $DATA_DIR/readeck-data/readeck
chmod a+x $DATA_DIR/readeck-data/readeck
cp ${HOME}/readeck.toml $DATA_DIR/readeck-data/readeck.toml
echo "Starting readeck..."
cd $DATA_DIR/readeck-data && ./readeck serve -config ./readeck.toml &
gh_install caddyserver/caddy linux_amd64.tar.gz /tmp/caddy.tar.gz
mkdir -p /tmp/caddy
tar -xzf /tmp/caddy.tar.gz -C /tmp/caddy
# Start the Node.js application
git clone https://github.com/waxz/Gemini-CLI-2-API.git /tmp/Gemini-CLI-2-API -b waxz-patch-1
git clone https://github.com/waxz/gemini-cli-openai /tmp/gemini-cli-openai
git clone https://github.com/snailyp/gemini-balance.git /tmp/gemini-balance
source /tmp/.venv/bin/activate
uv pip install -r /tmp/gemini-balance/requirements.txt
cat << EOF | tee /tmp/Gemini-CLI-2-API/config.json
{
"REQUIRED_API_KEY": "${REQUIRED_API_KEY:-}",
"SERVER_PORT": 3000,
"HOST": "localhost",
"MODEL_PROVIDER": "gemini-cli-oauth",
"OPENAI_API_KEY": "${OPENAI_API_KEY:-}",
"OPENAI_BASE_URL": "https://api.openai.com/v1",
"CLAUDE_API_KEY": "${CLAUDE_API_KEY:-}",
"CLAUDE_BASE_URL": "https://api.anthropic.com/v1",
"PROJECT_ID": "${PROJECT_ID:-}",
"PROMPT_LOG_MODE": "console",
"GEMINI_OAUTH_CREDS_FILE_PATH":"/tmp/gemini_oauth_creds.json"
}
EOF
cat << EOF | tee /tmp/gemini_oauth_creds.json
{
"access_token": "${GEMINI_OAUTH_ACCESS_TOKEN:-}",
"refresh_token": "${GEMINI_OAUTH_REFRESH_TOKEN:-}",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"token_type": "Bearer",
"expiry_date": 1753880406425
}
EOF
cat << EOF | tee /tmp/gemini-balance/.env
# 数据库配置
DATABASE_TYPE=mysql
#SQLITE_DATABASE=default_db
MYSQL_HOST=${MYSQL_HOST}
#MYSQL_SOCKET=/run/mysqld/mysqld.sock
MYSQL_PORT=${MYSQL_PORT}
MYSQL_USER=${MYSQL_USER}
MYSQL_PASSWORD=${MYSQL_PASSWORD}
MYSQL_DATABASE=${MYSQL_DATABASE}
API_KEYS=${GEMINI_API_KEYS}
ALLOWED_TOKENS=["${REQUIRED_API_KEY}"]
AUTH_TOKEN=${REQUIRED_API_KEY}
# For Vertex AI Platform API Keys
VERTEX_API_KEYS=["AQ.Abxxxxxxxxxxxxxxxxxxx"]
# For Vertex AI Platform Express API Base URL
VERTEX_EXPRESS_BASE_URL=https://aiplatform.googleapis.com/v1beta1/publishers/google
TEST_MODEL=gemini-1.5-flash
THINKING_MODELS=["gemini-2.5-flash-preview-04-17"]
THINKING_BUDGET_MAP={"gemini-2.5-flash-preview-04-17": 4000}
IMAGE_MODELS=["gemini-2.0-flash-exp"]
SEARCH_MODELS=["gemini-2.0-flash-exp","gemini-2.0-pro-exp"]
FILTERED_MODELS=["gemini-1.0-pro-vision-latest", "gemini-pro-vision", "chat-bison-001", "text-bison-001", "embedding-gecko-001"]
# 是否启用网址上下文,默认启用
URL_CONTEXT_ENABLED=false
URL_CONTEXT_MODELS=["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash","gemini-2.0-flash-live-001"]
TOOLS_CODE_EXECUTION_ENABLED=false
SHOW_SEARCH_LINK=true
SHOW_THINKING_PROCESS=true
BASE_URL=https://generativelanguage.googleapis.com/v1beta
MAX_FAILURES=10
MAX_RETRIES=3
CHECK_INTERVAL_HOURS=1
TIMEZONE=Asia/Shanghai
# 请求超时时间(秒)
TIME_OUT=300
# 代理服务器配置 (支持 http 和 socks5)
# 示例: PROXIES=["http://user:pass@host:port", "socks5://host:port"]
PROXIES=[]
# 对同一个API_KEY使用代理列表中固定的IP策略
PROXIES_USE_CONSISTENCY_HASH_BY_API_KEY=true
#########################image_generate 相关配置###########################
PAID_KEY=AIzaSyxxxxxxxxxxxxxxxxxxx
CREATE_IMAGE_MODEL=imagen-3.0-generate-002
UPLOAD_PROVIDER=smms
SMMS_SECRET_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PICGO_API_KEY=xxxx
CLOUDFLARE_IMGBED_URL=https://xxxxxxx.pages.dev/upload
CLOUDFLARE_IMGBED_AUTH_CODE=xxxxxxxxx
CLOUDFLARE_IMGBED_UPLOAD_FOLDER=
##########################################################################
#########################stream_optimizer 相关配置########################
STREAM_OPTIMIZER_ENABLED=false
STREAM_MIN_DELAY=0.016
STREAM_MAX_DELAY=0.024
STREAM_SHORT_TEXT_THRESHOLD=10
STREAM_LONG_TEXT_THRESHOLD=50
STREAM_CHUNK_SIZE=5
##########################################################################
######################### 日志配置 #######################################
# 日志级别 (debug, info, warning, error, critical),默认为 info
LOG_LEVEL=info
# 是否开启自动删除错误日志
AUTO_DELETE_ERROR_LOGS_ENABLED=true
# 自动删除多少天前的错误日志 (1, 7, 30)
AUTO_DELETE_ERROR_LOGS_DAYS=7
# 是否开启自动删除请求日志
AUTO_DELETE_REQUEST_LOGS_ENABLED=false
# 自动删除多少天前的请求日志 (1, 7, 30)
AUTO_DELETE_REQUEST_LOGS_DAYS=30
##########################################################################
# 假流式配置 (Fake Streaming Configuration)
# 是否启用假流式输出
FAKE_STREAM_ENABLED=True
# 假流式发送空数据的间隔时间(秒)
FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS=5
# 安全设置 (JSON 字符串格式)
# 注意:这里的示例值可能需要根据实际模型支持情况调整
SAFETY_SETTINGS=[{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "OFF"}, {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "OFF"}, {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "OFF"}, {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "OFF"}, {"category": "HARM_CATEGORY_CIVIC_INTEGRITY", "threshold": "BLOCK_NONE"}]
URL_NORMALIZATION_ENABLED=false
# tts配置
TTS_MODEL=gemini-2.5-flash-preview-tts
TTS_VOICE_NAME=Zephyr
TTS_SPEED=normal
#########################Files API 相关配置########################
# 是否启用文件过期自动清理
FILES_CLEANUP_ENABLED=true
# 文件过期清理间隔(小时)
FILES_CLEANUP_INTERVAL_HOURS=1
# 是否启用用户文件隔离(每个用户只能看到自己上传的文件)
FILES_USER_ISOLATION_ENABLED=true
##########################################################################
EOF
cat << EOF | tee /tmp/gemini-cli-openai/.dev.vars.test
# Required: OAuth2 credentials JSON from Gemini CLI authentication
GCP_SERVICE_ACCOUNT=${GCP_SERVICE_ACCOUNT}
# Optional: Google Cloud Project ID (auto-discovered if not set)
GEMINI_PROJECT_ID=${GEMINI_PROJECT_ID}
# Optional: API key for authentication (if not set, API is public)
# When set, clients must include "Authorization: Bearer <your-api-key>" header
# Example: sk-1234567890abcdef1234567890abcdef
OPENAI_API_KEY=${REQUIRED_API_KEY}
EOF
${HOME}/crypt.sh decrypt ${HOME}/gemini/enc.dev.var.x -e GEMINI_AUTH_ENC_PASS -o /tmp/gemini-cli-openai/.dev.var.x
${HOME}/crypt.sh decrypt ${HOME}/gemini/enc.dev.var.j -e GEMINI_AUTH_ENC_PASS -o /tmp/gemini-cli-openai/.dev.var.j
${HOME}/crypt.sh decrypt ${HOME}/gemini/enc.dev.var.w -e GEMINI_AUTH_ENC_PASS -o /tmp/gemini-cli-openai/.dev.var.w
${HOME}/crypt.sh decrypt ${HOME}/gemini/enc.dev.var.l -e GEMINI_AUTH_ENC_PASS -o /tmp/gemini-cli-openai/.dev.var.l
cd /tmp/Gemini-CLI-2-API && npm install && node src/api-server.js &
cd /tmp/gemini-balance && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload &
cd /tmp/gemini-cli-openai && npm i
cp /tmp/gemini-cli-openai/.dev.var.j /tmp/gemini-cli-openai/.dev.vars
echo "check /tmp/gemini-cli-openai/.dev.vars"
cat /tmp/gemini-cli-openai/.dev.vars
cd /tmp/gemini-cli-openai && npx wrangler dev --port 8881 --host 0.0.0.0 &
# cd /tmp/gemini-cli-openai && npm i && npx wrangler dev --port 8882 --host 0.0.0.0 --env j &
# cd /tmp/gemini-cli-openai && npm i && npx wrangler dev --port 8883 --host 0.0.0.0 --env w &
# cd /tmp/gemini-cli-openai && npm i && npx wrangler dev --port 8884 --host 0.0.0.0 --env l &
/tmp/caddy/caddy run --config ${HOME}/Caddyfile &
MAIN_PID=$!
# Wait for caddy process
wait $MAIN_PID
|