grok2api_B / entrypoint.sh
OwenPowell's picture
Update entrypoint.sh
849f235 verified
#!/bin/sh
set -e
echo "=== Entrypoint Started ==="
export TZ="Asia/Shanghai"
CONFIG="/app/data/config.toml"
mkdir -p /app/data /app/logs
# ============================================================
# 1. 每次启动都重新生成 config.toml
# ============================================================
cat > "$CONFIG" <<EOT
[app]
app_url = "__APP_URL__"
app_key = "__APP_KEY__"
api_key = "__API_KEY__"
[proxy]
base_proxy_url = "__PROXY_BASE_URL__"
user_agent = "__PROXY_UA__"
EOT
sed -i "s|__APP_URL__|${APP_APP_URL:-}|g" "$CONFIG"
sed -i "s|__APP_KEY__|${APP_KEY:-grok2api}|g" "$CONFIG"
sed -i "s|__API_KEY__|${API_KEY:-}|g" "$CONFIG"
sed -i "s|__PROXY_BASE_URL__|${PROXY_BASE_URL:-}|g" "$CONFIG"
sed -i "s|__PROXY_UA__|${PROXY_UA:-}|g" "$CONFIG"
echo "=== config.toml generated ==="
cat "$CONFIG"
# ============================================================
# 2. 修复 Supabase Pooler 兼容性
#
# Supabase 连接模式:
# - pooler:6543 = Transaction mode(不支持 prepared statements)❌
# - pooler:5432 = Session mode(支持 prepared statements,IPv4)✅
# - db.xxx:5432 = 直连(IPv6 only,HF Spaces 不支持)❌
#
# grok2api 用 asyncpg,依赖 prepared statements
# 所以必须用 Session mode (pooler:5432)
#
# 修复:自动将 pooler 端口 6543 → 5432(Session mode)
# ============================================================
export SERVER_STORAGE_TYPE="${SERVER_STORAGE_TYPE:-pgsql}"
export LOG_LEVEL="${LOG_LEVEL:-DEBUG}"
if [ -n "$SERVER_STORAGE_URL" ]; then
case "$SERVER_STORAGE_URL" in
*pooler.supabase.com:6543*)
export SERVER_STORAGE_URL=$(echo "$SERVER_STORAGE_URL" | sed 's|:6543/|:5432/|g')
echo "=== Fixed Supabase: port 6543 (Transaction) -> 5432 (Session) ==="
;;
esac
echo "=== Storage URL: $(echo $SERVER_STORAGE_URL | sed 's|://.*@|://***@|') ==="
fi
# ============================================================
# 3. 启动前同步环境变量到数据库(如果表已存在)
# ============================================================
if [ -n "$SERVER_STORAGE_URL" ]; then
echo "=== Attempting to sync env vars to database ==="
python3 << 'PYEOF'
import asyncio, json, os, sys
async def sync_config():
try:
import asyncpg
raw_url = os.environ.get("SERVER_STORAGE_URL", "")
dsn = raw_url.replace("postgresql+asyncpg://", "postgresql://")
conn = await asyncpg.connect(dsn)
try:
table_exists = await conn.fetchval("""
SELECT EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_name = 'app_config'
)
""")
if not table_exists:
print("app_config table not yet created, config.toml will be used at first startup")
return
overrides = [
("app", "app_key", os.environ.get("APP_KEY", "")),
("app", "api_key", os.environ.get("API_KEY", "")),
("app", "app_url", os.environ.get("APP_APP_URL", "")),
("proxy", "base_proxy_url", os.environ.get("PROXY_BASE_URL", "")),
("proxy", "user_agent", os.environ.get("PROXY_UA", "")),
]
for section, key, value in overrides:
if not value:
continue
json_value = json.dumps(value)
existing = await conn.fetchval(
"SELECT value FROM app_config WHERE section = $1 AND key_name = $2",
section, key
)
if existing is not None:
await conn.execute(
"UPDATE app_config SET value = $1 WHERE section = $2 AND key_name = $3",
json_value, section, key
)
print(f" Updated [{section}].{key}")
else:
await conn.execute(
"INSERT INTO app_config (section, key_name, value) VALUES ($1, $2, $3)",
section, key, json_value
)
print(f" Inserted [{section}].{key}")
print("=== Database config synced successfully ===")
finally:
await conn.close()
except Exception as e:
print(f"=== DB sync warning (non-fatal): {e} ===", file=sys.stderr)
asyncio.run(sync_config())
PYEOF
fi
# ============================================================
# 4. 启动服务
# ============================================================
if [ -f /app/scripts/init_storage.sh ]; then
/app/scripts/init_storage.sh || echo "=== DB Init Skipped ==="
else
echo "=== init_storage.sh not found, skipping ==="
fi
echo "=== Starting Server ==="
cd /app
# 激活虚拟环境(如果存在)
if [ -f /opt/venv/bin/activate ]; then
echo "=== Activating virtual environment ==="
. /opt/venv/bin/activate
fi
# 尝试多种方式启动 uvicorn
if command -v uvicorn >/dev/null 2>&1; then
exec uvicorn main:app --host 0.0.0.0 --port 8000
elif /opt/venv/bin/python3 -m uvicorn --version >/dev/null 2>&1; then
exec /opt/venv/bin/python3 -m uvicorn main:app --host 0.0.0.0 --port 8000
elif command -v python3 >/dev/null 2>&1; then
exec python3 -m uvicorn main:app --host 0.0.0.0 --port 8000
elif command -v python >/dev/null 2>&1; then
exec python -m uvicorn main:app --host 0.0.0.0 --port 8000
else
echo "ERROR: Neither uvicorn nor python found!"
exit 1
fi