259 lines
9.5 KiB
Markdown
259 lines
9.5 KiB
Markdown
# 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
|
||
```
|