Upload 3 files
Browse files
README.md
CHANGED
|
@@ -26,6 +26,10 @@ app_port: 7860
|
|
| 26 |
- `DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DBNAME?sslmode=require&channel_binding=require`
|
| 27 |
- `REDIS_URL=rediss://:PASSWORD@HOST:PORT/0`
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
## 建议配置(无默认值)
|
| 30 |
- JWT_SECRET
|
| 31 |
- TOTP_ENCRYPTION_KEY
|
|
@@ -34,11 +38,15 @@ app_port: 7860
|
|
| 34 |
|
| 35 |
## 可选环境变量(含默认值)
|
| 36 |
- PORT=7860
|
| 37 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
- TZ=Asia/Shanghai
|
| 39 |
- DATA_DIR=/tmp/sub2api
|
| 40 |
|
| 41 |
## 说明
|
| 42 |
- Hugging Face Docker Space 默认端口是 7860,可通过 `app_port` 覆盖。([huggingface.co](https://huggingface.co/docs/hub/spaces-sdks-docker?utm_source=openai))
|
| 43 |
- 空间里通常需要把可写目录放在 `/tmp`;如启用持久化存储,可使用 `/data`。([huggingface.co](https://huggingface.co/docs/hub/spaces-storage?utm_source=openai))([discuss.huggingface.co](https://discuss.huggingface.co/t/permission-denied-for-writing-files-within-spaces/29799?utm_source=openai))
|
| 44 |
-
-
|
|
|
|
| 26 |
- `DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DBNAME?sslmode=require&channel_binding=require`
|
| 27 |
- `REDIS_URL=rediss://:PASSWORD@HOST:PORT/0`
|
| 28 |
|
| 29 |
+
## 脚本行为
|
| 30 |
+
- 启动脚本会把 `DATABASE_URL` / `REDIS_URL` 解析为应用实际需要的 `DATABASE_*` / `REDIS_*` 变量。
|
| 31 |
+
- 不要在 HF 变量里加引号(否则解析会失败)。
|
| 32 |
+
|
| 33 |
## 建议配置(无默认值)
|
| 34 |
- JWT_SECRET
|
| 35 |
- TOTP_ENCRYPTION_KEY
|
|
|
|
| 38 |
|
| 39 |
## 可选环境变量(含默认值)
|
| 40 |
- PORT=7860
|
| 41 |
+
- SERVER_HOST=0.0.0.0
|
| 42 |
+
- SERVER_PORT=7860
|
| 43 |
+
- SERVER_MODE=release
|
| 44 |
+
- RUN_MODE=standard
|
| 45 |
+
- AUTO_SETUP=true
|
| 46 |
- TZ=Asia/Shanghai
|
| 47 |
- DATA_DIR=/tmp/sub2api
|
| 48 |
|
| 49 |
## 说明
|
| 50 |
- Hugging Face Docker Space 默认端口是 7860,可通过 `app_port` 覆盖。([huggingface.co](https://huggingface.co/docs/hub/spaces-sdks-docker?utm_source=openai))
|
| 51 |
- 空间里通常需要把可写目录放在 `/tmp`;如启用持久化存储,可使用 `/data`。([huggingface.co](https://huggingface.co/docs/hub/spaces-storage?utm_source=openai))([discuss.huggingface.co](https://discuss.huggingface.co/t/permission-denied-for-writing-files-within-spaces/29799?utm_source=openai))
|
| 52 |
+
- 应用侧实际使用 `DATABASE_*` / `REDIS_*` 变量(见官方 compose 示例)。([github.com](https://github.com/Wei-Shaw/sub2api/blob/main/docker-compose.yml?utm_source=openai))
|
start.sh
CHANGED
|
@@ -14,6 +14,30 @@ set -eu
|
|
| 14 |
mkdir -p "$DATA_DIR" "$BIN_DIR" || true
|
| 15 |
chmod 777 "$DATA_DIR" "$BIN_DIR" 2>/dev/null || true
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
require_env() {
|
| 18 |
name="$1"
|
| 19 |
eval "val=\${$name:-}"
|
|
@@ -23,9 +47,161 @@ require_env() {
|
|
| 23 |
fi
|
| 24 |
}
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
require_env DATABASE_URL
|
| 27 |
require_env REDIS_URL
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
export PORT SERVER_HOST SERVER_PORT SERVER_MODE RUN_MODE AUTO_SETUP TZ DATA_DIR
|
| 30 |
|
| 31 |
copy_and_exec() {
|
|
|
|
| 14 |
mkdir -p "$DATA_DIR" "$BIN_DIR" || true
|
| 15 |
chmod 777 "$DATA_DIR" "$BIN_DIR" 2>/dev/null || true
|
| 16 |
|
| 17 |
+
strip_quotes() {
|
| 18 |
+
val="$1"
|
| 19 |
+
case "$val" in
|
| 20 |
+
"\""*"\"") val="${val#\"}"; val="${val%\"}" ;;
|
| 21 |
+
esac
|
| 22 |
+
case "$val" in
|
| 23 |
+
"'"*"'") val="${val#'}"; val="${val%'}" ;;
|
| 24 |
+
esac
|
| 25 |
+
printf '%s' "$val"
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
url_decode() {
|
| 29 |
+
printf '%b' "$(printf '%s' "$1" | sed 's/+/ /g; s/%/\\x/g')"
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
get_query_param() {
|
| 33 |
+
query="$1"
|
| 34 |
+
key="$2"
|
| 35 |
+
if [ -z "$query" ]; then
|
| 36 |
+
return 0
|
| 37 |
+
fi
|
| 38 |
+
printf '%s' "$query" | tr '&' '\n' | awk -F= -v k="$key" '$1==k {print $2; exit}'
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
require_env() {
|
| 42 |
name="$1"
|
| 43 |
eval "val=\${$name:-}"
|
|
|
|
| 47 |
fi
|
| 48 |
}
|
| 49 |
|
| 50 |
+
parse_database_url() {
|
| 51 |
+
url="$1"
|
| 52 |
+
rest="${url#*://}"
|
| 53 |
+
base="$rest"
|
| 54 |
+
query=""
|
| 55 |
+
|
| 56 |
+
if [ "$rest" != "${rest%%\?*}" ]; then
|
| 57 |
+
base="${rest%%\?*}"
|
| 58 |
+
query="${rest#*\?}"
|
| 59 |
+
fi
|
| 60 |
+
|
| 61 |
+
userinfo="${base%%@*}"
|
| 62 |
+
hostport_db="${base#*@}"
|
| 63 |
+
if [ "$hostport_db" = "$base" ]; then
|
| 64 |
+
userinfo=""
|
| 65 |
+
hostport_db="$base"
|
| 66 |
+
fi
|
| 67 |
+
|
| 68 |
+
hostport="${hostport_db%%/*}"
|
| 69 |
+
dbname="${hostport_db#*/}"
|
| 70 |
+
if [ "$dbname" = "$hostport_db" ]; then
|
| 71 |
+
dbname=""
|
| 72 |
+
fi
|
| 73 |
+
|
| 74 |
+
user=""
|
| 75 |
+
pass=""
|
| 76 |
+
if [ -n "$userinfo" ]; then
|
| 77 |
+
case "$userinfo" in
|
| 78 |
+
*:*)
|
| 79 |
+
user="${userinfo%%:*}"
|
| 80 |
+
pass="${userinfo#*:}"
|
| 81 |
+
;;
|
| 82 |
+
*)
|
| 83 |
+
user="$userinfo"
|
| 84 |
+
pass=""
|
| 85 |
+
;;
|
| 86 |
+
esac
|
| 87 |
+
fi
|
| 88 |
+
|
| 89 |
+
host="${hostport%%:*}"
|
| 90 |
+
port="${hostport#*:}"
|
| 91 |
+
if [ "$port" = "$hostport" ]; then
|
| 92 |
+
port=""
|
| 93 |
+
fi
|
| 94 |
+
|
| 95 |
+
[ -n "$user" ] && export DATABASE_USER="$(url_decode "$user")"
|
| 96 |
+
[ -n "$pass" ] && export DATABASE_PASSWORD="$(url_decode "$pass")"
|
| 97 |
+
[ -n "$host" ] && export DATABASE_HOST="$(url_decode "$host")"
|
| 98 |
+
[ -n "$dbname" ] && export DATABASE_DBNAME="$(url_decode "$dbname")"
|
| 99 |
+
[ -n "$port" ] && export DATABASE_PORT="$port"
|
| 100 |
+
|
| 101 |
+
sslmode="$(get_query_param "$query" "sslmode")"
|
| 102 |
+
if [ -n "$sslmode" ]; then
|
| 103 |
+
export DATABASE_SSLMODE="$(url_decode "$sslmode")"
|
| 104 |
+
else
|
| 105 |
+
: "${DATABASE_SSLMODE:=require}"
|
| 106 |
+
fi
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
parse_redis_url() {
|
| 110 |
+
url="$1"
|
| 111 |
+
scheme="${url%%://*}"
|
| 112 |
+
rest="${url#*://}"
|
| 113 |
+
base="$rest"
|
| 114 |
+
query=""
|
| 115 |
+
|
| 116 |
+
if [ "$rest" != "${rest%%\?*}" ]; then
|
| 117 |
+
base="${rest%%\?*}"
|
| 118 |
+
query="${rest#*\?}"
|
| 119 |
+
fi
|
| 120 |
+
|
| 121 |
+
userinfo="${base%%@*}"
|
| 122 |
+
hostport_db="${base#*@}"
|
| 123 |
+
if [ "$hostport_db" = "$base" ]; then
|
| 124 |
+
userinfo=""
|
| 125 |
+
hostport_db="$base"
|
| 126 |
+
fi
|
| 127 |
+
|
| 128 |
+
hostport="${hostport_db%%/*}"
|
| 129 |
+
dbname="${hostport_db#*/}"
|
| 130 |
+
if [ "$dbname" = "$hostport_db" ] || [ -z "$dbname" ]; then
|
| 131 |
+
dbname=""
|
| 132 |
+
fi
|
| 133 |
+
|
| 134 |
+
pass=""
|
| 135 |
+
if [ -n "$userinfo" ]; then
|
| 136 |
+
case "$userinfo" in
|
| 137 |
+
*:*)
|
| 138 |
+
pass="${userinfo#*:}"
|
| 139 |
+
;;
|
| 140 |
+
*)
|
| 141 |
+
pass=""
|
| 142 |
+
;;
|
| 143 |
+
esac
|
| 144 |
+
fi
|
| 145 |
+
|
| 146 |
+
host="${hostport%%:*}"
|
| 147 |
+
port="${hostport#*:}"
|
| 148 |
+
if [ "$port" = "$hostport" ]; then
|
| 149 |
+
port=""
|
| 150 |
+
fi
|
| 151 |
+
|
| 152 |
+
[ -n "$host" ] && export REDIS_HOST="$(url_decode "$host")"
|
| 153 |
+
[ -n "$port" ] && export REDIS_PORT="$port"
|
| 154 |
+
[ -n "$pass" ] && export REDIS_PASSWORD="$(url_decode "$pass")"
|
| 155 |
+
|
| 156 |
+
db_query="$(get_query_param "$query" "db")"
|
| 157 |
+
if [ -n "$db_query" ]; then
|
| 158 |
+
dbname="$db_query"
|
| 159 |
+
fi
|
| 160 |
+
[ -n "$dbname" ] && export REDIS_DB="$(url_decode "$dbname")"
|
| 161 |
+
|
| 162 |
+
tls="false"
|
| 163 |
+
tls_query="$(get_query_param "$query" "ssl")"
|
| 164 |
+
if [ -z "$tls_query" ]; then
|
| 165 |
+
tls_query="$(get_query_param "$query" "tls")"
|
| 166 |
+
fi
|
| 167 |
+
if [ -n "$tls_query" ]; then
|
| 168 |
+
case "$(url_decode "$tls_query")" in
|
| 169 |
+
1|true|TRUE|True|yes|YES|on|ON)
|
| 170 |
+
tls="true"
|
| 171 |
+
;;
|
| 172 |
+
*)
|
| 173 |
+
tls="false"
|
| 174 |
+
;;
|
| 175 |
+
esac
|
| 176 |
+
else
|
| 177 |
+
if [ "$scheme" = "rediss" ]; then
|
| 178 |
+
tls="true"
|
| 179 |
+
fi
|
| 180 |
+
fi
|
| 181 |
+
export REDIS_ENABLE_TLS="$tls"
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
require_env DATABASE_URL
|
| 185 |
require_env REDIS_URL
|
| 186 |
|
| 187 |
+
DATABASE_URL="$(strip_quotes "$DATABASE_URL")"
|
| 188 |
+
REDIS_URL="$(strip_quotes "$REDIS_URL")"
|
| 189 |
+
export DATABASE_URL REDIS_URL
|
| 190 |
+
|
| 191 |
+
parse_database_url "$DATABASE_URL"
|
| 192 |
+
parse_redis_url "$REDIS_URL"
|
| 193 |
+
|
| 194 |
+
: "${DATABASE_DBNAME:=sub2api}"
|
| 195 |
+
: "${DATABASE_PORT:=5432}"
|
| 196 |
+
: "${DATABASE_SSLMODE:=require}"
|
| 197 |
+
: "${REDIS_PORT:=6379}"
|
| 198 |
+
: "${REDIS_DB:=0}"
|
| 199 |
+
|
| 200 |
+
require_env DATABASE_HOST
|
| 201 |
+
require_env DATABASE_USER
|
| 202 |
+
require_env DATABASE_PASSWORD
|
| 203 |
+
require_env REDIS_HOST
|
| 204 |
+
|
| 205 |
export PORT SERVER_HOST SERVER_PORT SERVER_MODE RUN_MODE AUTO_SETUP TZ DATA_DIR
|
| 206 |
|
| 207 |
copy_and_exec() {
|