本目录使用“自定义 Java 21 应用镜像 + Docker Compose + app.env 外部配置”。Compose 只启动 admin-server,并通过外部 vben-network 复用服务器已有的 MySQL、Redis 和 MinIO,不会重复创建这些服务,也不依赖 Nacos。
deploy/
Dockerfile 将 Java 21 和 app.jar 制作为应用镜像
.dockerignore 阻止 app.env 等文件进入镜像构建上下文
.env 管理镜像版本号,不包含密码
docker-compose.yml 构建并启动 Java 后端容器
app.env 数据库、Redis、MinIO、JWT 和 Cookie 配置
app.jar Maven 打包产物
app.env 已根据当前环境填写:数据库用户名为 root,MinIO 账号为 admin。后端分别使用 mysql、myredis、minio 容器名连接内部服务;只有返回给浏览器的 MinIO 公共地址继续使用宿主机 IP。app.env 和 app.jar 已加入 .gitignore。
在 Windows 的 E:\github\admin-server 目录执行:
$env:JAVA_HOME='D:\JAVA22'
$env:Path="$env:JAVA_HOME\bin;$env:Path"
mvn -DskipTests clean package
Copy-Item target\admin-server-0.1.0-SNAPSHOT.jar deploy\app.jar -Force项目使用 release 21 编译,生成的 JAR 在 Java 21 容器中运行。当前部署压缩包已包含打包好的 app.jar。
将完整部署压缩包上传到 CentOS,例如 /opt/admin-server/admin-server-deploy.zip,然后执行:
mkdir -p /opt/admin-server
cd /opt/admin-server
unzip admin-server-deploy.zip
chmod 600 app.env
chmod 644 app.jar
# 下面四条网络命令只需在服务器首次部署时执行一次。
docker network create vben-network
docker network connect vben-network mysql
docker network connect vben-network myredis
docker network connect vben-network minio
# 确认三个现有服务都已加入网络。
docker network inspect vben-network --format '{{range .Containers}}{{println .Name}}{{end}}'
docker compose version
docker compose config --quiet
docker compose build --pull admin-server
docker compose up -d admin-server
docker compose ps
docker compose logs --tail=200 -f admin-server如果 vben-network 或某个容器已经加入网络,对应的一次性命令可以跳过。admin-server 由 Compose 自动加入该网络,不需要再手动执行 docker network connect。
docker compose build 根据 Dockerfile 生成 admin-server:1.0.0 镜像;docker compose up 使用 app.env 创建容器。第一次需要下载 Java 21 基础镜像,服务器需能访问镜像仓库。服务器本身不需要安装 Java 或 Maven。
按 Ctrl+C 只退出日志查看,不会停止后台容器。
另一个终端执行:
curl -fsS http://127.0.0.1:8080/api/system/config/public正常响应包含 code: 200。接口文档地址:
http://服务器IP:8080/api/doc.html
容器显示 Up 只说明 Java 进程正在运行,还要验证登录、刷新 Token、权限接口和头像上传。
检查四个容器是否处于同一网络:
docker network inspect vben-network --format '{{range .Containers}}{{println .Name}}{{end}}'应包含 admin-server、mysql、myredis、minio。
首次启动会执行未应用的 Flyway 数据库迁移。启动前备份当前 vbenAdmin,保留已有 flyway_schema_history。历史迁移包含旧 sys_* 用户、角色、菜单表清理,不要删除版本记录后重新执行全部迁移。
本地前端代理目标使用:
http://192.168.137.10:8080/api
正式前端由 Nginx 将 /api/ 转发到后端 8080,转发时保留 /api 前缀。
当前 app.env 使用 REFRESH_COOKIE_SECURE=false、REFRESH_COOKIE_SAME_SITE=Lax,对应现有内网 HTTP 同站代理。正式启用 HTTPS 后改成 true、Lax;只有 HTTPS 跨站访问才按需使用 true、None。
Java 后端通过 http://minio:9000 访问 MinIO。MINIO_PUBLIC_URL 会返回给浏览器,当前配置为 http://192.168.137.10/minio,由 Nginx 将 /minio/ 转发到 minio:9000。宿主机 9001 是 MinIO API 直连端口,9090 是 MinIO 控制台。
例如从 1.0.0 发布到 1.0.1:
- 本地重新打包,将新 JAR 上传到服务器并命名为
app.jar.new。 - 在服务器确认文件有效,然后替换 JAR。
- 将
.env的ADMIN_SERVER_VERSION改为1.0.1。 - 构建新镜像并启动。
cd /opt/admin-server
test -s app.jar.new
chmod 644 app.jar.new
mv app.jar.new app.jar
sed -i 's/ADMIN_SERVER_VERSION=.*/ADMIN_SERVER_VERSION=1.0.1/' .env
docker compose build --pull admin-server
docker compose up -d admin-server
docker compose logs --tail=200 -f admin-server新版本使用新镜像标签,旧镜像仍然保留。更新 app.env 后也要执行 docker compose up -d --force-recreate admin-server,单纯 restart 不会重新读取环境配置。
例如回退到仍保留在服务器上的 1.0.0 镜像:
cd /opt/admin-server
sed -i 's/ADMIN_SERVER_VERSION=.*/ADMIN_SERVER_VERSION=1.0.0/' .env
docker compose up -d admin-server
docker compose logs --tail=200 -f admin-serverJAR 版本和数据库迁移需要保持兼容。应用镜像回退不会自动回退数据库,因此执行包含数据库结构变化的新版本前要先制定迁移和回退方案。
# 查看状态
docker compose ps
# 查看最近日志
docker compose logs --tail=200 admin-server
# 实时查看日志
docker compose logs -f admin-server
# 重新创建容器并读取新的 app.env
docker compose up -d --force-recreate admin-server
# 停止 Java 后端,不影响 MySQL、Redis、MinIO
docker compose stop admin-server
# 启动 Java 后端
docker compose start admin-serverapp.jar找不到:确认部署目录内存在普通文件app.jar,然后重新执行构建。- 拉取 Java 21 镜像失败:检查服务器网络或配置可用的 Docker 镜像加速地址。
8080被占用:修改 Compose 中端口映射左侧,例如8081:8080,并同步修改前端代理。- 日志出现
UnknownHostException:确认admin-server和对应服务都在vben-network,并核对mysql、myredis、minio容器名。 - 数据库拒绝连接:检查
app.env的账号密码,以及 MySQL 用户是否允许来自 Docker 网络的连接。 - 登录后无法刷新:核对浏览器实际使用 HTTP 还是 HTTPS,以及 Cookie 设置和 Nginx 代理是否一致。
- 内存不足:当前容器上限为
1g,Java 堆最多使用其中 60%,可以按服务器容量调整。 - 日志过大:Docker 控制台日志已限制为每份 10 MB、最多 3 份;业务审计日志仍写入数据库。