云控安装与迁移

新站按部署包安装;已经在跑的站点改更新源后走在线升级。装完必须挂上每分钟计划任务,云打包才能自动把安装包拉回本机。

云控后台走「在线更新」。电脑上的客户端要另装,旧客户端不会自动变成新客户端。

从这里开始

服务器要求

  • PHP 8.0 及以上,扩展:pdo_mysql、mbstring、openssl、fileinfo、gd、bcmath、curl、zip
  • MySQL 8.0,字符集 utf8mb4 / utf8mb4_unicode_ci
  • Nginx 或 Apache,宝塔可以。必须先配好域名和 HTTPS
  • 网站运行目录指向 public/

新装云控

官方给的 local-agent-admin-x.y.z.zip 是全量包,和新站安装、已有站在线更新是同一份。不要把示例 .env 覆盖已经生成的配置。

  1. 宝塔 → 网站 → 添加站点。域名填付款时登记的那个,并配好 HTTPS。
  2. 「网站目录」先记下来,一般是 /www/wwwroot/你的域名。不要勾选到 public。
  3. 文件管理进入这个目录,清空默认的 index.html 等(空站再装)。
  4. 上传 zip 到这个目录(网站根,不要传到 public 里面),再解压。
  5. 解压后这个目录下应直接看到:artisan、app、public、vendor。如果多出一层文件夹,把里面的文件全部移到网站根,再删掉空文件夹。
  6. 网站设置 → 网站目录:网站目录仍是上面的根目录;运行目录选 /public。保存。
  7. 权限(用户名按面板,常见 www):
    chown -R www:www storage bootstrap/cache
    chmod -R 775 storage bootstrap/cache
  8. 浏览器打开 https://你的域名/install.php,按向导完成:环境检测 → 权限 → 新建空数据库 → 站点名和管理员。不要用别人的库,不要用官方站的库。
  9. 装完后 /install.php 会锁定。后台地址是 https://你的域名/admin/。

装完必做

不要用示例文件覆盖已经装好的 .env。用宝塔打开网站根的 .env,确认这几行(域名换成你的):

APP_URL=https://你的域名
AGENT_BUILD_BASE_URL=https://build.haohuoban.com
UPDATE_CHECK_URL=

UPDATE_CHECK_URL 留空即可,检查更新会走官方授权端。

若提示域名未授权或检查失败,把实际访问的 HTTPS 域名发到群里登记后再检查一次。域名必须和付款时登记的一致。

计划任务

必须在宝塔加一条每 1 分钟执行的任务,命令是 php artisan schedule:run。云打包把安装包拉回本机、套餐过期、心跳报活都靠它。

没挂上,官方中转即使已经有包,后台也会一直停在「拉取中」。再打一包不会更快,只会多一份等着拉的包。

  1. 宝塔 → 计划任务 → 添加,类型选 Shell,周期选每 1 分钟。
  2. 工作目录填网站根(能直接看到 artisan 的那一层,不是 public)。
  3. 执行用户用网站用户(常见 www)。
  4. 命令写成面板里的完整 PHP 路径,例如:
cd /www/wwwroot/你的站点根 && /www/server/php/82/bin/php artisan schedule:run

任务加好后等两分钟,看该任务日志。没有 command not found 或权限错误,才算挂上。再登录后台 → 在线更新 → 检查更新,应能看到当前版本。

不要做成常驻服务

schedule:run 跑完该分钟的任务就退出。不要把它配成 systemd 常驻服务,尤其不要写 Restart=always。那样会每几秒空跑一轮,journalctl 里重启计数会涨到几千。

现场常见:服务启动 → 打印 No scheduled commands are ready to run(这一分钟没事可跑,正常)→ 正常退出 → 立刻再拉起。

已经做成服务的,先停掉:

systemctl stop 你的调度服务
systemctl disable 你的调度服务

再按上面改成宝塔每分钟一条,或给网站用户(常见 www)加 crontab:

* * * * * cd /www/wwwroot/你的站点根 && /www/server/php/82/bin/php artisan schedule:run >> /dev/null 2>&1

不要 crontab 和 systemd 同时挂同一条。手工跑一次能成功,只说明程序没坏,不能说明调度方式对了。

日志出现 Unable to create lockable file

路径一般在 storage/framework/cache/data/。缓存目录里混入了 root 或其他用户写下的文件,网站用户写不进去。登录续期、限流、计划任务互斥都会踩这个锁。

常见来源:用 root 跑过 artisan,或计划任务的执行用户不是网站用户。在网站根执行(用户名按面板):

chown -R www:www storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
runuser -u www -- php artisan cache:clear

以后排障一律用网站用户跑 artisan,不要再用 root。

已有站点迁到本授权端

面向已经在跑的站点。新装请走上一节,不要用这一节硬套。

不要重新上传安装包覆盖整站,不要再打开 /install.php,不要用压缩包往正在跑的网站目录里乱解。升级过程不要手动覆盖 .env,不要删除 storage/installed.lock。先备份整站和数据库。

「检查更新」里如果出现下面任一情况,说明检查地址还是原来那套,不是现在的官方授权端:

  • 本机版本比远端还新(例如本机已经较新,远端停在很旧的号)
  • 界面显示「已是最新」,但你知道官方已经发了更新的包
  • 远端版本长期不再前进

这时改配置就能接到新包,不必重装。在网站根 .env 里只改这几项,其它行留着:

AGENT_BUILD_BASE_URL=https://build.haohuoban.com
UPDATE_CHECK_URL=https://build.haohuoban.com/api/updates/admin/version.json
UPDATE_RELEASES_URL=https://build.haohuoban.com/api/updates/admin/releases.json
UPDATE_ALLOWED_ZIP_HOSTS=build.haohuoban.com

然后在网站根执行:

php artisan config:clear

再登录后台 → 在线更新 → 重新检查。远端应变成官方当前包,就可以点升级。升级会先备份代码和数据库到 storage/app/backups/,期间后台会短暂不可用。失败时把「升级历史」里的报错原文发到群里,用备份恢复,不要自己再解一层压缩包。

升完再核对四件事:

  1. 「检查更新」里本机版本与远端版本一致。
  2. 宝塔已有每分钟 schedule:run(PHP 写完整路径,工作目录是网站根)。
  3. 网站文件属主是运行用户(常见 www)。属主不对时,下一次在线更新可能写文件失败。
  4. 打开过配置缓存的站点,升完再执行一次 php artisan config:clear。

检查更新返回 HTTP 403

四行更新地址已经是官方授权端,后台仍显示「远端更新源返回 HTTP 403」。域名也已经登记。这时不是地址写错,改 .env 再清缓存也过不了。

1.6.44 之前的云控,检查更新不会带上本站域名。授权端要凭这个域名才发放更新包。请求到了,但认不出是哪一台站,直接拒绝。能带上域名的新代码,要等这次更新装上去才有,所以旧站自己点「立即升级」升不上去。

只有这种情况才能用当前官方全量包覆盖网站代码。其它时候仍不要往正在跑的目录里解压缩包。

覆盖前先备份整站和数据库。不要覆盖 .env,不要删除 storage/ 和 storage/installed.lock,不要再打开 /install.php。
  1. 把当前官方云控全量包解到网站根(能直接看到 artisan 的那一层)。多出来的一层文件夹要挪平。上面三样保留不动。
  2. 用网站用户(常见 www)在网站根执行迁移和清缓存。PHP 写面板里的完整路径,例如:
cd /www/wwwroot/你的站点根
/www/server/php/82/bin/php artisan migrate --force
/www/server/php/82/bin/php artisan config:clear

宝塔锁着的 public/.user.ini 改不了属主,可以忽略。

若迁移报某张表已经存在,把报错原文发到群里。不要删表,不要重装。做完再登录后台 → 在线更新 → 重新检查,本机版本应和远端一致。

1.6.44 及以上不用覆盖,按上一节改四行即可。

云打包停在「拉取中」

打包本身往往已经完成。安装包已经在官方中转备好,缺的是你的云控把大约 90MB 拉回本机。这件事只能靠上面的计划任务在命令行完成,官方写不进你的磁盘。不要靠网页里的「刷新拉取」。

先等 3 到 10 分钟,不要连点「刷新拉取」。网页里拉大会被服务器超时掐断,越点越卡。也不要重新打包、不要重装、不要覆盖 .env。再打一包不会更快,只会多出一份等着拉的包。
  1. 回宝塔确认每分钟 schedule:run 在跑,日志没有报错。
  2. 任务挂上后,后台「客户端打包」历史应变成「已落盘」,详细状态见 客户端打包。
  3. 任务在跑仍超过 15 分钟不到,把域名、打包时间和日志里带 CloudBuildFetch 的几行发到群里。

中转上的包大约保留 14 天。一直不拉回,过期会被清掉,那时才必须重新打包。14 天内不要当成「没打出来」。

电脑上的客户端

旧客户端和应用名、更新通道都不是同一套,不能指望「检查更新」自动换成新客户端。

  1. 先备份本机对话和知识库。
  2. 卸掉旧客户端。
  3. 从你的云控站点或群里提供的地址下载新安装包。
  4. 装好后,登录地址改成你自己的云控域名。

新旧软件的本机数据目录可能不同,不能假设对话和知识库会自动迁过去。

常见问题

现象常见原因怎么处理
打开站点不是后台,或满页 404 运行目录不对,或 zip 多解了一层 网站根应能直接看到 artisan,运行目录才是 /public
检查更新失败 / 未授权 域名没登记,或写成了 HTTP 把实际访问的 HTTPS 域名发到群里
检查更新 HTTP 403,地址已是官方的 云控低于 1.6.44,检查更新不带本站域名 用当前全量包覆盖代码,保留 .env 和 storage。见 检查更新返回 HTTP 403
本机比远端还新,却显示已是最新 .env 仍指向旧更新地址 按「已有站点迁过来」改四行,清缓存后再检查
在线更新写文件失败 文件属主不是网站运行用户 把整站改成运行用户(常见 www)后再升级
计划任务服务重启计数一直涨 把 schedule:run 做成了常驻服务 停掉该服务,改成宝塔每分钟一条。见 不要做成常驻服务
日志 Unable to create lockable file 缓存目录属主不是网站用户 把 storage 和 bootstrap/cache 收归网站用户,以后不要用 root 跑 artisan
云打包一直「拉取中」 没配每分钟计划任务,或又打了一包 补上 schedule:run,等任务拉完。不要重打。约 14 天内官方中转还在
打了很多包,本机仍没有安装包 每打一次只是多一份等拉的包 先挂计划任务,不要继续提交
生图或对话模型是空的 本站尚未授权,或还没同步 先确认已登录且域名已登记;模型来自云端同步

遇到问题或报错,把域名和报错原文发到群里。