wwforonce commited on
Commit
029ea4c
·
1 Parent(s): 4560dd6

add local api server

Browse files
Files changed (4) hide show
  1. Caddyfile +19 -0
  2. Dockerfile +17 -2
  3. add_bash_util.sh +109 -0
  4. start_with_sync.sh +164 -1
Caddyfile ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :7860 {
2
+ handle_path /8085/* {
3
+ reverse_proxy localhost:8085
4
+ }
5
+ # https://github.com/justlovemaki/AIClient-2-API
6
+ handle_path /apiv1/* {
7
+ reverse_proxy localhost:3000
8
+ }
9
+ # https://github.com/waxz/gemini-cli-openai
10
+ handle_path /apiv2/* {
11
+ reverse_proxy localhost:8787
12
+ }
13
+ handle_path /apiv3/* {
14
+ reverse_proxy localhost:8000
15
+ }
16
+ # openweb-ui
17
+ reverse_proxy localhost:8080
18
+
19
+ }
Dockerfile CHANGED
@@ -2,13 +2,22 @@ FROM ghcr.io/open-webui/open-webui:main
2
 
3
  # Install dependencies
4
  RUN apt update && apt install -y \
 
5
  gcc \
6
  curl \
7
  sudo \
8
  git-lfs \
9
  openssl \
 
 
 
 
10
  && rm -rf /var/lib/apt/lists/*
11
 
 
 
 
 
12
  # Install Python packages
13
  RUN pip install --no-cache-dir \
14
  huggingface_hub \
@@ -34,8 +43,14 @@ RUN chmod +x /app/sync_storage.py /start.sh
34
  # Set working directory
35
  WORKDIR /app
36
 
37
- # Expose port
38
- EXPOSE 8080
 
 
 
 
 
 
39
 
40
  # Start with sync
41
  ENTRYPOINT ["/start.sh"]
 
2
 
3
  # Install dependencies
4
  RUN apt update && apt install -y \
5
+ software-properties-common \
6
  gcc \
7
  curl \
8
  sudo \
9
  git-lfs \
10
  openssl \
11
+ wget \
12
+ jq \
13
+ python3 \
14
+ npm \
15
  && rm -rf /var/lib/apt/lists/*
16
 
17
+ RUN npm install npm@latest -g && \
18
+ npm install n -g && \
19
+ n latest
20
+
21
  # Install Python packages
22
  RUN pip install --no-cache-dir \
23
  huggingface_hub \
 
43
  # Set working directory
44
  WORKDIR /app
45
 
46
+ COPY ./add_bash_util.sh /add_bash_util.sh
47
+ COPY ./Caddyfile /Caddyfile
48
+ # Expose ports
49
+
50
+ EXPOSE 7860
51
+
52
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s \
53
+ CMD curl -f http://localhost:7860/ || exit 1
54
 
55
  # Start with sync
56
  ENTRYPOINT ["/start.sh"]
add_bash_util.sh ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # gh_install vi/websocat websocat.x86_64-unknown-linux-musl
3
+ gh_install() {
4
+ echo "Number of arguments: $#"
5
+ echo "All arguments as separate words: $@"
6
+ echo "All arguments as a single string: $*"
7
+
8
+ if [[ $# -ne 3 ]]; then
9
+ echo "Please set repo, arch, and filename"
10
+ return 1
11
+ fi
12
+
13
+ local repo="$1"
14
+ local arch="$2"
15
+ local filename="$3"
16
+
17
+ echo "Set repo: $repo, arch: $arch, filename: $filename"
18
+
19
+ local url
20
+ local count=0
21
+
22
+ while [[ -z "$url" && $count -lt 5 ]]; do
23
+ content=$(curl -s -L -H "Accept: application/vnd.github+json" "https://api.github.com/repos/$repo/releases")
24
+ url=$(echo "$content" | jq -r --arg arch "$arch" '.[0] | .assets[] | .browser_download_url | select(endswith($arch))')
25
+ count=$((count + 1))
26
+ done
27
+
28
+ if [[ -z "$url" ]]; then
29
+ echo "Failed to find a valid download URL after $count attempts."
30
+ return 1
31
+ fi
32
+
33
+ echo "Download URL: $url"
34
+ wget -q "$url" -O "$filename" && echo "Downloaded $filename successfully." || echo "Failed to download $filename."
35
+ }
36
+
37
+ check_installed() {
38
+ if [ "$#" -ne 1 ]; then
39
+ echo "Usage: check_installed <program_name>"
40
+ return 1
41
+ fi
42
+ if which "$1" &>/dev/null; then
43
+ >&2 echo "$1 is installed"
44
+ >&1 echo 0
45
+ else
46
+ >&2 echo "$1 is not installed"
47
+ >&1 echo 1
48
+ fi
49
+ }
50
+ # check_installed docker 1>/dev/null
51
+ # check_installed docker 2>/dev/null
52
+ # check_installed docker &>/dev/null
53
+
54
+
55
+ # Utility functions for managing processes
56
+ ps_kill() {
57
+ echo "Number of arguments: $#"
58
+ echo "All arguments as separate words: $@"
59
+ echo "All arguments as a single string: $*"
60
+
61
+ if [[ $# -ne 1 ]]; then
62
+ echo "Please set program"
63
+ return 1
64
+ fi
65
+ program="$1"
66
+
67
+ ps -A -o tid,cmd | grep -v grep | grep "$program" | awk '{print $1}' | xargs -I {} /bin/bash -c 'sudo kill -9 {} '
68
+ }
69
+
70
+ install_docker() {
71
+ if ! which docker &>/dev/null; then
72
+ echo "Docker is not installed. Installing..."
73
+ curl -fsSL https://get.docker.com | sh
74
+ sudo systemctl --now enable docker
75
+ echo "Docker installed successfully."
76
+ else
77
+ echo "Docker is already installed."
78
+ fi
79
+ }
80
+
81
+ create_user() {
82
+ if [ "$#" -ne 1 ]; then
83
+ echo "Usage: create_user <username>"
84
+ return 1
85
+ fi
86
+ export USERNAME="$1"
87
+ export MUID=$(id -u)
88
+ export MGID=$(id -g)
89
+
90
+ # add user without password
91
+
92
+ sudo groupadd $USERNAME
93
+ # same uid with host user
94
+ # sudo useradd -u $MUID -g $MGID -m -s /bin/bash $USERNAME
95
+ sudo useradd -g $MGID -m -s /bin/bash $USERNAME
96
+ sudo passwd -d $USERNAME
97
+ sudo usermod -a -G sudo $USERNAME
98
+ sudo usermod -a -G $USERNAME $USERNAME
99
+
100
+ install_docker
101
+ sudo usermod -a -G docker $USERNAME
102
+
103
+
104
+ echo "User $USERNAME created and added to sudo and docker groups."
105
+ }
106
+
107
+ # reset cursor
108
+ # https://unix.stackexchange.com/questions/6890/what-is-making-my-cursor-randomly-disappear-when-using-gnome-teminal
109
+ tput cnorm
start_with_sync.sh CHANGED
@@ -101,4 +101,167 @@ export WEBUI_SECRET_KEY="${WEBUI_SECRET_KEY:-$(openssl rand -hex 32)}"
101
  WEBUI_PID=$!
102
 
103
  # Wait for Open WebUI process
104
- wait $WEBUI_PID
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  WEBUI_PID=$!
102
 
103
  # Wait for Open WebUI process
104
+ # wait $WEBUI_PID
105
+
106
+ source /add_bash_util.sh
107
+
108
+ gh_install caddyserver/caddy linux_amd64.tar.gz /tmp/caddy.tar.gz
109
+ mkdir -p /tmp/caddy
110
+ tar -xzf /tmp/caddy.tar.gz -C /tmp/caddy
111
+
112
+
113
+ # Start the Node.js application
114
+ git clone https://github.com/waxz/Gemini-CLI-2-API.git /tmp/Gemini-CLI-2-API
115
+ git clone https://github.com/waxz/gemini-cli-openai /tmp/gemini-cli-openai
116
+
117
+ git clone https://github.com/snailyp/gemini-balance.git /tmp/gemini-balance
118
+
119
+ curl -LsSf https://astral.sh/uv/install.sh | sh
120
+ source $HOME/.local/bin/env
121
+
122
+ uv venv /tmp/.venv
123
+ source /tmp/.venv/bin/activate
124
+ uv pip install -r /tmp/gemini-balance/requirements.txt
125
+
126
+
127
+ cat << EOF | tee /tmp/Gemini-CLI-2-API/config.json
128
+ {
129
+ "REQUIRED_API_KEY": "${REQUIRED_API_KEY:-}",
130
+ "SERVER_PORT": 3000,
131
+ "HOST": "localhost",
132
+ "MODEL_PROVIDER": "gemini-cli-oauth",
133
+ "OPENAI_API_KEY": "${OPENAI_API_KEY:-}",
134
+ "OPENAI_BASE_URL": "https://api.openai.com/v1",
135
+ "CLAUDE_API_KEY": "${CLAUDE_API_KEY:-}",
136
+ "CLAUDE_BASE_URL": "https://api.anthropic.com/v1",
137
+ "PROJECT_ID": "${PROJECT_ID:-}",
138
+ "PROMPT_LOG_MODE": "console",
139
+ "GEMINI_OAUTH_CREDS_FILE_PATH":"/tmp/gemini_oauth_creds.json"
140
+ }
141
+ EOF
142
+ cat << EOF | tee /tmp/gemini_oauth_creds.json
143
+ {
144
+ "access_token": "${GEMINI_OAUTH_ACCESS_TOKEN:-}",
145
+ "refresh_token": "${GEMINI_OAUTH_REFRESH_TOKEN:-}",
146
+ "scope": "https://www.googleapis.com/auth/cloud-platform",
147
+ "token_type": "Bearer",
148
+ "expiry_date": 1753880406425
149
+ }
150
+ EOF
151
+ cat << EOF | tee /tmp/gemini-balance/.env
152
+ # 数据库配置
153
+ DATABASE_TYPE=mysql
154
+ #SQLITE_DATABASE=default_db
155
+ MYSQL_HOST=${MYSQL_HOST}
156
+ #MYSQL_SOCKET=/run/mysqld/mysqld.sock
157
+ MYSQL_PORT=${MYSQL_PORT}
158
+ MYSQL_USER=${MYSQL_USER}
159
+ MYSQL_PASSWORD=${MYSQL_PASSWORD}
160
+ MYSQL_DATABASE=${MYSQL_DATABASE}
161
+ API_KEYS=["${GEMINI_API_KEYS}"]
162
+ ALLOWED_TOKENS=["${REQUIRED_API_KEY}"]
163
+ AUTH_TOKEN=${REQUIRED_API_KEY}
164
+ # For Vertex AI Platform API Keys
165
+ VERTEX_API_KEYS=["AQ.Abxxxxxxxxxxxxxxxxxxx"]
166
+ # For Vertex AI Platform Express API Base URL
167
+ VERTEX_EXPRESS_BASE_URL=https://aiplatform.googleapis.com/v1beta1/publishers/google
168
+ TEST_MODEL=gemini-1.5-flash
169
+ THINKING_MODELS=["gemini-2.5-flash-preview-04-17"]
170
+ THINKING_BUDGET_MAP={"gemini-2.5-flash-preview-04-17": 4000}
171
+ IMAGE_MODELS=["gemini-2.0-flash-exp"]
172
+ SEARCH_MODELS=["gemini-2.0-flash-exp","gemini-2.0-pro-exp"]
173
+ FILTERED_MODELS=["gemini-1.0-pro-vision-latest", "gemini-pro-vision", "chat-bison-001", "text-bison-001", "embedding-gecko-001"]
174
+ # 是否启用网址上下文,默认启用
175
+ URL_CONTEXT_ENABLED=false
176
+ 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"]
177
+ TOOLS_CODE_EXECUTION_ENABLED=false
178
+ SHOW_SEARCH_LINK=true
179
+ SHOW_THINKING_PROCESS=true
180
+ BASE_URL=https://generativelanguage.googleapis.com/v1beta
181
+ MAX_FAILURES=10
182
+ MAX_RETRIES=3
183
+ CHECK_INTERVAL_HOURS=1
184
+ TIMEZONE=Asia/Shanghai
185
+ # 请求超时时间(秒)
186
+ TIME_OUT=300
187
+ # 代理服务器配置 (支持 http 和 socks5)
188
+ # 示例: PROXIES=["http://user:pass@host:port", "socks5://host:port"]
189
+ PROXIES=[]
190
+ # 对同一个API_KEY使用代理列表中固定的IP策略
191
+ PROXIES_USE_CONSISTENCY_HASH_BY_API_KEY=true
192
+ #########################image_generate 相关配置###########################
193
+ PAID_KEY=AIzaSyxxxxxxxxxxxxxxxxxxx
194
+ CREATE_IMAGE_MODEL=imagen-3.0-generate-002
195
+ UPLOAD_PROVIDER=smms
196
+ SMMS_SECRET_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
197
+ PICGO_API_KEY=xxxx
198
+ CLOUDFLARE_IMGBED_URL=https://xxxxxxx.pages.dev/upload
199
+ CLOUDFLARE_IMGBED_AUTH_CODE=xxxxxxxxx
200
+ CLOUDFLARE_IMGBED_UPLOAD_FOLDER=
201
+ ##########################################################################
202
+ #########################stream_optimizer 相关配置########################
203
+ STREAM_OPTIMIZER_ENABLED=false
204
+ STREAM_MIN_DELAY=0.016
205
+ STREAM_MAX_DELAY=0.024
206
+ STREAM_SHORT_TEXT_THRESHOLD=10
207
+ STREAM_LONG_TEXT_THRESHOLD=50
208
+ STREAM_CHUNK_SIZE=5
209
+ ##########################################################################
210
+ ######################### 日志配置 #######################################
211
+ # 日志级别 (debug, info, warning, error, critical),默认为 info
212
+ LOG_LEVEL=info
213
+ # 是否开启自动删除错误日志
214
+ AUTO_DELETE_ERROR_LOGS_ENABLED=true
215
+ # 自动删除多少天前的错误日志 (1, 7, 30)
216
+ AUTO_DELETE_ERROR_LOGS_DAYS=7
217
+ # 是否开启自动删除请求日志
218
+ AUTO_DELETE_REQUEST_LOGS_ENABLED=false
219
+ # 自动删除多少天前的请求日志 (1, 7, 30)
220
+ AUTO_DELETE_REQUEST_LOGS_DAYS=30
221
+ ##########################################################################
222
+
223
+ # 假流式配置 (Fake Streaming Configuration)
224
+ # 是否启用假流式输出
225
+ FAKE_STREAM_ENABLED=True
226
+ # 假流式发送空数据的间隔时间(秒)
227
+ FAKE_STREAM_EMPTY_DATA_INTERVAL_SECONDS=5
228
+
229
+ # 安全设置 (JSON 字符串格式)
230
+ # 注意:这里的示例值可能需要根据实际模型支持情况调整
231
+ 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"}]
232
+ URL_NORMALIZATION_ENABLED=false
233
+ # tts配置
234
+ TTS_MODEL=gemini-2.5-flash-preview-tts
235
+ TTS_VOICE_NAME=Zephyr
236
+ TTS_SPEED=normal
237
+ #########################Files API 相关配置########################
238
+ # 是否启用文件过期自动清理
239
+ FILES_CLEANUP_ENABLED=true
240
+ # 文件过期清理间隔(小时)
241
+ FILES_CLEANUP_INTERVAL_HOURS=1
242
+ # 是否启用用户文件隔离(每个用户只能看到自己上传的文件)
243
+ FILES_USER_ISOLATION_ENABLED=true
244
+ ##########################################################################
245
+ EOF
246
+
247
+ cat << EOF | tee /tmp/gemini-cli-openai/.dev.vars
248
+ # Required: OAuth2 credentials JSON from Gemini CLI authentication
249
+ GCP_SERVICE_ACCOUNT=${GCP_SERVICE_ACCOUNT}
250
+ # Optional: Google Cloud Project ID (auto-discovered if not set)
251
+ GEMINI_PROJECT_ID=${GEMINI_PROJECT_ID}
252
+
253
+
254
+ # Optional: API key for authentication (if not set, API is public)
255
+ # When set, clients must include "Authorization: Bearer <your-api-key>" header
256
+ # Example: sk-1234567890abcdef1234567890abcdef
257
+ OPENAI_API_KEY=${REQUIRED_API_KEY}
258
+ EOF
259
+
260
+ cd /tmp/Gemini-CLI-2-API && npm install && node src/api-server.js &
261
+ cd /tmp/gemini-balance && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload &
262
+ cd /tmp/gemini-cli-openai && npm i && npm run dev &
263
+ /tmp/caddy/caddy run --config /Caddyfile &
264
+ MAIN_PID=$!
265
+
266
+ # Wait for caddy process
267
+ wait $MAIN_PID