支持PC端/H5/小程序 多端部署,支持 Docker / Windows / Linux 多平台部署
部署包包含:程序 JAR 文件、Docker 构建文件、多平台启动脚本、部署文档。运行前需安装 JDK 17+(Docker 方式除外)。
推荐使用 Adoptium Temurin 发行版:https://adoptium.net/
解压即用:无需手动创建 .env,运行启动脚本即会自动拉起内置 MySQL / Redis 容器与应用容器。
| 组件 | 版本 | 说明 |
|---|---|---|
| Docker | Docker Desktop 4.22+ / Docker Engine + Compose v2.20+ | 内置 MySQL/Redis 容器依赖 compose profiles 与 depends_on.required 特性(旧版 Compose 会报 unknown field 错误) |
| 内存 | 2G+ | 三容器(MySQL/Redis/应用) |
应用内嵌前端页面与 Tomcat,只需暴露 8080 端口即可访问。
数据库 / Redis 默认由本包自建:解压即用,会创建 crm-mysql / crm-redis(宿主端口 3306 / 6379,与容器内一一对应;端口被占用时自动避让到空闲端口),使用独立数据卷,与宿主机上已有的 MySQL/Redis 互不影响。若确想让 CRM 复用宿主机现有实例,在 .env 设 USE_EXTERNAL_DB=1 / USE_EXTERNAL_REDIS=1 即可(见 3.2)。
crm-system-<版本>-docker/
├── crm-system.jar # 后端可执行包(内嵌前端页面、默认配置与建表 SQL)
├── application.yml # 可编辑配置(compose 已挂载到容器, 修改后 restart app 生效)
├── init.sql # 建库建表 SQL(自动建表已内置, 供手动初始化/审计)
├── demo-data.sql # 可选: 演示业务数据(每个功能 15 条, 建表完成后按需导入)
├── Dockerfile # 应用镜像
├── docker-compose.yml # 唯一编排文件(应用 + 内置 MySQL/Redis, 后者由 bundled profile 控制)
├── start.sh # 预检 + 依赖解析 + 启动包装(Linux/macOS)
├── start.bat # 预检 + 依赖解析 + 启动包装(Windows)
├── resolve-deps.ps1 # Windows 端依赖解析脚本(由 start.bat 调用)
├── .env.example # 授权主密钥、依赖来源等变量模板
└── VERSION
解压后无需创建 .env,直接运行启动脚本(./start.sh 或双击 start.bat)即可。
首次启动脚本会为本次部署自动生成一套独立随机授权主密钥与配套密文,无需手动配置;仅在宿主机无 JDK 且无法拉取临时 JDK 镜像时才会回退为内置演示主密钥并给出提示。
start.sh / start.bat 在启动前解析数据库 / Redis 的来源,默认自建,既不读取也不改动宿主机上已有的实例:
| 情况 | 行为 |
|---|---|
默认(USE_EXTERNAL_DB / USE_EXTERNAL_REDIS 未配置、no、auto) | 新建:拉取 mysql:8.0 / redis:6.0 镜像并创建 crm-mysql / crm-redis 容器,宿主端口 3306 / 6379(被占用时自动避让)。使用独立数据卷,宿主机已有 MySQL、Redis 的数据不受任何影响 |
已存在本项目创建的 crm-mysql / crm-redis 容器 | 继续沿用(包含处于停止状态的,会随 compose 一起启动),数据卷保留 |
明确设置 USE_EXTERNAL_DB=1 / USE_EXTERNAL_REDIS=1 | 复用宿主机现有实例(探测 3306、6379,询问账号密码并校验连通性),不创建对应容器;探测不到则回退为新建 |
填写了 EXTERNAL_DB_HOST + EXTERNAL_DB_PORT | 直连该外部实例(如云数据库),优先级最高,不做本地探测 |
MySQL 与 Redis 各自独立判断(例如 MySQL 新建、Redis 复用宿主机,组合是允许的)。内置容器的宿主端口被占用会自动避让:若 3306 / 6379 已被本机其他程序占用,脚本会自动改用第一个空闲端口(3307、6380…)并写回 .env 的 MYSQL_HOST_PORT / REDIS_HOST_PORT。
手动干预方式(在 .env 中设置):
| 变量 | 说明 |
|---|---|
USE_EXTERNAL_DB / USE_EXTERNAL_REDIS | no/0/bundled(默认,兼容取值 auto)= 新建内置容器/1/true/yes = 复用宿主机现有实例(探测不到则回退新建) |
MYSQL_HOST_PORT / REDIS_HOST_PORT | 内置容器对外暴露的宿主机端口,默认 3306 / 6379(被占用时自动避让) |
MYSQL_DETECT_PORTS / REDIS_DETECT_PORTS | 复用宿主机实例时的探测端口列表,默认 3306 / 6379 |
EXTERNAL_DB_USER / EXTERNAL_DB_PASSWORD / EXTERNAL_DB_NAME | 复用宿主机 MySQL 时的账号信息(预填可避免每次询问) |
EXTERNAL_REDIS_PASSWORD | 宿主机 Redis 的密码 |
EXTERNAL_DB_HOST / EXTERNAL_DB_PORT(Redis 同理) | 直连非本机的远程实例(如云数据库),填写后不做本地探测 |
复用宿主机实例时,容器内通过 host.docker.internal 访问宿主机网络,请确认宿主机 MySQL / Redis 监听的不是回环地址(MySQL 设 bind-address = 0.0.0.0,Redis 注释 bind 并设置 protected-mode no)。
只查看当前依赖解析结果、不启动容器:
./start.sh deps
推荐用 start.sh(会先做依赖探测、检查 Docker daemon 是否已运行、端口是否被占用,避免直接报难以理解的连接错误):
chmod +x start.sh
./start.sh # 等价于: docker compose up -d --build
./start.sh down # 等价于: docker compose down
./start.sh logs -f app # 其余参数原样透传给 docker compose
Windows 双击 start.bat 即可(同样先预检)。启动成功后,脚本会等待应用就绪(首次启动含建库建表,约 1~2 分钟)并打印运行状态面板,例如:
crm-app app Up 0.0.0.0:8080->8080/tcp
crm-mysql mysql Up (healthy) 0.0.0.0:3307->3306/tcp
crm-redis redis Up (healthy) 0.0.0.0:6380->6379/tcp
访问地址 : http://localhost:8080 默认账号 : admin / 123456
也可直接使用原生命令 docker compose up -d --build。首次启动会自动:构建应用镜像、拉取 MySQL/Redis 镜像并创建 crm-mysql / crm-redis(仅显式复用宿主机实例时跳过),应用首次启动自动建库建表(无需手动导入 SQL)。等待约 1~2 分钟即可访问 http://<服务器IP>:8080。
docker compose ps # 查看状态
docker compose logs -f app # 查看应用日志
docker compose restart app # 重启应用(修改配置后)
docker compose down # 停止并删除容器(数据卷保留)
docker compose down -v # 停止并删除容器+数据卷(慎用, 会清空数据)
默认内置:MySQL 账号 root / 密码 root,Redis 无密码。若显式改为复用宿主机现有实例,数据库账号密码改 .env 中的 DB_USERNAME / DB_PASSWORD(Redis 为 REDIS_PASSWORD),再 docker compose restart app 生效。
宿主端口映射(默认与容器内一致,使用标准端口,便于本地客户端直连调试;被本机常驻 MySQL/Redis 等其他程序占用时脚本会自动避让;容器内应用通信始终走 3306/6379,不受影响):
| 服务 | 宿主端口 | 容器内端口 | 被占用时 |
|---|---|---|---|
| Web | WEB_PORT(默认 8080) | 8080 | 自动改用空闲端口 |
| MySQL | MYSQL_HOST_PORT(默认 3306) | 3306 | 自动改用空闲端口 |
| Redis | REDIS_HOST_PORT(默认 6379) | 6379 | 自动改用空闲端口 |
端口冲突不用手工改文件:8080 被本机其他程序占用时,start.sh / start.bat 会自动改用第一个空闲端口(8081、8082…)并写回 .env 的 WEB_PORT,启动日志里会打印实际访问地址:
[警告] 宿主端口 8080 已被占用: java (PID 91637)
[提示] 已自动改用宿主端口 8081, 访问地址 http://localhost:8081
想固定用某个端口,在 .env 设置 WEB_PORT=9090 即可(需自行确保该端口空闲)。内置 MySQL / Redis 的宿主端口同理,被占用时会自动避让并写回 .env。
修改配置有两种方式(优先级:环境变量 > application.yml):
方式一:编辑包根 application.yml(已挂载到容器 /app/application.yml)
修改后生效:
docker compose restart app
方式二:修改 docker-compose.yml 环境变量
如修改 MySQL 密码:改 mysql 服务的 MYSQL_ROOT_PASSWORD 并同步改 app 服务的 DB_PASSWORD,重建生效:
docker compose up -d --build
init.sql 为完整建表脚本,应用首次启动会自动建库建表,无需手动导入;此文件供手工初始化其他环境或审计表结构使用。
可选测试数据:新部署默认不含业务数据。如需预置演示客户/线索/合同等测试数据,首次启动建表完成后执行(建议空库/演示环境):
docker compose exec -T mysql mysql -uroot -proot crm_db --default-character-set=utf8mb4 < demo-data.sql
脚本内置幂等防重,可重复执行不会翻倍;若历史库演示数据已膨胀,用 fix-dup-data.sql 清理。
上述命令仅适用于内置 crm-mysql 容器;若已复用宿主机现有 MySQL,改用宿主机自身的客户端导入即可,例如:
mysql -h127.0.0.1 -P3306 -uroot -p crm_db --default-character-set=utf8mb4 < demo-data.sql
关于授权主密钥:本 docker 包使用演示主密钥加密(开箱即用)。请勿随意修改 CRM_LICENSE_MASTER_KEY——如需自定义密钥,请使用 Linux/Windows 原生包的 ./start.sh configure 基于新主密钥重新生成配套密文,再连同密文一并填写;否则应用会因密文不匹配而启动失败(报错:授权主密钥与配套密文不匹配 / Tag mismatch)。
admin 登录 → 系统管理 → 授权管理(查看/生成 License)| 账号 | 密码 | 角色 |
|---|---|---|
admin | 123456 | 超级管理员 |
sales01 | 123456 | 销售经理 |
sales02 | 123456 | 销售员 |
market01 | 123456 | 市场管理员 |
登录页默认展示上述内置账号提示(点击标签即可填充账号密码,本部署包默认开启);如需隐藏,登录后进入 系统管理 → 系统设置 → 功能开关,关闭「登录页默认账号提示」即可。
生产环境请登录后立即修改默认密码。
| 问题 | 处理 |
|---|---|
Cannot connect to the Docker daemon ... Is the docker daemon running? | Docker Desktop 未启动:open -a Docker,等状态变 Running 后重试(推荐改用 ./start.sh,会自动提示并等待就绪) |
ports are not available: exposing port TCP 0.0.0.0:8080 ... bind: address already in use | 宿主 8080(或 .env 里 WEB_PORT 指定的端口)被占用:重新执行 start.sh 会自动改用空闲端口并写回 WEB_PORT;也可手动设置 WEB_PORT=8081(或先把占用 8080 的程序关掉) |
| 内置 MySQL/Redis 端口 3306/6379 被占用 | 无需手工处理:重跑 start.sh / start.bat 会自动避让到空闲端口(3307/6380…)并写回 .env;也可在 .env 中直接指定端口 |
报 address already in use 但 lsof -iTCP:3306 看不到占用者 | macOS 上非 root 的 lsof 检测不到以 _mysql 用户运行的 mysqld;本包已改用 TCP 连接探测兜底,重跑 start.sh 即可正确避让;确认可用 sudo lsof -nP -iTCP:3306 -sTCP:LISTEN |
docker: 'compose' is not a docker command | 未装 Compose v2 插件:升级 Docker Desktop 20.10+ 或安装 compose 插件 |
Mac 上 exec ./bin/sh: exec format error | Pull 时架构不匹配:确认 Docker Desktop 使用与您机型一致的镜像架构(Apple 芯片 arm64 / Intel amd64) |
应用反复重启,日志 Access denied for user 'root' | ① 显式设置了 USE_EXTERNAL_DB=1 / USE_EXTERNAL_REDIS=1 但账号密码与宿主机实例不匹配:改为 no(默认自建)或在 .env 填对 EXTERNAL_DB_USER / EXTERNAL_DB_PASSWORD 后重跑 ./start.sh;② 内置 MySQL 首次初始化未完成即被 app 连接:执行 docker compose restart app |
升级旧版本后启动失败,日志 Data truncation: Truncated incorrect DOUBLE value | 该数据卷是旧版本(bigint 主键)初始化的库,2.6.3 已统一为 UUID(varchar(36))主键,新旧 schema 无法自动升级。备份后重建数据卷:docker compose down → docker volume rm <项目名>_crm-mysql-data → 重新 ./start.sh |
修改了 application.yml 不生效 | 该文件已挂载进容器,需 docker compose restart app(挂载路径:/app/application.yml) |
| 想让多个 CRM 实例共用一套 MySQL/Redis | 设置 USE_EXTERNAL_DB=1 / USE_EXTERNAL_REDIS=1;请先启动宿主机实例再部署,否则探测不到会回退为新建内置容器 |
| 复用宿主机 MySQL 后提示"账号或密码不正确" | 修改 .env 的 EXTERNAL_DB_USER / EXTERNAL_DB_PASSWORD 后 docker compose restart app;或设 USE_EXTERNAL_DB=no(默认)改用内置容器 |
复用宿主机 Redis 后日志报 NOAUTH / 连不上 | 宿主机 Redis 设了密码:在 .env 填写 EXTERNAL_REDIS_PASSWORD 后 docker compose restart app |
| 容器内连不上宿主机 MySQL/Redis | 宿主机实例只监听了 127.0.0.1:MySQL 改 bind-address = 0.0.0.0,Redis 注释 bind 并设置 protected-mode no;Linux 主机请用 Docker 20.10+ 以支持 host-gateway |
docker compose up -d --build 报 unable to get image ... Cannot connect to the Docker daemon at unix:///Users/<用户>/.docker/run/docker.sock.open -a Docker,等待菜单栏鲸鱼图标不再显示 Starting(约 20~40 秒);② docker info 能输出版本即就绪,Linux 服务器用 sudo systemctl start docker;③ 仍失败:Docker Desktop → Settings → Advanced → 勾选 Allow the default Docker socket to be used,Apply & Restart;④ 之后建议统一使用 ./start.sh(含以上检测与提示)。