Files
kefu_cloud/deploy/README.md
T
2026-07-15 16:09:05 +08:00

215 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 生产部署(Docker / 腾讯云 CVM
单机 Docker Compose 方案:`Nginx + API + PostgreSQL + MinIO`,适合腾讯云轻量/ CVM。
## 架构
```
Internet ──:80/443──▶ 边缘网关(Caddy 推荐 / 或 CLB
web(nginx) :HTTP_PORT(默认 18080 → 容器 80
├── / 前端 SPA
├── /api/* → api:8080(含 WebSocket
├── /health → api
└── /files/* → minio:9000/kefu(图片公共读)
```
**两层分工(不要混为一谈):**
| 层级 | 组件 | 职责 |
|------|------|------|
| 边缘 | 宿主机 Caddy(或 CLB) | 占 80/443、多域名、自动 HTTPS |
| 应用内 | compose 里的 `web`Nginx | SPA + `/api` + `/files` 路径反代 |
若机器上已有 `caddy` 占用 80/443(例如旧站 `kefu_sys`),**不要**让本项目 `HTTP_PORT=80`,应改用 `18080` 并由 Caddy 反代。
## 服务器准备(腾讯云)
1. 购买 **CVM / 轻量应用服务器**(建议 2 核 4G 起,系统 Ubuntu 22.04
2. **安全组**放行:`22``80`(有证书再放 `443`)。应用内端口(如 `18080`**不必**对公网开放
3. 安装 Docker
```bash
# Ubuntu 示例
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# 重新登录后 docker 无需 sudo
docker compose version
```
4. **(强烈建议)Docker 镜像加速** —— 加速拉 `golang` / `node` / `nginx` / `postgres` 等基础镜像。
腾讯云 CVM 可写(其它云可换成对应镜像地址):
```bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker info | grep -A5 'Registry Mirrors'
```
说明:Dockerfile 内已默认使用 **腾讯云 Alpine 源、goproxy.cn、npmmirror**,加速构建阶段的 `apk` / `go mod` / `npm ci`
基础镜像本身仍依赖上面的 Docker Hub 镜像加速。
5. 上传代码到服务器,例如:
```bash
git clone <你的仓库地址> kefu_cloud
cd kefu_cloud
```
6. 部署前检查端口占用:
```bash
sudo ss -tlnp | grep -E ':80|:443|:18080'
docker ps --format 'table {{.Names}}\t{{.Ports}}'
```
## 一键部署
```bash
chmod +x deploy/scripts/*.sh
# 首次会生成 deploy/.env.prod 并提示你改域名/公网地址
./deploy/scripts/deploy.sh
# 需要演示账号时(kefu_admin / kefu_admin123 等)
./deploy/scripts/deploy.sh --seed
```
### 必改配置(`deploy/.env.prod`
| 变量 | 示例 | 说明 |
|------|------|------|
| `APP_BASE_URL` | `https://kefu.xx.com` | **浏览器**访问根地址(经 Caddy 时写 https 域名,不要写 `:18080` |
| `STORAGE_PUBLIC_BASE_URL` | `https://kefu.xx.com/files` | **必须**与应用内 Nginx `/files` 一致 |
| `HTTP_PORT` | `18080` | 宿主机映射端口;已有 Caddy 占 80 时用非 80 端口 |
| `DB_PASSWORD` / `JWT_SECRET` / `STORAGE_*` | 强随机 | 脚本可自动生成密钥 |
脚本会校验占位符是否改掉,并在 `HTTP_PORT` 已被占用时告警/退出。
### 常用命令
```bash
./deploy/scripts/deploy.sh --status # 状态
./deploy/scripts/deploy.sh --down # 停容器(保留卷)
./deploy/scripts/deploy.sh --seed-only # 仅跑种子
./deploy/scripts/backup-db.sh # 备份数据库到 ./backups
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f api
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f web
```
## 与现有 Caddy 共存(同机已有 kefu_sys 等)
典型现状:
```text
caddy 0.0.0.0:80→80, 0.0.0.0:443→443
kefu_sys 仅容器内 8080(由 Caddy 反代)
```
推荐拓扑:
```text
Internet
└── Caddy :80/:443
├── 旧域名 → kefu_sys
└── 新域名 → 127.0.0.1:18080 → kefu-cloud-web(Nginx)
```
### 步骤
1. `.env.prod` 设置(示例):
```bash
HTTP_PORT=18080
APP_BASE_URL=https://kefu.example.com
STORAGE_PUBLIC_BASE_URL=https://kefu.example.com/files
```
2. 部署本项目:`./deploy/scripts/deploy.sh`(先确认本机 `curl http://127.0.0.1:18080/healthz` 返回 ok
3.`deploy/caddy/Caddyfile.example` 中的站点段合并进现有 Caddy 配置,把域名改成真实域名后 reload:
```bash
# 示例(按你实际 Caddy 部署方式调整)
# docker exec caddy caddy validate --config /etc/caddy/Caddyfile
# docker exec caddy caddy reload --config /etc/caddy/Caddyfile
```
4. 浏览器访问 `https://kefu.example.com`,登录页 `/login`,健康检查 `/health`
### 为何边缘用 Caddy、应用内仍用 Nginx
- **Caddy**:你已在用、自动 HTTPS、多站点配置简单,继续当 80/443 入口。
- **Nginxweb 容器)**SPA、`/api` WebSocket、`/files`→MinIO 已写好,无需换成 Caddy。
- **不要**再在宿主机起一个 Nginx 抢 80/443,也**不要**让本 compose 默认绑 80。
## HTTPS 其它方式
任选其一(与上一节「Caddy 共存」二选一即可):
1. **CLB / CDN** 终结 HTTPS,回源 CVM `HTTP_PORT`(或仍回源 Caddy
2. 本机 **Caddy** 反代到 `127.0.0.1:${HTTP_PORT}`(推荐,见上)
3. 独占机器时 `HTTP_PORT=80`,另用 Nginx + Lets Encrypt 做 443
配置 HTTPS 后,请同步把 `APP_BASE_URL``STORAGE_PUBLIC_BASE_URL` 改成 `https://…`
## 使用腾讯云 COS 替代 MinIO(可选)
1. 创建 COS 桶,开启公共读或使用 CDN 域名
2.`.env.prod` 配置 S3 兼容参数(见 `.env.prod.example` 注释)
3.`docker-compose.prod.yml` 中去掉 `minio` / `minio-init` 依赖,并修改 Nginx,去掉 `/files` 反代(图片直链 COS
当前一键脚本默认 **内置 MinIO**,零额外云产品即可跑通。
## 默认种子账号(仅 --seed 后)
| 角色 | 用户名 | 密码 |
|------|--------|------|
| 平台管理员 | `platform_admin` | `kefu_admin123` |
| 租户管理员 | `kefu_admin` | `kefu_admin123` |
| 坐席 | `agent1` 等 | `kefu_admin123` |
**上线后立即修改密码或关闭 seed 账号。**
## 目录说明
| 路径 | 说明 |
|------|------|
| `docker-compose.prod.yml` | 生产编排 |
| `deploy/docker/Dockerfile.api` | Go API 镜像 |
| `deploy/docker/Dockerfile.web` | 前端构建 + Nginx |
| `deploy/docker/nginx.conf` | 反代与 SPA |
| `deploy/caddy/Caddyfile.example` | 边缘 Caddy 站点示例(与 80 共存) |
| `deploy/.env.prod.example` | 环境变量模板 |
| `deploy/scripts/deploy.sh` | 一键部署 |
| `deploy/scripts/backup-db.sh` | 数据库备份 |
## 故障排查
| 现象 | 处理 |
|------|------|
| 端口被占用 / bind 失败 | `ss -tlnp` 查占用;改 `HTTP_PORT` 或停冲突容器 |
| 页面 502 | `docker compose … logs api`,检查 DB 是否 healthyCaddy 是否指到正确端口 |
| 图片打不开 | 检查 `STORAGE_PUBLIC_BASE_URL` 是否为 `…/files`MinIO 桶是否 public download |
| WebSocket 断 | 确认走同源 `/api/ws`Caddy 用示例中的 `flush_interval`CLB 需开启 WebSocket |
| 构建 Go 失败 | 服务器内存不足时加 swap,或本机 build 后 `docker save` 上传 |
| 只能本机 18080 访问、域名不通 | Caddy 未 reload / 域名 DNS 未指向本机 / 安全组未放 80/443 |
## 升级
```bash
git pull
./deploy/scripts/backup-db.sh # 升级前建议备份
./deploy/scripts/deploy.sh # 重新 build 并滚动启动
```