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

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 指向 Vite dist/api 等路径 reverse_proxy 到后端。
  • 优先 Caddyfile 声明式配置;注意 file_server 与 SPA try_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 .);确认 ADDRDB_PATHJWT_SECRET 等环境变量在开发期的取值与文档一致。
  • 前端:通常 make dev-frontendcd frontend && npm run dev;通过 Vite 代理将 API 指到本地 Go 端口,避免生产路径硬编码。
  • 数据库与文件:说明 SQLite 文件路径、上传目录等是否在仓库外或需初始化脚本;新增迁移或种子数据时写明执行顺序。

2. 合并前的本地验证(与 CI 对齐)

  • 在仓库根目录执行与 CI 相同的构建序列(例如 Makefilebuildfrontendnpm ci && npm run build,再 go build …),确保无仅本地才有的依赖或未提交的 frontend/dist 误用。
  • 若有 go testnpm 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 逐步对应(进入 frontendnpm cinpm run buildgo 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_proxyfile_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/