Files
crmchat/部署文档.md
T

259 lines
9.5 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.
# CRMChat 客服系统 — Docker 部署文档
## 环境要求
- Docker 24+
- Docker Compose v2+
- 端口 18091(可自定义)
## 快速开始
### 国内网络(默认,镜像加速)
```bash
# 1. 复制环境变量
cp .env.docker .env
# 2. 一键启动
docker compose -f docker-compose.yml -f docker-compose.cn.yml up -d
```
### 海外网络
```bash
cp .env.docker .env
docker compose up -d
```
## 主服务器部署与更新(8.133.254.174)
生产环境部署在主服务器阿里云,IP 直连 18091 端口(无域名、无证书,勿再使用已废弃的 kefu.wildcs2.com)。
### 服务器访问
```bash
ssh -i "C:/data/密钥/祝总阿里云.pem" root@8.133.254.174
```
- 部署目录:`/www/projects/crmchat`(gitea clone,master 分支)
- 访问地址:`http://8.133.254.174:18091`(阿里云安全组已放行 18091/TCP)
- 代码推送:`git push origin master`(偶发认证失败,重试一次即可)
### 更新部署标准流程(顺序不可颠倒)
```bash
# 本地:提交并推送
git push origin master
# 服务器:拉取 → 重建 php 镜像 → 重建容器 → 重启 nginx → 健康检查
cd /www/projects/crmchat
git pull
docker compose build php
docker compose up -d php
docker restart crmchat-nginx
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:18091/chat/index # 预期 200
```
每一步都有原因,跳过或换序会出事故:
| 步骤 | 为什么 |
|------|--------|
| `docker compose build php` 必须在任何重启之前 | 旧镜像的 entrypoint 没有空库守卫,**对旧镜像容器执行 restart 会无条件重导初始化 SQL,清空整个数据库**(2026-09-25 已踩:清掉了用户会话数据)。新镜像的 entrypoint 检测到库已初始化(`eb_system_admin` 哨兵表存在)会跳过导入 |
| `up -d php` 而非 `restart php` | 新 entrypoint 在新镜像里,restart 不换镜像;up -d 重建容器才会用新镜像 |
| `docker restart crmchat-nginx` 收尾 | ① php 容器重建后 IP 变化,nginx 缓存旧 IP → 502;② `nginx.conf` 是单文件 bind mount,git pull 替换文件后容器仍指向旧 inode,`nginx -s reload` 读到的还是旧配置,必须 restart 容器重新挂载 |
### 已固化的构建/配置修改(勿回退)
- `docker/php/Dockerfile`:apt 源切阿里云镜像。原因:`php:7.4-cli` 基于 Debian bullseye,LTS 已于 2026-08-31 结束,deb.debian.org 从 ECS 访问超时、各镜像站陆续清理 bullseye 包(404);security 源在镜像站/archive 迁移空窗期同样 404,暂去掉(基础镜像本身是 2022 快照,无实际回退;中期应升级基础镜像到受支持的 Debian/PHP 版本)
- `nginx/nginx.conf`:`absolute_redirect off`。原因:容器内 nginx 监听 80、对外映射 18091,nginx 发绝对 Location 重定向时用的是容器内端口(80),外部端口 18091 会丢失
- `entrypoint.sh`:空库守卫 + `eb_system_admin` 哨兵表检查(见上)
### 忘记密码重置方法
```bash
# 在服务器上执行(以 admin 为例,kefu 同理换表名字段)
cd /www/projects/crmchat
MYSQLPASS=$(grep '^MYSQL_ROOT_PASSWORD=' .env | cut -d= -f2)
NEWPASS=$(openssl rand -hex 8); echo "新密码: $NEWPASS"
HASH=$(docker exec crmchat-php php -r "echo password_hash(\$argv[1], PASSWORD_DEFAULT);" "$NEWPASS")
docker exec crmchat-mysql mysql -uroot -p"$MYSQLPASS" crmeb_chat \
-e "UPDATE eb_system_admin SET pwd='$HASH' WHERE account='admin';"
# kefu 坐席:UPDATE eb_chat_service SET password='$HASH' WHERE account='kefu';
```
## 访问地址
> 本地开发默认 admin123 / kefu123;**主服务器(8.133.254.174:18091)的 admin / kefu 密码已于 2026-09-25 重置为随机值**(不再使用默认密码),重置方法见「主服务器部署与更新」。
| 入口 | 地址 | 账号 | 密码 |
|------|------|------|------|
| 后台管理 | `http://localhost:18091/admin` | admin | admin123 |
| 客服坐席 | `http://localhost:18091/kefu` | kefu | kefu123 |
| 用户端 | `http://localhost:18091/chat/index?token=82b739d20bd2d29dc67f112b7f193683` | — | — |
| Demo 页 | `http://localhost:18091/demo` | — | — |
## 容器架构
```
┌──────────┐ ┌──────────────┐ ┌───────────┐ ┌────────┐
│ Nginx │────▶│ PHP 7.4 + │────▶│ MySQL 5.7│ │ Redis │
│ :18091 │ │ Swoole 4 │ │ :3306 │ │ :6379 │
└──────────┘ └──────────────┘ └───────────┘ └────────┘
│ │
▼ ▼
静态文件 ThinkPHP 6 路由
admin/ /api/* /kefu /install
demo/ WebSocket /ws
```
| 容器 | 镜像 | 说明 |
|------|------|------|
| crmchat-nginx | nginx:alpine | 反向代理 + 静态文件 |
| crmchat-php | 自构建 (PHP 7.4 + Swoole 4.8 + Redis) | ThinkPHP 6 应用 |
| crmchat-mysql | mysql:5.7 | 数据库,数据持久化 |
| crmchat-redis | redis:alpine | 缓存/Session/WebSocket 状态 |
## 环境变量 (.env)
```bash
# 数据库
DB_HOSTNAME=mysql
DB_DATABASE=crmeb_chat
DB_USERNAME=root
DB_PASSWORD=root # 生产环境务必修改
DB_PORT=3306
# Redis
REDIS_HOSTNAME=redis
REDIS_PORT=6379
REDIS_PASSWORD=
# Nginx 端口
NGINX_PORT=18091
# MySQL root 密码
MYSQL_ROOT_PASSWORD=root # 生产环境务必修改
```
## 目录结构
```
kefu/
├── docker/
│ └── php/
│ ├── Dockerfile # PHP 7.4 + Swoole4 镜像
│ ├── entrypoint.sh # 启动脚本(自动生成 .env、导入数据库、启动 Swoole)
│ └── swoole.php # Swoole 配置
├── nginx/
│ └── nginx.conf # Nginx 配置
├── crmchat/ # ThinkPHP 6 后端源码
│ └── public/
│ ├── admin/ # 管理后台前端(构建产物)
│ ├── demo/ # 用户端 Demo 页
│ └── install/
│ ├── crmeb_clean.sql # 数据库初始化 SQL(29 张表,含初始数据)
│ └── install.lock # 自动生成,跳过安装向导
├── docker-compose.yml # 海外版 Docker Compose
├── docker-compose.cn.yml # 国内镜像加速版(覆盖镜像源)
├── .env.docker # 环境变量模板
└── .env # 实际环境变量(gitignore)
```
## 常用命令
```bash
# 启动
docker compose -f docker-compose.yml -f docker-compose.cn.yml up -d
# 停止
docker compose down
# 停止并清除数据(完全重置)
docker compose down -v
# 重启
docker compose restart
# 查看日志
docker compose logs -f php
# 进入容器
docker exec -it crmchat-php bash
```
## 数据库说明
初始化 SQL 文件 `crmchat/public/install/crmeb_clean.sql` 包含:
- 29 张 `eb_` 前缀表
- 完整初始数据:管理员、客服、角色权限、系统菜单、系统配置、应用 Token
- 启动时 `entrypoint.sh` 自动导入,首次启动即用,无需安装向导
APP_KEY 已固定,Token `82b739d20bd2d29dc67f112b7f193683` 重启不变。
## 注意事项
1. **客服需要打开 WebSocket** — 仅仅登录 API 不够,需要浏览器访问 `/kefu` 进入聊天面板建立 WebSocket 连接才能接收用户消息
2. **生产环境务必修改** `.env` 中的数据库密码和 MySQL root 密码
3. **APP_KEY 已固定** — 如需更换,修改 `entrypoint.sh` 中 `APP_KEY` 的值,并重新执行 `docker compose down -v && docker compose up -d`
## 模块打包部署
三个模块的分工与部署方式:
| 模块 | 功能 | Docker 部署方式 |
|------|------|-----------------|
| `admin/` | Web 前端(管理后台 + 客服面板 + 用户端) | 构建后复制到 `crmchat/public/admin/`,Nginx 静态 serve |
| `crmchat/` | PHP 后端(API + WebSocket) | Volume 挂载到容器,Swoole 运行 |
| `uniapp/` | 移动端客服 App | 不在 Docker 范围内,需单独打包 |
### admin/ — 管理后台前端
**构建产物已内置在 `crmchat/public/admin/` 中,直接可用,无需额外构建步骤。**
只有在修改了 `admin/src/` 下的源码后,才需要重新构建并提交:
```bash
cd admin
npm install # 首次或依赖变更后
npm run build # 构建 → dist/
# Windows
Remove-Item -Path "..\crmchat\public\admin\*" -Recurse -Force
Copy-Item -Path "dist\*" -Destination "..\crmchat\public\admin\" -Recurse
# Linux / Mac
rm -rf ../crmchat/public/admin/*
cp -r dist/* ../crmchat/public/admin/
# 确认提交
git add ../crmchat/public/admin/ && git commit -m "更新 admin 前端构建产物"
```
构建产物提交后,新环境 clone 即可直接用 Docker 部署,无需安装 Node.js。
### crmchat/ — PHP 后端
代码通过 volume 挂载到容器(`./crmchat:/var/www/html`),修改 `.php` 文件后需重启 PHP 容器才能生效:
```bash
docker compose restart php
```
### uniapp/ — 移动端客服 App
不在 Docker 部署范围内。使用 **HBuilderX** 打开 `uniapp/` 目录,即可编译打包为:
- Android APK
- iOS IPA
- 微信小程序 / 支付宝小程序 / 百度小程序 / 头条小程序
- H5 网页
打包前需在 `uniapp/pages/config/app.js` 中配置后端 API 域名和 WebSocket 地址:
```javascript
defaultDomainName: '你的后端域名', // 如 chat.example.com
defaultRequestType: 'https', // http 或 https
defaultWsType: 'wss', // ws 或 wss
```