开始使用
安装互客鱼(自托管)
本指南将引导您从全新的服务器到运行中的互客鱼安装,包含一个管理员账户、 一个已发布的智能体,以及在小部件测试页面上回答问题。如果您的服务器已经 配置好 PHP、Node、数据库和 Redis,预计需要 20-40 分钟。
1. 服务器要求
| 组件 | 最低要求 | 说明 |
|---|---|---|
| PHP | 8.3+ | 推荐 8.4。扩展:bcmath、curl、fileinfo、gd、intl、mbstring、openssl、pdo_pgsql(或 pdo_mysql)、tokenizer、xml、zip。 |
| Composer | 2.6+ | 用于安装 PHP 依赖。 |
| Node.js | 20+ | 用于构建管理 SPA 和访客小部件。 |
| 数据库 | PostgreSQL 14+ 或 MySQL 8.0+ | Postgres 是主要目标。 |
| Redis | 7+ | 缓存、会话、队列、热路径检索缓存。 |
| RAM / CPU | 2 vCPU / 2 GB | 一个应用 + 一个 worker 进程。如果将它们运行在同一台机器上,请增加配置。 |
| 磁盘 | 10 GB+ | 应用 + 日志空间。向量存储位于 Cloudflare / Qdrant,不在磁盘上。 |
| TLS | HTTPS | 小部件需要在 HTTPS 源上加载到客户网站。在 FrankenPHP 前使用 Caddy / Nginx / Cloudflare。 |
| SMTP | 任何提供商 | Postmark / Resend / SES / 您自己的 SMTP。密码重置、潜在客户通知、账单收据必需。 |
您需要的外部账户
- 至少一个 LLM 提供商 — Cloudflare Workers AI 是 最便宜的,我们推荐使用(聊天 + 嵌入 + 向量数据库 + 浏览器爬虫都在一个账单上)。 OpenAI 可以作为直接替代品。 OpenRouter 也可以,并提供免费的 Llama 3.3 模型。
- 向量存储 — Cloudflare Vectorize(首选,共享 Cloudflare 账户)或自托管的 Qdrant 实例。
- 可选:Stripe 用于客户账单,以及 Sentry / Honeycomb 用于错误/追踪报告。
2. 将代码部署到服务器
上传您下载的源代码包(CodeCanyon zip),或克隆您的私有仓库, 到文档根目录。本指南假设您在项目目录内操作。
cd /var/www/hukeyu # or wherever you unpacked the zip
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate
php artisan key:generate 向 .env 写入一个新的
APP_KEY。生成后立即备份此值 —
app_settings 中的每个加密列(您将在第 7 步中粘贴的
Stripe / Cloudflare / OpenAI 密钥)都使用此密钥密封。丢失它意味着
丢失这些秘密。
3. 配置数据库连接
编辑 .env 并填写数据库块。默认指向本地 Docker Postgres;
请替换为您的实际主机。
DB_CONNECTION=pgsql # or mysql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=hukeyu
DB_USERNAME=hukeyu
DB_PASSWORD=…strong-password…
如果数据库不存在,请先创建:
createdb -U postgres hukeyu
# or, MySQL:
mysql -uroot -p -e "CREATE DATABASE hukeyu CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
4. 填写 .env 的其余部分
您可以通过管理 UI 稍后翻转的每个键 — Stripe、PayPal、Razorpay、
Cloudflare、OpenAI、OpenRouter、邮件、品牌 — 可以在
.env 中留空并在 Web 管理中粘贴。下面的键是应用在启动时
需要的,在您打开管理界面之前。
| 变量 | 值 |
|---|---|
APP_URL | 您将提供应用的公共 HTTPS URL,例如 https://app.example.com。用于构建小部件代码片段、OAuth 回调和签名 URL。 |
APP_NAME | 标题栏和电子邮件中显示的名称。 |
APP_ENV | production. |
APP_DEBUG | false. |
REDIS_HOST / REDIS_PORT / REDIS_PASSWORD | Redis connection. |
SESSION_DRIVER / CACHE_STORE / QUEUE_CONNECTION | All redis in production. |
WIDGET_JWT_SECRET | 访客会话 JWT 的 HS256 签名密钥。生成 openssl rand -hex 32 并粘贴结果。不要保留默认值。 |
BROADCAST_CONNECTION | 如果您想要实时收件箱 + 人工聊天接管,则为 reverb。设置为 null 以禁用。 |
REVERB_APP_ID / REVERB_APP_KEY / REVERB_APP_SECRET | 标识 Reverb 应用的随机令牌。生成新的字符串。 |
REVERB_HOST | WebSocket 进程的公共主机名 — 如果在同一主机上反向代理 WS,则与 APP_URL 相同的域。 |
REVERB_SCHEME | wss in production. |
MAIL_FROM_ADDRESS / MAIL_FROM_NAME | 外发邮件的发件人身份。必需。 |
每个变量的完整参考位于 环境变量。
LLM 提供商密钥(您也可以稍后在管理中粘贴这些)
至少设置其中一个,以便新创建的智能体可以回答问题。 自动绑定器根据存在的密钥按 Cloudflare → OpenRouter → OpenAI 的顺序选择。
# Cloudflare Workers AI (preferred)
CLOUDFLARE_ACCOUNT_ID=
CLOUDFLARE_API_TOKEN=
CLOUDFLARE_VECTORIZE_INDEX=hukeyu-chunks
# or OpenAI
OPENAI_API_KEY=
# 或 OpenRouter(有免费的 Llama 3.3 模型)
OPENROUTER_API_KEY=
LLM_PROVIDER=openrouter # 需要选择使用 OpenRouter
VectorizeClient::ensureCollection 是幂等的,
因此重新运行安装步骤是安全的。
5. 运行迁移并播种计划
php artisan migrate --force
php artisan db:seed --class=PlanSeeder --force
PlanSeeder 创建账单系统读取的 Free / Pro 计划行。
它是幂等的 — 重新运行它不会重复计划。
在生产环境中跳过 UserSeeder。它
创建演示账户 admin@mail.com /
customer@mail.com,使用公共密码
password — 本地开发没问题,但在公共部署上是
一个开放的门。
6. 构建前端包
npm ci
npm run build # admin Inertia SPA → public/build/
npm run build:widget # visitor widget → public/widget/widget.js
php artisan storage:link # symlinks public/storage → storage/app/public
php artisan optimize # caches routes, config, views
两个构建输出都与源代码一起提交到我们的部署工件中(CodeCanyon zip 包含预构建的它们),但在服务器上重新运行可确保包与您上传的代码的 PHP 版本匹配。
7. 提供应用服务并运行 worker
互客鱼在 Laravel Octane + FrankenPHP 上运行 HTTP 服务器,Horizon 用于队列,Reverb 用于 WebSocket 实时通道。这三个都需要被监督的进程;以下是使用 systemd 的单主机安装的最低要求。
应用服务器
# /etc/systemd/system/hukeyu-app.service
[Unit]
Description=hukeyu Octane (FrankenPHP)
After=network.target redis.service postgresql.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/hukeyu
ExecStart=/usr/bin/php artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8000 --workers=4
Restart=always
[Install]
WantedBy=multi-user.target
在您的 TLS 终止器(Caddy、Nginx、Cloudflare 代理)前放置,
指向 127.0.0.1:8000。反向代理是向公众提供
https://app.example.com 的服务;Octane 进程仅
绑定到 localhost。
队列 worker
# /etc/systemd/system/hukeyu-horizon.service
[Unit]
Description=hukeyu Horizon queue worker
After=network.target redis.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/hukeyu
ExecStart=/usr/bin/php artisan horizon
Restart=always
[Install]
WantedBy=multi-user.target
Horizon 默认监督 crawl / index / default 队列。
从平台管理的 /admin/queue-health 检查队列健康状况。
WebSocket 进程
# /etc/systemd/system/hukeyu-reverb.service
[Unit]
Description=hukeyu Reverb WebSocket server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/hukeyu
ExecStart=/usr/bin/php artisan reverb:start --host=0.0.0.0 --port=8080
Restart=always
[Install]
WantedBy=multi-user.target
反向代理 wss://realtime.example.com(或同一域上的不同路径)
到 127.0.0.1:8080。如果您设置
BROADCAST_CONNECTION=null,则跳过此进程 —
您将失去实时收件箱和人工接管功能。
启用并启动所有服务
sudo systemctl daemon-reload
sudo systemctl enable --now hukeyu-app hukeyu-horizon hukeyu-reverb
8. 配置 cron 调度器
多个作业按计划运行 — 刷新过时的爬取、同步 OAuth 源、释放过时的 “需要人工”对话、从缺口建议策划答案。选择以下两个选项之一。
选项 A — 主机 cron(最简单)
将单行添加到 root 的 crontab(或拥有项目文件的用户):
* * * * * cd /var/www/hukeyu && php artisan schedule:run >> /dev/null 2>&1
选项 B — Cloudflare Cron Worker
互客鱼可以部署一个 Cloudflare Worker,每分钟访问您安装的
/_internal/queue/tick 端点,这样您根本不需要主机 cron。
对于无法定期运行进程的无服务器部署很有用。
在您已将 Cloudflare 账户 ID 和 API 令牌粘贴到
设置 → 系统(下一步)后,打开
设置 → 系统 → Cron worker 并点击
Deploy。状态报告在
/settings/system/cron-worker/status。
9. 创建您的第一个管理员
在 {APP_URL}/register 正常注册。互客鱼会为您自动
创建第一个工作区。然后从命令行将您的账户提升为
super_admin,以便您可以访问平台管理并粘贴系统密钥。
php artisan hukeyu:make-admin you@example.com
注销并重新登录;/admin 和 设置 →
系统 现在在侧边栏中可见。
10. 通过管理界面输入系统密钥(推荐)
以 super_admin 身份打开 设置 → 系统。粘贴:
- Cloudflare 账户 ID + API 令牌 + Vectorize 索引名称 + AI Gateway URL(可选)。
- OpenAI 密钥(可选备用)。
- OpenRouter 密钥(可选,免费 Llama 3.3 模型)。
- Stripe publishable + secret + webhook 签名密钥(可选,用于账单)。
- PayPal / Razorpay 如果您想要额外的支付网关。
- 邮件 SMTP / API 凭证。
- 品牌 — 用您自己的标签、页脚徽标和链接目标替换“Powered by 互客鱼”。
每个部分都有一个 Test 按钮,可以使用您刚刚粘贴的
密钥与上游 API 通信 —
Test mail 发送真实电子邮件,
Test LLM 调用小型聊天完成,
Test Stripe 访问 Stripe API 根目录等。在保存之前使用这些,
以便立即捕获错误的密钥,而不是在第一次客户注册时。
APP_KEY 轮换需要手动迁移。
app_settings 中的加密列在您粘贴时使用
APP_KEY 的值密封;如果不重新加密就轮换,
将使它们无法读取,您将不得不重新粘贴每个密钥。
11. 冒烟测试安装
- 访问
{APP_URL}/admin并确认平台仪表板无红色横幅渲染。 - 从 设置 → 系统,点击每个 Test 按钮(邮件、LLM、Stripe)。每个都应报告成功。
- 从您的工作区,运行快速入门:创建智能体,从您自己的网站添加一个知识源,观察它翻转为 indexed,发布智能体,将嵌入代码片段粘贴到测试页面。
- 在隐身窗口中打开您的测试页面。向智能体询问一个应该从您索引的页面回答的问题。您应该在约 1 秒内看到流式传输的令牌和引用出现。
- 检查
/admin/queue-health— crawl + index 队列应该正在排出,没有失败的作业。
故障排除
| 症状 | 修复 |
|---|---|
Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest |
您跳过了 npm run build 或拉取了 resources/js/ 的更改而没有重新构建。运行 npm run build + npm run build:widget。 |
| 即使有索引的源,智能体仍回答“我没有足够的信息” | 可能是置信度阈值不匹配。Cloudflare 的 bge-base-en-v1.5 峰值在 0.55–0.65,OpenAI 峰值更高。打开智能体的 Advanced 选项卡并将 confidence_threshold 降低到 0.5 以支持 Cloudflare 安装。新智能体会自动获得此默认值。 |
| 小部件脚本加载但从未在客户网站上打开 | 检查 智能体 → 设置 → Allowed origins。每个条目都与页面的 Origin 头严格匹配;空列表意味着拒绝所有位置。参见 Allowed origins。 |
队列未排出;/admin/queue-health 显示增长的深度 |
Horizon 进程未运行或未订阅正确的连接。sudo systemctl status hukeyu-horizon → 检查它是 active (running);.env 中的 QUEUE_CONNECTION 应该是 redis。 |
| 实时收件箱不会实时更新 | Reverb 进程未运行或 WS 反向代理未连接。检查 REVERB_HOST + REVERB_PORT 是否与您的反向代理转发匹配;在浏览器控制台中,您应该看到成功的 wss://… 升级。 |
每个源上都显示 "Crawl failed: …" |
可能没有配置 LLM 提供商。设置 → 系统 → Cloudflare + 点击 Test LLM。源上的错误列对客户进行了清理;super_admins 在源详细信息页面上看到原始上游消息。 |
npm run build 期间 Failed to load PostCSS config |
您可能运行了 npm install --production。构建需要开发依赖 — 使用默认标志重新运行 npm ci。 |