You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.5 KiB
7.5 KiB
| name | description | disable-model-invocation |
|---|---|---|
| tool-website-stack | 指定该技能时加载。 | true |
工具网站开发技术栈
评审与前提论证(必须先做)
在给出架构结论、改栈或写 .drone.yml/Caddy 配置前,必须完成一轮前提显式化 + 自我反驳,再进入实现;不得默认「显然成立」的隐含假设。
- 列出前提:把当前方案依赖的假设写成可检验的条目(流量与并发写、是否多机、runner 上是否已有 Go/Node、是否需要持久会话、是否必须容器隔离、合规/密钥归属等)。
- 反驳与边界:对每条前提追问「若假则怎样」——例如 SQLite 单写瓶颈、exec runner 与宿主机污染、纯静态托管 vs 需要 BFF、Caddy 与 SPA 路由冲突;至少给出一条会推翻当前选型的反例场景。
- 结论带条件:最终推荐写成「在 A、B、C 成立时采用 X;若 D 则改为 Y」,避免无条件绝对表述。
- 变更评审:涉及技术栈、部署路径或 CI 形态的改动,用简短对照表说明「改前假设 / 改后假设 / 风险 / 回滚」后再落代码或配置。
技术栈
- 后端:golang, sqlite
- 前端:vite + react
- 部署:drone-ci(type: exec,执行器在服务器环境),caddy;应用进程用
nohup后台启动,禁止使用systemctl/ systemd 单元管理本服务
后端(Go + SQLite)
- 优先保持单二进制、少依赖:SQLite 适合单机工具站与中小流量;迁移用
embed或显式 SQL 文件,避免隐式魔法。 - API 与静态资源分工清晰:由 Go 提供 API/SSR(若需要)或由 Go 仅作 BFF,前端静态由 Caddy 或 Go
embed二选一,勿混用两套来源导致缓存与路由冲突。 - 连接 SQLite 时设置合理
busy_timeout、单写者多读者模型;并发写多时再讨论迁移,默认不引入额外数据库。
前端(Vite + React)
- 使用 Vite 约定:
npm run build产出dist,环境变量以VITE_前缀暴露给客户端;敏感配置不放前端。 - 与 Go 联调:开发期用 Vite dev server 代理 API 到本地 Go 端口;生产构建产物路径与 Caddy/Go 静态路由一致。
CI(Drone,type: exec)
- exec 执行器在服务器本机运行:流水线步骤直接在该机 shell 环境执行,不是 Kubernetes/docker pipeline 的隔离容器。
.drone.yml中需type: exec;脚本依赖服务器已安装的工具链(Go、Node、sqlite3 等),改 CI 时注明需在 runner 主机预装的依赖。- 密钥用 Drone 仓库/组织密钥注入环境变量,勿写入仓库明文。
部署(Caddy)
- 典型模式:Caddy 终止 TLS,反代到 Go 监听端口;或对静态
root指向 Vitedist,/api等路径reverse_proxy到后端。 - 优先 Caddyfile 声明式配置;注意
file_server与 SPAtry_files类行为与 React Router 模式一致。
进程管理(Go 应用)
- 禁止使用
systemctl、systemd unit、daemon-reload等方式管理本仓库的 Go 二进制。 - 使用
nohup:部署脚本在替换二进制后,先结束旧进程(例如pkill -x <二进制名>,或读 PID 文件kill),再执行nohup /path/to/binary >> /path/to/app.log 2>&1 &;必要时echo $!写入.pid便于下次优雅停止。 - 环境变量在启动该行的 shell 中已
export,或由 Drone 步骤注入后再执行nohup,勿依赖 systemd 的Environment=。
开发与部署文档(功能完成后)
功能或里程碑合并前,应把「如何在本机跑通、如何打出生产包、流水线与服务器上发生什么」写清楚,便于本人或他人接手与排障。下列条目按本栈默认约定组织;若某仓库的 Makefile、.drone.yml、nohup 启动命令与日志路径不同,以仓库内实际文件为准。
1. 本地开发与联调
- 后端:通常
make dev-backend或等价命令(例如go run -tags dev .);确认ADDR、DB_PATH、JWT_SECRET等环境变量在开发期的取值与文档一致。 - 前端:通常
make dev-frontend或cd frontend && npm run dev;通过 Vite 代理将 API 指到本地 Go 端口,避免生产路径硬编码。 - 数据库与文件:说明 SQLite 文件路径、上传目录等是否在仓库外或需初始化脚本;新增迁移或种子数据时写明执行顺序。
2. 合并前的本地验证(与 CI 对齐)
- 在仓库根目录执行与 CI 相同的构建序列(例如
Makefile的build:frontend下npm ci && npm run build,再go build …),确保无仅本地才有的依赖或未提交的frontend/dist误用。 - 若有
go test、npm test、lint,在说明中列出应执行的命令;无测试时至少注明「已手工验证的场景」(关键 API、页面、鉴权路径)。
3. 生产构建与二进制
- 产物:单一 Go 二进制(可内嵌前端
dist)或「二进制 + 静态目录」二选一,与 Caddy/路由设计一致;写明生产构建使用的 Go build tags(例如dev与默认/生产 embed 的差异)。 - 优化:如使用
-ldflags="-s -w"等,在文档中一笔带过即可,避免与 CI 中的go build参数不一致。
4. CI(Drone exec)在服务器上做什么
- 触发条件:例如仅
main分支;说明是否「每次 push 都构建、仅 main 部署」。 - 构建步骤:与
.drone.yml逐步对应(进入frontend、npm ci、npm run build、go build输出路径)。 - 部署步骤:例如将二进制
cp到固定路径后,结束旧进程再以nohup /path/to/binary >> /path/to.log 2>&1 &拉起新进程(不得使用systemctl);注明需要 exec runner 所在机器 已预装 Go/Node/sqlite3 及版本下限,与.drone.yml注释一致。 - 密钥:列出需在 Drone 中配置的密钥名(不落仓库);若新增环境变量,说明在 Drone 步骤
environment中注入,或在部署 shell 里export后再执行nohup。
5. 运行时与 Caddy
- 进程:监听地址与端口(如
:8882)、工作目录、读写路径(数据库、上传目录)。 - Caddy:站点块域名、
reverse_proxy或file_server与 SPA 路由的关系;TLS 由 Caddy 管理时,无需在应用内重复监听 443。 - 健康检查:若有
/health或等价端点,写明供负载均衡或运维探活使用。
6. 交付物形式(收尾时建议产出)
- PR / 合并说明中简述:行为变更、配置项变更、是否需要一次手动迁移数据,以及部署侧是否需调整
pkill/日志路径/nohup行。 - 可选:若仓库维护
README或独立docs/deploy.md,将本节要点同步到该文件,避免知识只存在于对话中;未要求时不要新建大段无关文档,仅补充与本次部署相关的增量。
7. 回滚与风险
- 部署失败时:恢复上一版二进制(或从上一成功构建的制品恢复),结束当前进程后再次用
nohup启动旧二进制;若涉及数据库 schema,说明是否可安全回滚或需备份先行。 - 对 SQLite 文件、上传目录在部署脚本中的覆盖风险点一句提醒。
默认偏好
- 遵守上文「评审与前提论证」:重大决策前先写完前提与反驳,再动手。
- 改动范围限于实现需求:不无故更换栈内技术或引入与 sqlite/exec runner 冲突的部署假设。
- 新建子项目时目录与命名与现有仓库一致;无现成约定时采用常见布局:
cmd/、internal/、web/或frontend/。