Files
easy-next-admin/docs/deployment.md
laker 8c1f4c7c75 feat: initialize EasyNextAdmin
Publish the current verified project state without local development history or personal-path artifacts.
2026-07-17 17:58:57 +08:00

14 KiB
Raw Permalink Blame History

编译与部署

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_URLMYSQL_USERNAMEMYSQL_PASSWORDRedis 默认指向 redis://redis:6379,真实部署建议显式传入 EASY_REDIS_ADDRESSEASY_REDIS_PASSWORDprod 默认开启 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

生产环境建议:

  • 使用非 local profile 启动避免加载本地开发配置Swagger UI 和 OpenAPI JSON 在通用配置中默认关闭。
  • 内网和公网部署都使用 prod profile并通过环境变量或启动参数提供数据库、Redis、对象存储、线程池容量和真实前端域名。
  • 不启用 local profile/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.requestseasy.remote.calls 等低基数指标,后续要换 Prometheus 或 OTLP 时应新增 exporter而不是改业务埋点。
  • 通过环境变量、启动参数或配置中心覆盖数据库密码、Redis 密码、对象存储配置。
  • 按企业安全策略配置会话超时:EASY_AUTH_SESSION_IDLE_TIMEOUT 默认 30mEASY_AUTH_SESSION_ABSOLUTE_TIMEOUT 默认 8h。普通企业后台绝对超时通常为 8-12 小时,公网或高权限后台建议 4-8 小时。
  • 按真实前端域名覆盖 easy.web.cors.allowed-originseasy.web.cors.allowed-origin-patterns,不要在生产环境继续使用本地开发 Origin也不要开放 * 且携带凭证。
  • 按部署方式收紧 easy.web.security-headersHTTPS 环境可开启 hsts-enabled,稳定资源路径后再配置 content-security-policy,避免本地 HTTP 和历史内联资源被误伤。
  • /actuator/health 暴露给负载均衡健康检查,其他 Actuator 端点按内网权限控制。
  • 使用反向代理统一接入 HTTPS、访问日志和限流策略。
  • 对公开生产环境,生产安全路线固定为服务端会话 + HttpOnly; Secure; SameSite Cookie并为写接口配置 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-OptionsX-Content-Type-OptionsReferrer-PolicyPermissions-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 脱公式注入至少验证一次。
  • 公开生产环境必须替换初始化账号密码;如需公开体验环境,应单独准备脱敏账号和隔离数据,不复用生产配置。