用途
在用户自己的 VPS 上搭建一个仅限本人或小团队使用的私有内部工具,地址形如 crm.my-domain.com,外人无法打开,并把它交给用户的智能体(Hermes)日常运行和修复。如果要做的是供他人注册或付费使用的应用,应改用 create-software 技能。
安全模型
应用被三道墙保护:
- Cloudflare WAF 自定义规则,作用于应用和 Convex 主机名,只放行用户的 IP 与 VPS IP。
- Dokploy basic auth,使用长随机密码,由用户保存在自己的密码管理器中。
- 每个 Convex 函数内部的服务端密钥或已登录用户校验。
用户 IP 变化(出差、4G)时,可让智能体“add my IP”更新规则。团队场景可用 Cloudflare Access 的邮件验证码替代 IP 列表。
技术栈
- 应用:TanStack Start(React、TypeScript、Vite),Node 服务器构建。
- UI:shadcn/ui 基于 Base UI + Tailwind CSS v4、lucide-react、sonner。
- 数据库与后端、定时任务:Convex,通过 Dokploy Convex 模板自托管在 VPS 上。
- 客户端库:create-software 中列出的 TanStack 库(Query + @convex-dev/react-query、Table、Virtual、Form、Markdown、Hotkeys、Pacer、AI)。
- 邮件:仅在需要发送时使用 Lumail,经由 @lumail/convex。
- 托管:VPS 上的 Dokploy,从 GitHub 仓库构建。
- 域名、DNS、锁定:Cloudflare 配合 cf CLI,DNS 代理,WAF IP 规则。
- 运行与修复:用户的智能体 Hermes,使用 Dokploy API token。
使用方式
先做访问检查,Dokploy 必须已安装在 VPS 上,否则应停止并说明。检查命令示例:
git --version && gh auth status cf --version && cf auth whoami ssh <vps> 'docker ps --format "{{.Names}}" | head' dokploy-cli auth test
然后运行 grill-me 技能,只有在需求简报确认后才开始构建。内部工具需确认“除你之外还有谁会用”,以及子域名和需放行的 IP(用户机器上可用 curl -s https://ifconfig.me 获取当前 IP)。
构建流程要点:脚手架生成 TanStack Start + Tailwind + shadcn 初始化,Node 服务器构建与 Dockerfile(端口 3000),git init 后创建私有 GitHub 仓库并推送。每个 VPS 部署一次 Dokploy Convex 模板(后端与仪表盘)到 convex-api.<domain> 与 convex-site.<domain>,在后端容器生成管理密钥,通过 .env.local 中的 CONVEX_SELF_HOSTED_URL 和 CONVEX_SELF_HOSTED_ADMIN_KEY 指向 CLI。为所有查询建立索引,用 .take(n) 或 .paginate() 限制增长的表。
每个公共 Convex 函数首先调用同一辅助校验(用 npx convex env set 设置的共享密钥,或多人使用时用 Better Auth 邮件 OTP)。仅服务端调用的函数使用 internal*。
界面使用 useSuspenseQuery(convexQuery(...)) 实现实时更新,列表用 TanStack Table,表单用 TanStack Form,cmd+k 与 j/k 快捷键用 TanStack Hotkeys。按 references/fast-app.md 做性能优化:defaultPreload: "intent"、30 秒查询缓存、详情页 loader、每个路由匹配真实布局的 pendingComponent 骨架屏、每个异步按钮的加载状态、有索引且有界的 Convex 读取。
在 Dokploy 中从 GitHub 仓库创建应用(Dockerfile 构建),环境变量(Convex URL、密钥)在 Dokploy 中设置,绝不写入仓库,开启推送自动部署。在 Dokploy 绑定 tool.<domain> 并启用 HTTPS,自行在 Cloudflare 创建 DNS 记录(A 记录指向 VPS IP,代理开启)。不要为应用在 VPS 上开放端口,一切经 Dokploy 代理走 Cloudflare。
为 Dokploy 应用启用 basic auth 并生成密码,只告知用户一次,让其存入密码管理器,绝不写入文件。创建 Cloudflare WAF 自定义规则,阻止列表外 IP 访问应用和 Convex 主机名(可用 cf cli search "waf custom rule" 查找命令)。若 VPS 配置了备份,将 Convex 卷加入 Dokploy 每夜备份到 R2。
交付给智能体:在智能体项目文件夹写 About.md,包含 URL、仓库、Dokploy 应用 id、Convex URL、密码存放位置(不写密码本身)和 IP 规则 id。告知智能体如何重新部署(推送或 Dokploy API)、读取部署日志、应用日志并在用户报告故障时修复、在规则中增删 IP。
验证:从允许的 IP 访问 URL 会要求密码,随后应用加载且主要操作可用真实数据完成;从非允许 IP(另一台服务器或不同网络)访问时 Cloudflare 同时拦截应用和 Convex API 主机名;向 GitHub 推送会自动重新部署。修复所有错误后,对 Convex 函数和锁定运行 audit-safety。切勿打印、提交或记录密码、管理密钥或 token。最终回复 URL、打开方式(密码 + 允许 IP)以及智能体现在能做什么。
适用场景与限制
适用于个人或小团队的私有内部工具,需要密码与 IP 双重锁定、并交由智能体运维。限制:Dokploy 必须已预先安装;仅供他人注册或付费的应用不适用;IP 变化需手动或经智能体更新;团队可用 Cloudflare Access 邮件验证码替代 IP 列表。