deploy: 官网 ckb.quwanzhi.com 宝塔上线 DNS+SSL+验收文档

阿里云 A 记录指向存客宝宝塔,Nginx 443 泛域名证书,部署脚本补 SSL/DNS 步骤。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Manus AI
2026-05-31 19:15:04 +08:00
parent b5b40e8bf3
commit 3aa7ecf8c0
5 changed files with 288 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# 官网 · 进行中2026-05-31 · 仅剩余项)
> **已完成全文** → [已完成/官网_0531工程交付_20260531/官网_0531工程交付_20260531.md](./已完成/官网_0531工程交付_20260531/官网_0531工程交付_20260531.md)
> **待开发总表** → [20260531_待开发清单.md](./20260531_待开发清单.md)
> **代码目录**`官网/` · **专文**`开发文档/1、需求/官网/`
> **整体进度**:官网站 **100%** · 超管 SEO 中心 **0%** · 公网 DNS/SSL **✅ 已上线**
---
## 一、剩余需求表
| ID | 优先级 | 需求 | 状态 | 专文 |
|:---|:---:|:---|:---:|:---|
| REQ-WEB-61 | **P0** | 官网 AI 客服 生产联调 | 🟡 BFF+FAQ 全绿 · ckbapi 路由已部署 · **待 AI 模型/KB 配置** | [14](../官网/14-官网AI客服获客场景_20260531.md) |
| REQ-WEB-41 | P1 | SuperAdmin `/dashboard/seo-center` | ⬜ 跨端 · 需授权改 SuperAdmin 仓 | 12 |
| REQ-WEB-42 | P1 | SEO BFF `/v1/admin/seo/*` | ⬜ 跨端 · 需授权改存客宝 Server | 12 |
| REQ-WEB-10 | P2 | 公网 DNS + 宝塔 SSL | ✅ ckb.quwanzhi.com → 42.194.245.239 · HTTPS 泛域名证书 | 01 |
| REQ-WEB-23 | P2 | Screaming Frog 审计归档 | ⬜ 需人工跑 SF + 归档 MD | 09 |
---
## 二、本轮回合已完成2026-05-31 晚)
| ID | 验收 |
|:---|:---|
| REQ-WEB-07 | `ind-ecom.jpg/webp` 换为 `hero-growth-chart` 专属图MD5≠ind-store |
| REQ-WEB-52 | `device.html#device-poster` 双竖版海报样板 + `device-phone.css` |
| REQ-WEB-22 | 后台「生成 32 位 Key」+ 保存时自动写 `{key}.txt` · runtime ping 已有 |
| Hero CTA | `trial``pricing.html` → 自动弹留资窗 · smoke ✅ |
| deploy | `deploy_official_site.sh` 启动轮询 30s · smoke **ALL PASS** |
---
## 三、REQ-WEB-61 生产联调清单
| # | 项 | 状态 |
|:---:|:---|:---:|
| 1 | 宝塔 pm2 `ckb-official` 8090 运行 | ✅ |
| 2 | BFF `/api/official-ai/chat` 签名 parity | ✅ |
| 3 | 首页 AI 挂件 10s 弹出 | ✅ |
| 4 | FAQ 兜底upstream 失败时 keyword 回复) | ✅ |
| 5 | **生产 ckbapi 部署 `official-ai/chat` 路由** | ✅ 已 rsync |
| 6 | **计划 779 绑定 KB/内容库 ID** | ⬜ |
| 7 | **生产 AI 网关 Provider非 503** | 🟡 模型 endpoint 不可用 · FAQ 兜底可用 |
**存客宝侧** [REQ-CKB-66](./存客宝_进行中_20260531.md#四p0--req-ckb-66--对外-ai-客服生产联调)
---
## 四、验收命令
```bash
bash 开发文档/8、部署/scripts/deploy_official_site.sh --smoke
# 后台 http://127.0.0.1:8090/admin/ admin / key123456
```
**2026-05-31 smoke**ALL PASS含 Hero→价格页弹窗、device 海报区)
---
## 五、变更记录
| 日期 | 摘要 |
|:---|:---|
| 2026-05-31 | REQ-WEB-60/62/63/21/54/11 等已完成项迁入 `已完成/官网_0531工程交付` |
| 2026-05-31 | 本文仅保留 ⬜/🟡 剩余项 |
| 2026-05-31 晚 | ✅ WEB-07/52/22 · Hero trial 流程 · deploy 30s 就绪 · smoke ALL PASS |
| 2026-05-31 晚 | 剩余 5 项WEB-61 生产、WEB-41/42 超管、WEB-10 DNS、WEB-23 SF |

View File

@@ -0,0 +1,65 @@
# 官网 ckb.quwanzhi.com · 宝塔部署进度
> 更新时间2026-05-31
> 域名https://ckb.quwanzhi.com
> 服务器42.194.245.239:22022存客宝宝塔
> **整体进度100%**DNS + SSL + 全页 + API 验收通过)
---
## 部署架构
| 层 | 说明 |
|:---|:---|
| DNS | 阿里云 A 记录 `ckb.quwanzhi.com``42.194.245.239` |
| Nginx | `/www/server/panel/vhost/nginx/ckb.quwanzhi.com.conf` · 80/443 反代 |
| SSL | `*.quwanzhi.com` 泛域名证书(`/root/ssl_deploy_wildcard.sh` |
| 应用 | PM2 `ckb-official` · `scripts/site-unified-server.mjs` · `:8090` |
| 代码 | `/www/wwwroot/ckb.quwanzhi.com` |
---
## 一键部署
```bash
# 1. 部署官网 + Nginx + SSL + DNS
bash 开发文档/8、部署/scripts/deploy_official_baota.sh
# 2. 仅改 DNS阿里云 API
bash 开发文档/8、部署/scripts/aliyun_dns_ckb_official.sh
```
---
## 2026-05-31 验收结果
| 项 | 结果 |
|:---|:---:|
| HTTPS 首页 / pricing / sitemap / admin | 200 |
| POST `/api/track` | 200 |
| POST `/api/lead-submit`(带 sign+timestamp | 200 · 新增成功 |
| POST `/api/official-ai/chat` | 200 · FAQ 兜底(上游模型暂不可用) |
| POST `/admin/api/login` | 200 · token ok |
| 阿里云 DNS @223.5.5.5 | 42.194.245.239 |
| 服务器 curl https://ckb.quwanzhi.com | 200 |
---
## 生产 ckbapi 补丁(官网 AI/留资依赖)
本次同步到 `/www/wwwroot/ckbapi.quwanzhi.com`
- `application/cunkebao/controller/plan/OfficialAiChatController.php`
- `application/cunkebao/config/route.php`(含 `v1/api/official-ai`
- `application/common/service/PromptMergeService.php`
- `application/common/service/AiGatewayService.php`
**待办(非阻塞)**AI 网关模型 `doubao-seed-1-8-251215` 权限/配置;计划 779 绑定知识库。
---
## 相关脚本
- `开发文档/8、部署/scripts/deploy_official_baota.sh`
- `开发文档/8、部署/scripts/nginx_ckb_official.conf`
- `开发文档/8、部署/scripts/aliyun_dns_ckb_official.sh`

View File

@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# 阿里云 DNSckb.quwanzhi.com → 存客宝宝塔 42.194.245.239
set -euo pipefail
python3 - <<'PY'
import os, re, sys, json
RR = "ckb"
TARGET_IP = "42.194.245.239"
DOMAIN = "quwanzhi.com"
INDEX_MD = "/Users/karuo/Documents/个人/卡若AI/运营中枢/工作台/00_账号与API索引.md"
def get_creds():
id_val = os.environ.get("ALIYUN_ACCESS_KEY_ID")
secret_val = os.environ.get("ALIYUN_ACCESS_KEY_SECRET")
if id_val and secret_val:
return id_val, secret_val
if not os.path.isfile(INDEX_MD):
return None, None
text = open(INDEX_MD, encoding="utf-8").read()
in_ali = False
for line in text.splitlines():
if "### 阿里云" in line:
in_ali = True
continue
if in_ali and line.strip().startswith("###"):
break
if in_ali:
if "AccessKey ID" in line:
m = re.search(r"`([A-Za-z0-9]+)`", line)
if m: id_val = m.group(1)
if "Secret" in line and "key" not in line.lower():
m = re.search(r"`([A-Za-z0-9]+)`", line)
if m: secret_val = m.group(1)
return id_val, secret_val
key_id, key_secret = get_creds()
if not key_id:
print("未找到阿里云凭证"); sys.exit(1)
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
client = AcsClient(key_id, key_secret, "cn-hangzhou")
req_list = DescribeDomainRecordsRequest()
req_list.set_accept_format("json")
req_list.set_DomainName(DOMAIN)
req_list.set_RRKeyWord(RR)
resp = json.loads(client.do_action_with_exception(req_list))
records = resp.get("DomainRecords", {}).get("Record", [])
for r in records:
if (r.get("RR") or "").lower() == RR.lower():
rid = r.get("RecordId")
if r.get("Value") == TARGET_IP and r.get("Type") == "A":
print(f"解析已正确: {RR}.{DOMAIN} -> {TARGET_IP}")
sys.exit(0)
req_u = UpdateDomainRecordRequest()
req_u.set_accept_format("json")
req_u.set_RecordId(rid)
req_u.set_RR(RR)
req_u.set_Type("A")
req_u.set_Value(TARGET_IP)
client.do_action_with_exception(req_u)
print(f"已更新: {RR}.{DOMAIN} -> {TARGET_IP}")
sys.exit(0)
req = AddDomainRecordRequest()
req.set_accept_format("json")
req.set_DomainName(DOMAIN)
req.set_RR(RR)
req.set_Type("A")
req.set_Value(TARGET_IP)
client.do_action_with_exception(req)
print(f"已添加: {RR}.{DOMAIN} -> {TARGET_IP}")
PY

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# 存客宝官网 → 腾讯云存客宝宝塔42.194.245.239)部署
# 域名 ckb.quwanzhi.com · 静态 + /api + /admin 由 Node 统一服务(8090) 提供Nginx 反代
# 用法bash 开发文档/8、部署/scripts/deploy_official_baota.sh
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
SITE="$ROOT/官网"
HOST="root@42.194.245.239"
PORT_SSH=22022
SSH="ssh -p $PORT_SSH -o BatchMode=yes -o StrictHostKeyChecking=no"
DEST="/www/wwwroot/ckb.quwanzhi.com"
APP_PORT=8090
VHOST="/www/server/panel/vhost/nginx/ckb.quwanzhi.com.conf"
echo ">>> 1/5 创建目录"
$SSH "$HOST" "mkdir -p $DEST $DEST/data"
echo ">>> 2/5 rsync 官网静态+服务端(保留服务器 data避免覆盖线上 analytics"
rsync -avz --delete -e "ssh -p $PORT_SSH -o BatchMode=yes -o StrictHostKeyChecking=no" \
--exclude 'data/analytics.json' \
--exclude 'node_modules' \
--exclude '.DS_Store' \
"$SITE/" "$HOST:$DEST/"
echo ">>> 3/5 写 Nginx vhost"
scp -P $PORT_SSH -o BatchMode=yes -o StrictHostKeyChecking=no \
"$ROOT/开发文档/8、部署/scripts/nginx_ckb_official.conf" "$HOST:$VHOST"
echo ">>> 4/5 pm2 启动/重启 Node 统一服务 (port ${APP_PORT})"
$SSH "$HOST" "cd ${DEST} && pm2 delete ckb-official >/dev/null 2>&1 || true; SITE_PORT=${APP_PORT} pm2 start scripts/site-unified-server.mjs --name ckb-official --cwd ${DEST}; pm2 save"
echo ">>> 5/7 部署泛域名 SSL 证书"
$SSH "$HOST" "bash /root/ssl_deploy_wildcard.sh 2>/dev/null | grep -E 'ckb.quwanzhi|Done' || true"
echo ">>> 6/7 校验 Nginx 并重载"
$SSH "$HOST" "nginx -t && nginx -s reload && echo NGINX_RELOADED"
echo ">>> 7/7 阿里云 DNS 指向"
bash "$ROOT/开发文档/8、部署/scripts/aliyun_dns_ckb_official.sh" || echo "WARN: DNS 脚本未执行(缺凭证则手动确认 A 记录)"
echo ">>> 验收"
$SSH "$HOST" "sleep 2; echo -n '本地8090 首页 '; curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:$APP_PORT/index.html; echo -n 'HTTP 反代 '; curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: ckb.quwanzhi.com' http://127.0.0.1/index.html; echo -n 'HTTPS 反代 '; curl -s -o /dev/null -w '%{http_code}\n' -k -H 'Host: ckb.quwanzhi.com' https://127.0.0.1/index.html; echo -n 'track API '; curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' -H 'Host: ckb.quwanzhi.com' http://127.0.0.1/api/track -d '{\"visitorId\":\"v_deploy_check\",\"events\":[]}'"
echo ">>> 完成。官网 https://ckb.quwanzhi.com"

View File

@@ -0,0 +1,39 @@
server {
listen 80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen [::]:80;
server_name ckb.quwanzhi.com;
ssl_certificate /www/server/panel/vhost/cert/ckb.quwanzhi.com/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/ckb.quwanzhi.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn) {
return 404;
}
location ~ \.well-known {
allow all;
}
# 官网统一服务(静态 + /api/* + /admin/api/*)由 Node 提供,全部反代到 127.0.0.1:8090
location / {
proxy_pass http://127.0.0.1:8090;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 30s;
}
access_log /www/wwwlogs/ckb.quwanzhi.com.log;
error_log /www/wwwlogs/ckb.quwanzhi.com.error.log;
}