Publish the current verified project state without local development history or personal-path artifacts.
14 KiB
编译与部署
EasyNextAdmin 建议维护三套企业内部交付主线:裸机/VM 传统部署、单机 Docker Compose 部署、K8s 云原生部署。Docker Swarm 只作为已有 Swarm 团队的兼容说明,不作为主推交付路线。当前仓库的 docker-compose.yml 只用于本地 MySQL、Redis 依赖,不作为生产编排方案。
交付形态选择
| 形态 | 适合团队 | 推荐方式 |
|---|---|---|
| 裸机/VM 传统包 | 没有 Docker/K8s 平台,只有 Linux 服务器、Nginx、MySQL、Redis | 后端 JAR + systemd,前端 dist + Nginx,配置用环境变量或外部配置文件 |
| 单机 Docker Compose 包 | 有 Docker,但没有集群编排;适合小企业、演示和私有化单机交付 | 后端镜像 + 前端镜像 + Compose 文件,生产依赖优先使用外部 MySQL/Redis |
| Docker Swarm 兼容说明 | 客户已有 Swarm 集群和运维经验,但暂不上 K8s | 复用 Compose 镜像和配置,补 docker stack、Secret、滚动更新和回滚说明 |
| K8s 云原生包 | 已有镜像仓库、Kubernetes、Ingress、Secret/ConfigMap 和运维平台 | 后端镜像 + 前端镜像,K8s Deployment/Service/Ingress,配置和密钥由平台注入 |
所有生产形态都使用 prod profile,都要求外部 MySQL 和可选 Redis;区别在于进程托管、发布回滚、配置密钥和流量摘除方式。裸机/VM、Compose、K8s 是三套主线,Swarm 只做兼容路线。
后端构建
在仓库根目录执行:
mvn -pl easy-next-admin-server -am -DskipTests package
产物:
easy-next-admin-server/target/easyNextAdmin.jar
如需运行测试:
mvn -pl easy-next-admin-server -am verify
后端 JAR 部署
环境 Profile
配置文件按职责拆分:
application.yaml:公共基线,放所有环境共享的默认行为。application-local.yaml:本地开发,保留 Swagger UI、演示账号、前端开发 CORS、较小线程池和便捷数据库/Redis 默认值。application-prod.yaml:生产部署,内网和公网都从这里起步,数据库、Redis、线程池、Tomcat、CORS 和安全响应头通过环境变量或启动参数覆盖。
local 默认 MySQL URL 带 createDatabaseIfNotExist=true,只用于本机 root 演示账号在空环境下自动创建数据库。prod 不提供该参数:生产数据库应由 DBA 或基础设施流程预建,应用账号只拥有目标 schema 内运行和迁移所需权限,不应拥有全局 CREATE DATABASE 权限。
生产部署使用 prod profile。prod 不提供数据库默认值,必须显式传入 MYSQL_URL、MYSQL_USERNAME 和 MYSQL_PASSWORD;Redis 默认指向 redis://redis:6379,真实部署建议显式传入 EASY_REDIS_ADDRESS 和 EASY_REDIS_PASSWORD。prod 默认开启 HSTS、收紧 Actuator 暴露范围和关闭 CORS 白名单。前后端同域网关反代时不需要 CORS;前后端分离域名部署时显式配置真实域名:
MYSQL_URL="jdbc:mysql://mysql:3306/easy-next-admin?serverTimezone=GMT%2B8&characterEncoding=UTF-8&connectionCollation=utf8mb4_unicode_ci&useSSL=true" \
MYSQL_USERNAME=easy_admin \
MYSQL_PASSWORD="替换为生产数据库密码" \
java -jar easy-next-admin-server/target/easyNextAdmin.jar \
--spring.profiles.active=prod \
--easy.spring.redis.address=redis://redis:6379 \
--easy.spring.redis.password="替换为生产 Redis 密码" \
--easy.web.cors.allowed-origins[0]=https://admin.example.com
内网 HTTP 部署仍建议使用 prod,再按实际网络环境覆盖差异。例如纯内网未启用 HTTPS 时关闭 HSTS,并把 CORS 域名设为真实内网前端地址:
java -jar easy-next-admin-server/target/easyNextAdmin.jar \
--spring.profiles.active=prod \
--spring.datasource.url="jdbc:mysql://mysql:3306/easy-next-admin?serverTimezone=GMT%2B8&characterEncoding=UTF-8&connectionCollation=utf8mb4_unicode_ci&useSSL=false&allowPublicKeyRetrieval=true" \
--spring.datasource.username=easy_admin \
--spring.datasource.password="替换为内网数据库密码" \
--easy.spring.redis.address=redis://redis:6379 \
--easy.spring.redis.password="替换为内网 Redis 密码" \
--easy.web.security-headers.hsts-enabled=false \
--easy.web.cors.allowed-origins[0]=http://admin.intranet.example
示例:
java \
-jar easy-next-admin-server/target/easyNextAdmin.jar \
--spring.profiles.active=prod \
--spring.datasource.url="jdbc:mysql://127.0.0.1:3306/easy-next-admin?serverTimezone=GMT%2B8&characterEncoding=UTF-8&connectionCollation=utf8mb4_unicode_ci&useSSL=false&allowPublicKeyRetrieval=true" \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--easy.features.redis=true \
--easy.spring.redis.address=redis://127.0.0.1:6379 \
--easy.spring.redis.password=111222
生产环境建议:
- 使用非
localprofile 启动,避免加载本地开发配置;Swagger UI 和 OpenAPI JSON 在通用配置中默认关闭。 - 内网和公网部署都使用
prodprofile,并通过环境变量或启动参数提供数据库、Redis、对象存储、线程池容量和真实前端域名。 - 不启用
localprofile;/api/auth/demo-accounts在生产环境会返回空列表,仍需替换初始化账号密码。 - 使用外部 MySQL 和 Redis,避免把生产状态放在应用容器内。
- Redis 使用能力级开关
easy.features.redis=true。开启后缓存、会话、验证码、重复请求、幂等、限流和分布式锁会自动切到 Redis/Redisson 实现。 - Kafka 使用能力级开关
easy.features.kafka=true。未开启时不会创建 Kafka Producer、Consumer、Topic Admin 和健康检查,避免单机开发误连localhost:9092。 - Feign、调度、监控、WebLog、OSS 和本地消息也都通过
easy.features.*控制。生产只开启实际需要的能力;Influx 指标导出默认关闭,需要接入外部指标库时再显式配置。InfluxDB 作为当前指标后端没有问题,应用侧通过 Micrometer 输出easy.api.requests、easy.remote.calls等低基数指标,后续要换 Prometheus 或 OTLP 时应新增 exporter,而不是改业务埋点。 - 通过环境变量、启动参数或配置中心覆盖数据库密码、Redis 密码、对象存储配置。
- 按企业安全策略配置会话超时:
EASY_AUTH_SESSION_IDLE_TIMEOUT默认30m,EASY_AUTH_SESSION_ABSOLUTE_TIMEOUT默认8h。普通企业后台绝对超时通常为 8-12 小时,公网或高权限后台建议 4-8 小时。 - 按真实前端域名覆盖
easy.web.cors.allowed-origins或easy.web.cors.allowed-origin-patterns,不要在生产环境继续使用本地开发 Origin,也不要开放*且携带凭证。 - 按部署方式收紧
easy.web.security-headers:HTTPS 环境可开启hsts-enabled,稳定资源路径后再配置content-security-policy,避免本地 HTTP 和历史内联资源被误伤。 - 把
/actuator/health暴露给负载均衡健康检查,其他 Actuator 端点按内网权限控制。 - 使用反向代理统一接入 HTTPS、访问日志和限流策略。
- 对公开生产环境,生产安全路线固定为服务端会话 +
HttpOnly; Secure; SameSiteCookie,并为写接口配置 CSRF 防护;当前 Bearer token 方案只适合作为本地开发和前后端分离调试路线,不作为生产验收方案。 - 用户导入保持 CSV、小文件和行数限制;当前默认单文件不超过 2MB、单次不超过 1000 行,避免后台导入拖垮服务。
- 实时日志的日志级别调整是独立权限
monitor:weblog:level,只授予可信运维角色。 - 本地 logback 文件日志用于 WebLog 和现场排障;采集到 OpenSearch / Elasticsearch / SLS / Loki 的日志应通过采集器解析或 JSON appender 形成结构化字段。不要把 WebLog 当集中日志平台使用,也不要在本地文件里长期打开 DEBUG。
- 审计和 API 访问日志要配置保留策略:
audit_api_log这类高增长表建议 30-90 天热数据,登录、权限、角色、菜单和敏感变更按企业合规保留更久;清理或归档任务必须记录范围、行数和执行结果。
依赖版本与兼容性
本仓库的 docker-compose.yml 只作为本地开发依赖编排,当前固定的兼容性基线如下:
| 依赖 | 本地镜像 | 说明 |
|---|---|---|
| MySQL | mysql:8.4 |
MySQL 8.4 LTS。新数据卷使用默认 caching_sha2_password 认证,不启用已废弃的 mysql_native_password。 |
| Redis | redis:7.4-alpine |
Redis 7.4 Alpine。开启 AOF,适合本地保留运行态数据;兼容 Redis 7.4 生成的 RDB/AOF 基础文件格式。 |
企业部署时建议保持同一大版本和小版本通道,不要直接使用 latest。如果升级 MySQL 或 Redis 的大版本、小版本,需要先在预发环境完成数据库迁移、登录、权限、文件、流程、调度、缓存和审计链路验证。生产镜像建议进一步固定到补丁版本或 digest,并通过镜像扫描和变更窗口统一升级。
MySQL 8.4 默认禁用旧的 mysql_native_password 服务端插件,MySQL 9 会移除该插件。EasyNextAdmin 作为全新脚手架不为旧插件保留默认兼容配置;如果企业环境里存在历史账号,应在升级窗口内先迁移到 caching_sha2_password,再切换到 MySQL 8.4 或更高版本。
前端构建
cd easy-next-admin-web
npm ci
npm run build
产物:
easy-next-admin-web/dist
默认构建后的前端仍通过相对路径 /api 访问后端。生产部署时,应由 Nginx 或网关把 /api/ 反向代理到后端服务。
Nginx 静态部署
示例配置:
server {
listen 80;
server_name example.com;
root /usr/share/nginx/html/easy-next-admin;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 75s;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
try_files $uri $uri/ /index.html;
}
}
注意 proxy_pass http://127.0.0.1:8080; 不带末尾 /,这样会保留 /api 前缀,匹配当前后端控制器路径。proxy_read_timeout 75s 用于给普通业务查询、导入导出和工作流详情留出反向代理读取时间,避免代理先于应用正常响应断开。
Docker 构建
企业环境通常不要直接把本地 docker-compose.yml 当生产编排。推荐做法是:
- 应用镜像和依赖镜像分开发布,MySQL、Redis 优先使用托管服务或独立高可用集群。
- 镜像使用明确 tag,生产发布清单固定 digest;升级通过预发验证和回滚方案管理。
- 密码、Token、对象存储密钥使用 Secret/配置中心,不写入镜像、不提交
.env。 - 容器以非 root 用户运行,限制运行权限,保留健康检查、资源限制和日志轮转。
- 数据目录、上传文件和日志进入持久化卷或外部服务,备份恢复流程要定期演练。
- 业务应用实例保持无状态,横向扩容依赖外部 Redis、数据库和对象存储。
构建后端镜像:
mvn -pl easy-next-admin-server -am -DskipTests package
docker build -f easy-next-admin-server/Dockerfile -t easy-next-admin-server:local .
后端 Dockerfile 放在 easy-next-admin-server/,但构建上下文仍然要使用仓库根目录 .。镜像构建会复制本地 Maven 产物 easy-next-admin-server/target/easyNextAdmin.jar,因此必须先在本地或 CI 中完成 Maven 打包。这样 Docker 镜像阶段只做运行环境封装,不在镜像构建里重复下载 Maven 依赖。后端镜像默认使用 SPRING_PROFILES_ACTIVE=prod 启动;本地临时调试容器时,可通过 -e SPRING_PROFILES_ACTIVE=local 显式覆盖。
运行后端容器示例。下面命令只用于本机快速验证后端镜像:数据库连宿主机 MySQL,并显式关闭 Redis,避免单容器示例误连 redis://redis:6379。接近生产的容器部署应去掉 EASY_FEATURE_REDIS=false,并传入真实 Redis 地址和密码。
docker run --rm -p 8080:8080 \
-e JAVA_OPTS="-Xms512m -Xmx1024m" \
-e EASY_FEATURE_REDIS=false \
easy-next-admin-server:local \
--spring.datasource.url="jdbc:mysql://host.docker.internal:3306/easy-next-admin?serverTimezone=GMT%2B8&characterEncoding=UTF-8&connectionCollation=utf8mb4_unicode_ci&useSSL=false&allowPublicKeyRetrieval=true" \
--spring.datasource.username=root \
--spring.datasource.password=123456
构建前端镜像:
cd easy-next-admin-web
npm ci
npm run build
cd ..
docker build -t easy-next-admin-web:local ./easy-next-admin-web
前端 Dockerfile 只复制本地构建产物 easy-next-admin-web/dist 到 Nginx 镜像,因此必须先完成前端构建。
运行前端容器示例:
docker run --rm -p 8081:80 easy-next-admin-web:local
前端镜像默认把 /api/ 和 /storage/ 代理到 http://host.docker.internal:8080,适合本地 Docker Desktop 访问宿主机后端。企业部署或前后端同在 Docker 网络时,通过运行时环境变量覆盖代理目标,不需要重新构建镜像:
docker run --rm -p 8081:80 \
-e API_PROXY_PASS=http://server:8080 \
easy-next-admin-web:local
前端镜像内置的 nginx.conf 默认写入 X-Frame-Options、X-Content-Type-Options、Referrer-Policy 和 Permissions-Policy,并对 /assets/ 指纹文件启用长期缓存,对入口页面使用 no-store,避免发版后浏览器长期持有旧入口。
发布检查
发布前建议至少执行:
mvn -pl easy-next-admin-server -am -DskipTests package
cd easy-next-admin-web && npm run build
仓库内置 GitHub Actions 工作流会在 push 和 PR 时运行后端 verify、前端单元测试和前端构建;本地仍可按需只运行对应命令。
发布后检查:
GET /actuator/health返回UP。- 前端刷新任意二级路由不会 404。
- 登录、工作台、用户管理、角色授权、流程待办、实时日志至少各验证一次。
- 用户导入模板、1000 行限制、导出 CSV 脱公式注入至少验证一次。
- 公开生产环境必须替换初始化账号密码;如需公开体验环境,应单独准备脱敏账号和隔离数据,不复用生产配置。