From 19b69e2d5a3f667f0b97ca869a65c5faf0ea0e4f Mon Sep 17 00:00:00 2001 From: skycurtain Date: Tue, 8 Sep 2026 20:05:49 +0800 Subject: [PATCH] =?UTF-8?q?docs(deploy):=20=E9=83=A8=E7=BD=B2=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E2=80=94=E2=80=94=E5=BC=80=E5=8F=91=E6=9C=BA=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=20+=20=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=BD=BB=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=EF=BC=88Caddy=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按熟悉的工作流调整:构建在开发机完成(四绿验证后的 dist 才是部署物),SFTP 上传 dist/Caddyfile/compose.yaml/Dockerfile 四件到服务器,服务器上 docker build 仅做 COPY(无构建工具链需求,秒级)。单阶段 Dockerfile;.dockerignore 不再排除 dist(部署必需品)且继续排除 .env*;README 部署章节重写为三步流程(本机构建/SFTP/服务器 compose)。compose 文件采用 Compose 规范标准名 compose.yaml(docker-compose.yml 仅为向后兼容保留)。 --- .dockerignore | 11 +++++++++++ Caddyfile | 24 ++++++++++++++++++++++++ Dockerfile | 6 ++++++ README.md | 28 +++++++++++++++++++++++++++- compose.yaml | 21 +++++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Caddyfile create mode 100644 Dockerfile create mode 100644 compose.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2b6c8ef --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +# 服务器轻构建的上下文:只需 dist + Caddyfile(新部署模式,产物在开发机构建) +# 注意:dist 是部署必需品,不再排除 +node_modules +.git +.eslintcache +*.tsbuildinfo + +# 环境变量文件绝不能进镜像层(真实网关地址在 .env.local 里) +.env +.env.local +.env.*.local diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..f3fe538 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,24 @@ +# bench 的 Caddy 配置:静态托管 + 网关反向代理 +# +# :80 表示监听 80 端口、禁用自动 HTTPS(容器场景由外层决定 TLS; +# 若将来直接暴露公网域名,把 :80 换成域名,Caddy 会自动签发证书) +# +# GATEWAY 由 docker run -e / compose environment 注入(Caddyfile 支持 {$GATEWAY} 环境变量占位) +# 未注入时 Caddy 启动会因空地址报错——与 vite dev 行为一致:不写死默认值 + +:80 { + # 静态站点:根目录 + SPA fallback(不存在的路径回退 index.html) + root * /usr/share/caddy + encode gzip + + # 接口代理:与 vite.config.ts 的 dev 代理语义一致,转发到网关 + @api path /api/* /v1/* + handle @api { + reverse_proxy {$GATEWAY} + } + + handle { + try_files {path} /index.html + file_server + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..002cc2d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +# bench 运行镜像:仅把本机构建好的 dist 打进 Caddy(构建在开发机完成,见 README 部署章节) +# 服务器上 docker build 只做 COPY,秒级完成,不需要任何构建工具链 +FROM caddy:2-alpine + +COPY Caddyfile /etc/caddy/Caddyfile +COPY dist /usr/share/caddy diff --git a/README.md b/README.md index 4c3ef76..56080f1 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,36 @@ bun run build # type-check + vite build(dist/) ## 已知边界 -- 生产部署(`bun run build`)无 Vite 代理,需为网关路径配置反向代理 - `useClipboard` 在非 https 环境(如 http://localhost)自动降级 `execCommand` - `/v1/models/:model` 单模型详情接口未纳入(数据源是硬编码静态表,与 `/v1/models` 不一致,无调试价值) +## 部署(开发机构建 + 服务器轻构建运行) + +构建在开发机完成(四绿验证后的 dist 才是部署物),服务器只做镜像 COPY + 起容器, +不需要任何构建工具链。 + +```bash +# —— 开发机 —— +bun run build # 得到 dist/(此时已过 test/type-check/lint) +# SFTP 上传四个部署物到服务器同一目录: +# dist/ Caddyfile compose.yaml Dockerfile +# (.env 不上传,GATEWAY 在服务器上以 .env 或环境变量提供) + +# —— 服务器(目录内需有 .env,内容为 GATEWAY=https://…)—— +docker compose up -d --build # 首次:拉 caddy 镜像 + COPY 产物起容器,秒级 +# 浏览器打开 http://<服务器IP>:8080 + +# —— 常规更新(开发机)—— +bun run build # 重新构建 +# SFTP 覆盖 dist/ +docker compose up -d --build # 服务器上重新 COPY + 替换容器 +``` + +- Caddy 承担与 dev 代理相同的职责:静态文件 + `/api`、`/v1` 转发到 `$GATEWAY` + SPA fallback +- 换网关:改服务器上的 `.env` 后 `docker compose up -d --force-recreate`(无需重新 build) +- 暴露公网时把 `Caddyfile` 的 `:80` 改为域名,Caddy 自动签发 HTTPS 证书 +- `compose.yaml`(Compose 规范标准文件名)里 `GATEWAY` 为必填(未设置时启动即报错,不会带错误配置运行) + ## 文档 - 交互与技术决策:`docs/bench交互设计文档.md` diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..60bac82 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,21 @@ +# bench 部署编排:服务器上 docker compose up -d 即起 +# 前置:开发机已 bun run build 得到 dist/,并把 dist/ Caddyfile/ compose.yaml/ Dockerfile/ +# 四项经 SFTP 上传到服务器同一目录(见 README 部署章节) +# +# 常规更新流程(开发机): +# 1. bun run build +# 2. SFTP 覆盖上传 dist/ 目录 +# 3. 服务器上 docker compose up -d --build # 重新 COPY 产物进镜像并滚动替换容器 + +services: + bench: + build: + context: . + image: new-api-key-bench + container_name: bench + ports: + - "8080:80" + environment: + # 必填:NewAPI 网关地址(Caddyfile 的 {$GATEWAY} 占位由此注入) + GATEWAY: ${GATEWAY:?请在 .env 或环境中设置 GATEWAY,例如 GATEWAY=https://your-gateway.example.com} + restart: unless-stopped