diff --git a/skills/ucloud-sandbox-site/SKILL.md b/skills/ucloud-sandbox-site/SKILL.md index 6c73c6d..279322f 100644 --- a/skills/ucloud-sandbox-site/SKILL.md +++ b/skills/ucloud-sandbox-site/SKILL.md @@ -69,6 +69,16 @@ ucloud-sandbox-cli update -y && ucloud-sandbox-cli version 本节只准备 `ucloud-sandbox-cli`,不要安装或更新本 Skill 本身。 +### 判断 Skill 是否最新 + +当需要确认 Skill 是否为最新版本时,比较已安装 CLI 版本与 GitHub 最新 release;两者一致(或 Skill 相关文件无落后提交)即视为 Skill 已是最新: + +```bash +ucloud-sandbox-cli version +curl -fsSL https://api.github.com/repos/ucloud/ucloud-sandbox-cli/releases/latest | grep tag_name +``` +如果不是最新的通过`npx skills add ucloud/ucloud-sandbox-cli -s astraflow-api -s ucloud-sandbox-site`提示用户进行更新skill + ## 连接站点 ### 1. 获取并校验站点连接 Key @@ -141,6 +151,50 @@ CLI 连接验证与公共 URL 访问是两件事:AI 可以通过 CLI 连接沙 IP 名单和自定义域名都属于站点侧配置,AI 无法通过 CLI 查询或修改,只能引导客户在星图控制台调整或改用自定义域名访问。此时可以保留站点内 `http://127.0.0.1:80` 的验证结果,但不要宣布公共页面验证通过。 +### 5. 返回统一连接提示 + +完成连接验证(成功或失败)后,按本节的固定模板向用户返回提示。不要省略字段、改动措辞或用其他格式替代;模板中的 ``、`` 用实际值替换。 + +连接成功(第 2 步的 `exec` 验证通过)时返回: + +``` +已成功连接站点,可以开始开发。 +- 沙箱 ID: +- 地域: +- 工作目录:/home/user +- 连接技能:ucloud-sandbox-site(<技能状态>) + +使用指引 +- 开发站点:用自然语言描述你的想法,Agent 会帮你开发。 +- 保存数据:站点已预装 PostgreSQL,默认未启动。需要时告诉 Agent:“使用预装数据库保存数据。” +- 查看效果:开发完成后,回到「站点空间」,点击「访问」即可查看,无需单独发布。 +``` + +连接失败(连接 Key 校验通过但 `exec` 验证失败)时返回: + +``` +连接失败,暂时无法访问站点。 +- 沙箱 ID: +- 地域: +- 失败原因:<根据实际返回信息填写> +- 连接技能:ucloud-sandbox-site(<技能状态>) + +排查指引 +- 更新技能:旧版技能可能导致连接失败,请重新安装最新版后重试。 +- 核对连接信息:回到「站点空间」,重新复制完整连接语句后交给 Agent。 +- 仍无法连接:将以上信息及错误提示提供给技术支持,协助排查。 +``` + +各字段来源: + +- 沙箱 ID:从连接 Key 派生的沙箱 ID,不含连接码。 +- 地域:当前 CLI 配置或 `UCLOUD_SANDBOX_REGION` 中的地域,可通过 `ucloud-sandbox-cli config` 确认。 +- 工作目录:第 2 步验证命令中 `pwd` 的输出,正常为 `/home/user`。 +- 失败原因:摘自 CLI 的实际错误输出,可以概括但不得虚构,也不要包含完整连接 Key 或连接码。 +- 连接技能状态三选一:会话或平台已确认技能为最新版时用“已是最新”;已确认技能不是最新时用“请重新安装最新版,否则可能影响新功能使用”(成功模板)或“请重新安装最新版,否则可能影响连接及新功能使用”(失败模板);无法完成检查时用“未能检查更新,请确认是否为最新版”。不要编造检查结果。 + +连接 Key 为旧格式或校验失败时不套用失败模板,按“获取并校验站点连接 Key”的要求回复。连接成功后继续执行站点操作时,不需要重复返回成功模板。 + ## 常用命令 以下示例均假定当前 shell 已正确设置 `UCLOUD_SANDBOX_API_KEY` 和 `SANDBOX_ID`。`sandbox` 可以缩写为 `sbx`。 @@ -171,6 +225,78 @@ ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" "python3 --version && node --versi ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" "sudo -n apt-get update && sudo -n apt-get install -y " ``` +### PostgreSQL 15 与 pgvector(仅适用于 site 模板) + +基于 `site` 系列模板(规格模板命名格式为 `site-{CPU核数}c-{内存GiB数}g`)构建的站点内置 PostgreSQL 15、客户端和 pgvector。先检查实际环境,不要仅凭站点连接 Key 判断数据库已安装或已启动: + +```bash +ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" \ + "whoami && command -v start-postgres && command -v stop-postgres && psql --version" +``` + +默认 Linux 用户应为 `user`。`base` 模板不包含这些数据库组件;若命令缺失,先确认站点模板和实际安装情况,不要用站点凭证创建或替换沙箱。 + +#### 启动、验证和停止 + +- `start-postgres` 内部执行 `sudo -n systemctl start postgresql-vector.service`,由其依赖启动 `postgresql@15-main.service`,调用者无需再包一层 sudo。 +- `postgresql-vector.service` 是以 `postgres` 运行的 oneshot 初始化单元:通过 `enable-pgvector` 按需创建非超级用户角色 `user`、由该角色拥有的 `ucloud` 数据库,并在 `ucloud` 中执行 `CREATE EXTENSION IF NOT EXISTS vector`。 +- 初始化单元使用 `RemainAfterExit=yes`,显示 `active (exited)` 正常;重复启动已活动的单元不会重新执行初始化 SQL,也不会修正已有角色或数据库的属性。 + +在同一沙箱中启动数据库: + +```bash +ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" "start-postgres" +``` + +通过 Unix Socket 检查服务、连接身份和向量类型。`pg_isready` 只能检查服务就绪,后面的 SQL 成功才证明应用身份可以连接并使用 pgvector: + +```bash +ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" \ + "sudo -n systemctl is-active postgresql@15-main.service && \ + sudo -n systemctl is-active postgresql-vector.service && \ + pg_isready -h /var/run/postgresql -p 5432 -U user -d ucloud && \ + psql -X -w -v ON_ERROR_STOP=1 -h /var/run/postgresql -p 5432 -U user -d ucloud \ + -c \"SELECT current_user, current_database(), '[1,2,3]'::vector;\"" +``` + +预期查询返回 `user`、`ucloud` 和 `[1,2,3]`。需要停止数据库时执行: + +```bash +ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" "stop-postgres" +``` + +`stop-postgres` 内部停止 `postgresql@15-main.service`,初始化单元随依赖关系一起停止;它不会删除数据库。不要把停止数据库作为连接验证的收尾步骤,以免中断网站。 + +#### 应用连接配置 + +模板默认使用本地 Unix Socket 目录 `/var/run/postgresql`、端口 `5432`、数据库 `ucloud` 和角色 `user`。`pg_hba.conf` 对本地 Socket 使用 `peer` 认证,对 IPv4、IPv6 的所有 TCP 连接(含回环地址)使用 `reject`;模板同时关闭了 PostgreSQL SSL。 + +- 应用和迁移命令必须在同一沙箱内以 Linux 用户 `user` 运行。peer 核对操作系统身份,仅在配置中填写数据库用户名 `user` 并不能让 root 进程通过认证。 +- 显式指定 Socket 目录,不使用 `127.0.0.1` 或 `localhost`。不要假定省略 `host` 就会使用 Socket,例如 Node.js 的 `pg` 默认连接 `localhost`。 +- 指定 Socket 目录后,`port=5432` 选择的是 `.s.PGSQL.5432` Socket 文件,并不代表走 TCP。此连接不需要数据库密码,也不要要求 SSL 或放开 `pg_hba.conf` 来修复连接。 +- 不要使用超级用户 `postgres` 运行业务应用;必要的管理员操作使用 `sudo -n -u postgres psql`。 + +应用连接示例: + +| 客户端 | 连接示例 | +| --- | --- | +| Python / psycopg | `psycopg.connect("host=/var/run/postgresql port=5432 dbname=ucloud user=user")` | +| Node.js / pg | `new Pool({ host: '/var/run/postgresql', port: 5432, database: 'ucloud', user: 'user' })` | +| Go / pgx 或 lib/pq | `host=/var/run/postgresql port=5432 dbname=ucloud user=user sslmode=disable` | + +#### 同时满足 peer 认证和 80 端口要求 + +使用数据库的动态网站不能套用后文的 root 静态服务启动示例。可通过 systemd 的 `User=user` 与 `AmbientCapabilities=CAP_NET_BIND_SERVICE` 让应用以 `user` 身份绑定 `0.0.0.0:80`,使用 `sudo -n` 管理服务。此时进程、PID 和日志由 systemd 管理,无需另存 PID 文件;环境变量加载和 HTTP 验证仍按部署章节执行。 + +#### 数据库排错 + +| 现象 | 处理 | +| --- | --- | +| Socket 不存在或连接被拒绝 | 检查 `start-postgres` 结果、`systemctl status postgresql@15-main.service postgresql-vector.service` 和 `/var/run/postgresql`;需要日志时使用 `sudo -n journalctl -u postgresql@15-main.service -u postgresql-vector.service -n 100 --no-pager`,输出前检查是否包含敏感内容 | +| `pg_hba.conf rejects connection`,或日志出现 `127.0.0.1` / `::1` | 客户端走了 TCP;显式把 `host` 改成 Socket 目录,并检查环境变量或连接 URL 是否覆盖配置 | +| `Peer authentication failed` 或 `role "root" does not exist` | 检查实际应用或迁移进程的 Linux 用户与数据库角色,改为 `user`;不要通过 `trust`、密码或放开 TCP 绕过 peer | +| 缺少 `ucloud`、`user` 或 `vector` 类型 | 检查初始化单元状态和日志,并确认连接的是 `ucloud`;初始化脚本只在该数据库中启用 `vector` | + ### 浏览和读取文件 ```bash @@ -326,7 +452,7 @@ ucloud-sandbox-cli sandbox exec "$SANDBOX_ID" ' 启动前通过 sudo 创建日志和 PID 文件,再把所有者归还给 `user`,既能兼容先前试错留下的 root 文件,也能避免后续维护需要一直提权。必须在 root 启动器内部记录 `$!`,确保 PID 指向真正的网站服务,而不是外层 `sudo` 包装进程。 -对于 SSR、Node 或其他动态服务,保留同样的 `sudo -n`、PID、日志、后台运行和环境变量加载模式,把 `exec python3 ...` 替换成项目的生产启动命令,并显式设置或传入 `HOST=0.0.0.0`、`PORT=80`。不要把开发服务器当作默认的生产部署方案。 +对于不使用本地 PostgreSQL 的 SSR、Node 或其他动态服务,保留同样的 `sudo -n`、PID、日志、后台运行和环境变量加载模式,把 `exec python3 ...` 替换成项目的生产启动命令,并显式设置或传入 `HOST=0.0.0.0`、`PORT=80`。不要把开发服务器当作默认的生产部署方案。 ### 验证并返回地址