Files
kefu_cloud/deploy
yml2213 ff90d742ad 新增 mac 本地一键开发启动脚本
提供 deploy/scripts/dev-local.sh,统一拉起 Postgres/MinIO、API 与前端;Makefile 的 dev 相关目标改为调用该脚本。
2026-07-17 21:39:26 +08:00
..
2026-07-15 16:09:05 +08:00

生产部署(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 里的 webNginx SPA + /api + /files 路径反代

若机器上已有 caddy 占用 80/443(例如旧站 kefu_sys),不要让本项目 HTTP_PORT=80,应改用 18080 并由 Caddy 反代。

服务器准备(腾讯云)

  1. 购买 CVM / 轻量应用服务器(建议 2 核 4G 起,系统 Ubuntu 22.04
  2. 安全组放行:2280(有证书再放 443)。应用内端口(如 18080不必对公网开放
  3. 安装 Docker
# Ubuntu 示例
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# 重新登录后 docker 无需 sudo
docker compose version
  1. (强烈建议)Docker 镜像加速 —— 加速拉 golang / node / nginx / postgres 等基础镜像。
    腾讯云 CVM 可写(其它云可换成对应镜像地址):
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 镜像加速。

  1. 上传代码到服务器,例如:
git clone <你的仓库地址> kefu_cloud
cd kefu_cloud
  1. 部署前检查端口占用:
sudo ss -tlnp | grep -E ':80|:443|:18080'
docker ps --format 'table {{.Names}}\t{{.Ports}}'

一键部署

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 已被占用时告警/退出。

常用命令

./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 等)

典型现状:

caddy        0.0.0.0:80→80, 0.0.0.0:443→443
kefu_sys     仅容器内 8080(由 Caddy 反代)

推荐拓扑:

Internet
   └── Caddy :80/:443
         ├── 旧域名  →  kefu_sys
         └── 新域名  →  127.0.0.1:18080  →  kefu-cloud-web(Nginx)

步骤

  1. .env.prod 设置(示例):
HTTP_PORT=18080
APP_BASE_URL=https://kefu.example.com
STORAGE_PUBLIC_BASE_URL=https://kefu.example.com/files
  1. 部署本项目:./deploy/scripts/deploy.sh(先确认本机 curl http://127.0.0.1:18080/healthz 返回 ok

  2. deploy/caddy/Caddyfile.example 中的站点段合并进现有 Caddy 配置,把域名改成真实域名后 reload:

# 示例(按你实际 Caddy 部署方式调整)
# docker exec caddy caddy validate --config /etc/caddy/Caddyfile
# docker exec caddy caddy reload --config /etc/caddy/Caddyfile
  1. 浏览器访问 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_URLSTORAGE_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 是否 healthy;Caddy 是否指到正确端口
图片打不开 检查 STORAGE_PUBLIC_BASE_URL 是否为 …/filesMinIO 桶是否 public download
WebSocket 断 确认走同源 /api/wsCaddy 用示例中的 flush_intervalCLB 需开启 WebSocket
构建 Go 失败 服务器内存不足时加 swap,或本机 build 后 docker save 上传
只能本机 18080 访问、域名不通 Caddy 未 reload / 域名 DNS 未指向本机 / 安全组未放 80/443

升级

git pull
./deploy/scripts/backup-db.sh       # 升级前建议备份
./deploy/scripts/deploy.sh          # 重新 build 并滚动启动