app-cli

运维脚本仓库。不放业务代码,只放「怎么跑起来、怎么检查、怎么上线」的操作入口。

三个业务仓各自独立,本仓库通过路径引用它们:

<project>/
├─ app-cli/        ← 本仓库:脚本与部署编排
├─ backend/        ← Go 后端(8090 公开 / 8091 SSG / 8092 后台)
├─ test/test/      ← Astro 前端
└─ fashion-siglip/ ← CLIP 向量服务(可选,仅后台「疑似同款」用)

为什么单独一个仓库

理由 具体好处
脚本不跟业务版本绑在一起 改部署流程不用动业务仓,回滚业务代码不会把脚本一起回滚掉
一处放全部「怎么运行」的知识 换机器只 clone 这个仓库 + 配一份 config/local.env
服务器只需拉这一个仓库 蓝绿部署时槽位切换、备份、健康检查都在这里

代价是目录必须同级(脚本要能按 ../backend 找到业务仓)。路径不一致时在 config/local.env 里显式写死。


目录结构(当前进度)

app-cli/
├─ dev.cmd                     # 双击启动(转发给 dev/dev.ps1)
├─ config/
│  ├─ local.env.example        # 路径/端口覆盖模板(复制成 local.env)
│  └─ local.env                # 本机实际值,不入库
├─ lib/
│  └─ common.ps1               # 公共函数:路径探测/端口/进程/HTTP(已在用)
├─ dev/                        # ★ 本地环境(第一版已完成)
│  ├─ dev.ps1                  # 一键启动:后端 + 前端(可选 CLIP)
│  ├─ stop.ps1                 # 按 PID 登记停止,支持 -Force 清残留
│  ├─ status.ps1               # 端口 / PID / 健康检查一览
│  └─ doctor.ps1               # 体检:版本/路径/依赖/数据库/端口/CORS
└─ vision/
   └─ vision.ps1               # CLIP 服务 start/stop/restart/status/logs

# 下面是规划中的目录,本轮还没建:
# ├─ check/                    # 提交前检查:go build+vet+test、astro check
# ├─ deploy/                   # 生产部署:docker-compose、nginx、deploy.sh、init-db.sh
# └─ docs/                     # 排障手册

脚本分四类

类别 目录 运行在哪 现在
本地环境 dev/ 开发机 Windows ✅ 已完成
视觉服务 vision/ 开发机 / 服务器 ✅ 已完成
提交前检查 check/ 开发机 待建
生产部署 deploy/ Linux 服务器 待迁入(现在散在前端仓)

分界的意义:dev/ 里的东西永远不在生产跑,deploy/ 里的东西不在开发机跑。混在一起就会出现「为了本地方便给生产脚本加了个开关」这类事故。


本地开发怎么用

首次:

cd <project>/app-cli
copy config\local.env.example config\local.env    # 可选,不填也能跑(自动探测同级目录)
.\dev\doctor.ps1                                  # 先体检

日常:

.\dev\dev.ps1                  # 后端 + 前端
.\dev\dev.ps1 -Vision -Open    # 连 CLIP 一起起,并打开浏览器
.\dev\dev.ps1 frontend         # 只起前端(后端已在跑)
.\dev\dev.ps1 -Force           # 端口被占时先杀掉占用者
.\dev\status.ps1               # 看状态
.\dev\stop.ps1                 # 停掉

也可以双击 dev.cmd(自动带 -ExecutionPolicy Bypass,绕开脚本执行策略限制)。

端口约定

端口 服务 谁能访问
8090 后端公开 API 前端浏览器直连(dev 模式下 baseApi 写死这个地址)
8091 后端 SSG 内部接口 仅构建期取数用
8092 管理后台 /admin 本机
4321 Astro dev server 浏览器
8900 CLIP 向量服务 仅 127.0.0.1

4321 不是随便选的:后端 cors.allow_origins 里放行的就是 http://localhost:4321。 而前端 astro.config.mjs 的 server.port 是 3000(那是给容器内 node 常驻用的), 所以直接 npm run dev 会起在 3000 —— 浏览器请求会被 CORS 拦掉,页面表现为「没数据」。 dev.ps1 用 --port 4321 显式覆盖,并在启动后自检 CORS 回显,不一致直接告警。

为什么后端是「先编译再运行」而不是 go run

go run 会派生一个 main.exe 子进程,PID 杀掉 go run 父进程后子进程可能还在,端口继续被占——正是「明明关了服务 8090 还能通」的成因。 dev.ps1 用 go build -o .bin/fashionapi-dev.exe 再直接运行,进程树干净,stop.ps1 能准确回收。

日志与状态

.logs/backend.log   .logs/backend.err.log
.logs/frontend.log  .logs/frontend.err.log
.logs/vision.log    .logs/vision.err.log
.run/backend.pid    .run/frontend.pid    .run/vision.pid

stop.ps1 优先按 PID 停;端口上还有本脚本管不到的进程(比如手动 go run 留下的)时只报告不硬杀,加 -Force 才清。


设计取舍

1. 不用 pm2 / 不用 supervisor(本地) 进程管理交给脚本 + PID 登记。引入 pm2 只是多一层要维护的状态,而失败场景(谁占着端口、为什么没起来)反而变难查。

2. 只做 PowerShell,不做 .sh 双份 开发机是 Windows。生产是 Linux,那边用 deploy/ 的 bash 脚本,本来就该分开写——同一套逻辑写两遍,最后一定是两份都只测过一份。

3. 路径自动探测 + 显式覆盖 默认按同级目录找,用标记文件(cmd\server\main.go / astro.config.mjs / app.py)校验。写错路径会在启动前报错,不会静默启动到空目录。

4. 体检和启动分离 doctor.ps1 只读不写,可以随时跑;dev.ps1 只管启动。合并成一个会出现「想查问题时它顺手改了环境」。


下一步

  1. check/check.ps1:go build + go vet + go test ./internal/... + astro check 一条命令
  2. deploy/:把现在散落在前端仓的 docker-compose.yml、nginx/、deploy.sh、init-db.sh 迁进来,改成 build: context: ../backend / ../test/test
  3. docs/:把「上线后 5 处点检」和常见故障对照表写成文档
Description
No description provided
Readme 56 KiB
Languages
PowerShell 98.1%
Batchfile 1.9%