caidao78 commited on
Commit
dc4ea8d
·
verified ·
1 Parent(s): a69e380

Upload 5 files

Browse files
Dockerfile CHANGED
@@ -1,10 +1,19 @@
1
- FROM --platform=linux/amd64/v3 xxnuo/mtranserver:latest
2
 
3
- # 复制模型文件到容器中
4
- COPY ./models /app/models
 
 
 
5
 
6
- # 暴露端口
7
- EXPOSE 8989
 
8
 
9
- # 设置环境变量
10
- ENV CORE_API_TOKEN=88888888
 
 
 
 
 
 
1
+ FROM alpine:3.21
2
 
3
+ ENV TZ=Asia/Shanghai
4
+ ENV RUNTIME_DIR=/tmp/cliproxyapi
5
+ ENV SUPERVISOR_CONF=/etc/supervisord.conf
6
+ ENV UPDATE_INTERVAL_SECONDS=14400
7
+ ENV STOP_WAIT_SECS=60
8
 
9
+ RUN apk add --no-cache ca-certificates curl supervisor tzdata \
10
+ && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
11
+ && echo $TZ > /etc/timezone
12
 
13
+ COPY entrypoint.sh /usr/local/bin/entrypoint.sh
14
+ COPY scripts/release-common.sh /usr/local/bin/release-common.sh
15
+ COPY scripts/update-loop.sh /usr/local/bin/update-loop.sh
16
+ COPY supervisord.conf /etc/supervisord.conf
17
+ RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/release-common.sh /usr/local/bin/update-loop.sh
18
+
19
+ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
entrypoint.sh ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ : "${RELEASE_COMMON_SH:=/usr/local/bin/release-common.sh}"
5
+ : "${SUPERVISORD_BIN:=/usr/bin/supervisord}"
6
+ : "${OPEN_FILE_LIMIT:=65535}"
7
+
8
+ . "$RELEASE_COMMON_SH"
9
+
10
+ export RUNTIME_DIR
11
+ export SUPERVISOR_CONF
12
+
13
+ shell_quote() {
14
+ printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\"'\"'/g")"
15
+ }
16
+
17
+ write_run_app_script() {
18
+ run_app_script="$RUNTIME_DIR/run-app.sh"
19
+
20
+ {
21
+ printf '#!/bin/sh\n'
22
+ printf 'set -eu\n'
23
+ printf 'exec "%s"' "$(current_binary_path)"
24
+ for arg in "$@"; do
25
+ printf ' %s' "$(shell_quote "$arg")"
26
+ done
27
+ printf '\n'
28
+ } > "$run_app_script"
29
+
30
+ chmod +x "$run_app_script"
31
+ }
32
+
33
+ prepare_runtime_environment() {
34
+ ulimit -n "$OPEN_FILE_LIMIT"
35
+ ensure_runtime_dirs
36
+ rm -f "$RUNTIME_DIR/supervisor.sock" "$RUNTIME_DIR/supervisord.pid"
37
+ }
38
+
39
+ bootstrap_release_or_exit() {
40
+ if ! ensure_initial_release; then
41
+ echo "错误: 初次启动时无法准备可运行版本" >&2
42
+ exit 1
43
+ fi
44
+ }
45
+
46
+ start_supervisord() {
47
+ exec "$SUPERVISORD_BIN" -c "$SUPERVISOR_CONF"
48
+ }
49
+
50
+ main() {
51
+ prepare_runtime_environment
52
+ bootstrap_release_or_exit
53
+ write_run_app_script "$@"
54
+ start_supervisord
55
+ }
56
+
57
+ main "$@"
scripts/release-common.sh ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ : "${REPO_API_URL:=https://api.github.com/repos/caidaoli/CLIProxyAPI/releases/latest}"
4
+ : "${RUNTIME_DIR:=/tmp/cliproxyapi}"
5
+ : "${RELEASES_DIR:=$RUNTIME_DIR/releases}"
6
+ : "${CURRENT_LINK:=$RUNTIME_DIR/current}"
7
+ : "${CURRENT_TAG_FILE:=$RUNTIME_DIR/current.tag}"
8
+ : "${DOWNLOADS_DIR:=$RUNTIME_DIR/downloads}"
9
+ : "${SUPERVISOR_CONF:=/etc/supervisord.conf}"
10
+ : "${SUPERVISOR_PROGRAM_NAME:=cliproxyapi}"
11
+ : "${CURRENT_BINARY_NAME:=cli-proxy-api}"
12
+ : "${APP_BINARY_NAMES:=cli-proxy-api CLIProxyAPI}"
13
+
14
+ log() {
15
+ timestamp=$(date '+%Y-%m-%d %H:%M:%S %z')
16
+ printf '[%s] %s\n' "$timestamp" "$*" >&2
17
+ }
18
+
19
+ tag_to_dir_name() {
20
+ printf '%s\n' "$1" | tr '/:' '__'
21
+ }
22
+
23
+ release_dir_for_tag() {
24
+ printf '%s/%s\n' "$RELEASES_DIR" "$(tag_to_dir_name "$1")"
25
+ }
26
+
27
+ ensure_runtime_dirs() {
28
+ mkdir -p "$RUNTIME_DIR" "$RELEASES_DIR" "$DOWNLOADS_DIR"
29
+ }
30
+
31
+ current_tag() {
32
+ if [ -f "$CURRENT_TAG_FILE" ]; then
33
+ tr -d '\n' < "$CURRENT_TAG_FILE"
34
+ fi
35
+ }
36
+
37
+ current_binary_path() {
38
+ printf '%s/%s\n' "$CURRENT_LINK" "$CURRENT_BINARY_NAME"
39
+ }
40
+
41
+ fetch_latest_release_info() {
42
+ response=$(curl -fsSL "$REPO_API_URL") || return 1
43
+
44
+ tag_name=$(
45
+ printf '%s\n' "$response" \
46
+ | grep -Eo '"tag_name"[[:space:]]*:[[:space:]]*"[^"]+"' \
47
+ | head -n 1 \
48
+ | cut -d '"' -f 4 \
49
+ || true
50
+ )
51
+ asset_url=$(
52
+ printf '%s\n' "$response" \
53
+ | grep -Eo '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]*"' \
54
+ | cut -d '"' -f 4 \
55
+ | grep -E '/[^/]*linux[-_]amd64(\.tar\.gz)?$' \
56
+ | head -n 1 \
57
+ || true
58
+ )
59
+
60
+ if [ -z "$tag_name" ] || [ -z "$asset_url" ]; then
61
+ return 1
62
+ fi
63
+
64
+ printf '%s|%s\n' "$tag_name" "$asset_url"
65
+ }
66
+
67
+ load_latest_release() {
68
+ release_info=$(fetch_latest_release_info) || return 1
69
+ LATEST_TAG=${release_info%%|*}
70
+ LATEST_ASSET_URL=${release_info#*|}
71
+ }
72
+
73
+ find_release_binary() {
74
+ release_dir=$1
75
+
76
+ for name in $APP_BINARY_NAMES; do
77
+ if [ -f "$release_dir/$name" ]; then
78
+ printf '%s\n' "$release_dir/$name"
79
+ return 0
80
+ fi
81
+ done
82
+
83
+ find "$release_dir" -maxdepth 3 -type f \( -name 'cli-proxy-api' -o -name 'CLIProxyAPI' \) | head -n 1
84
+ }
85
+
86
+ activate_release() {
87
+ tag_name=$1
88
+ release_dir=$2
89
+
90
+ rm -f "$CURRENT_LINK"
91
+ ln -s "$release_dir" "$CURRENT_LINK"
92
+ printf '%s\n' "$tag_name" > "$CURRENT_TAG_FILE"
93
+ }
94
+
95
+ extract_release_binary() {
96
+ source_dir=$1
97
+ target_path=$2
98
+ binary_path=$(find_release_binary "$source_dir" || true)
99
+
100
+ if [ -z "$binary_path" ]; then
101
+ return 1
102
+ fi
103
+
104
+ if [ "$binary_path" != "$target_path" ]; then
105
+ cp "$binary_path" "$target_path"
106
+ fi
107
+ chmod +x "$target_path"
108
+ }
109
+
110
+ cleanup_workspace() {
111
+ workspace=$1
112
+ if [ -n "$workspace" ] && [ -d "$workspace" ]; then
113
+ rm -rf "$workspace"
114
+ fi
115
+ }
116
+
117
+ install_release() {
118
+ tag_name=$1
119
+ asset_url=$2
120
+
121
+ ensure_runtime_dirs
122
+ release_dir=$(release_dir_for_tag "$tag_name")
123
+ release_binary="$release_dir/$CURRENT_BINARY_NAME"
124
+
125
+ if [ -x "$release_binary" ]; then
126
+ activate_release "$tag_name" "$release_dir"
127
+ return 0
128
+ fi
129
+
130
+ workspace=$(mktemp -d "$RUNTIME_DIR/install.XXXXXX") || return 1
131
+ download_name=$(basename "$asset_url")
132
+ if [ -z "$download_name" ] || [ "$download_name" = "/" ] || [ "$download_name" = "." ]; then
133
+ download_name="release.asset"
134
+ fi
135
+ download_path="$DOWNLOADS_DIR/$download_name"
136
+ stage_dir="$workspace/stage"
137
+
138
+ rm -f "$download_path" || {
139
+ cleanup_workspace "$workspace"
140
+ return 1
141
+ }
142
+ mkdir -p "$stage_dir" || {
143
+ cleanup_workspace "$workspace"
144
+ return 1
145
+ }
146
+ curl -fsSL "$asset_url" -o "$download_path" || {
147
+ cleanup_workspace "$workspace"
148
+ return 1
149
+ }
150
+
151
+ case "$download_path" in
152
+ *.tar.gz)
153
+ tar -xzf "$download_path" -C "$stage_dir" || {
154
+ cleanup_workspace "$workspace"
155
+ return 1
156
+ }
157
+ extract_release_binary "$stage_dir" "$stage_dir/$CURRENT_BINARY_NAME" || {
158
+ cleanup_workspace "$workspace"
159
+ return 1
160
+ }
161
+ ;;
162
+ *)
163
+ cp "$download_path" "$stage_dir/$CURRENT_BINARY_NAME" || {
164
+ cleanup_workspace "$workspace"
165
+ return 1
166
+ }
167
+ chmod +x "$stage_dir/$CURRENT_BINARY_NAME" || {
168
+ cleanup_workspace "$workspace"
169
+ return 1
170
+ }
171
+ ;;
172
+ esac
173
+
174
+ rm -rf "$release_dir" || {
175
+ cleanup_workspace "$workspace"
176
+ return 1
177
+ }
178
+ mv "$stage_dir" "$release_dir" || {
179
+ cleanup_workspace "$workspace"
180
+ return 1
181
+ }
182
+ cleanup_workspace "$workspace"
183
+
184
+ activate_release "$tag_name" "$release_dir"
185
+ }
186
+
187
+ ensure_initial_release() {
188
+ if load_latest_release; then
189
+ if install_release "$LATEST_TAG" "$LATEST_ASSET_URL"; then
190
+ return 0
191
+ fi
192
+ log "警告: 安装最新版本失败,尝试使用已有版本继续启动"
193
+ fi
194
+
195
+ [ -x "$(current_binary_path)" ]
196
+ }
197
+
198
+ restart_managed_service() {
199
+ supervisorctl -c "$SUPERVISOR_CONF" restart "$SUPERVISOR_PROGRAM_NAME"
200
+ }
201
+
202
+ update_if_needed() {
203
+ load_latest_release || {
204
+ log "检查最新版本失败"
205
+ return 1
206
+ }
207
+
208
+ installed_tag=$(current_tag)
209
+ if [ "$LATEST_TAG" = "$installed_tag" ]; then
210
+ log "当前已是最新版本: $LATEST_TAG"
211
+ return 0
212
+ fi
213
+
214
+ log "发现新版本: ${installed_tag:-<none>} -> $LATEST_TAG"
215
+ install_release "$LATEST_TAG" "$LATEST_ASSET_URL" || {
216
+ log "安装新版本失败: $LATEST_TAG"
217
+ return 1
218
+ }
219
+
220
+ if [ -n "$installed_tag" ]; then
221
+ restart_managed_service
222
+ fi
223
+ }
scripts/update-loop.sh ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ : "${UPDATE_INTERVAL_SECONDS:=14400}"
5
+ : "${RELEASE_COMMON_SH:=/usr/local/bin/release-common.sh}"
6
+
7
+ . "$RELEASE_COMMON_SH"
8
+
9
+ while true; do
10
+ sleep "$UPDATE_INTERVAL_SECONDS"
11
+ log "开始定时版本检查"
12
+ if ! update_if_needed; then
13
+ log "警告: 自动更新检查失败,继续运行当前版本"
14
+ fi
15
+ done
supervisord.conf ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [unix_http_server]
2
+ file=%(ENV_RUNTIME_DIR)s/supervisor.sock
3
+ chmod=0700
4
+
5
+ [supervisord]
6
+ nodaemon=true
7
+ pidfile=%(ENV_RUNTIME_DIR)s/supervisord.pid
8
+ logfile=%(ENV_RUNTIME_DIR)s/supervisord.log
9
+ logfile_maxbytes=0
10
+ minfds=65535
11
+
12
+ [rpcinterface:supervisor]
13
+ supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
14
+
15
+ [supervisorctl]
16
+ serverurl=unix://%(ENV_RUNTIME_DIR)s/supervisor.sock
17
+
18
+ [program:cliproxyapi]
19
+ command=/bin/sh %(ENV_RUNTIME_DIR)s/run-app.sh
20
+ autostart=true
21
+ autorestart=true
22
+ startsecs=0
23
+ stopasgroup=true
24
+ killasgroup=true
25
+ stopwaitsecs=%(ENV_STOP_WAIT_SECS)s
26
+ stdout_logfile=/dev/fd/1
27
+ stdout_logfile_maxbytes=0
28
+ stderr_logfile=/dev/fd/2
29
+ stderr_logfile_maxbytes=0
30
+
31
+ [program:cliproxyapi-updater]
32
+ command=/usr/local/bin/update-loop.sh
33
+ autostart=true
34
+ autorestart=true
35
+ startsecs=0
36
+ stopasgroup=true
37
+ killasgroup=true
38
+ stdout_logfile=/dev/fd/1
39
+ stdout_logfile_maxbytes=0
40
+ stderr_logfile=/dev/fd/2
41
+ stderr_logfile_maxbytes=0