项目的框架演进为:
阶段一:核心代码开发。使用 IDEA 或 VSCode 在本地完成所有微服务和前端页面的编码与调试。
阶段二:Docker 容器化。为每个服务编写
Dockerfile,将它们打包成镜像,并通过docker-compose.yml实现一键本地部署。阶段三:Kubernetes 容器编排。将 Docker Compose 的编排能力升级到生产级的 Kubernetes,编写 YAML 文件定义 Deployment、Service、Ingress、HPA(自动伸缩)等资源,实现应用的弹性、自愈和滚动更新。
阶段四:可观测性体系建设。集成 Prometheus + Grafana 构建监控体系,接入 ELK/Loki 构建日志平台,让系统状态一目了然。
阶段五:云上生产部署。将镜像推送至阿里云 ACR,利用 Terraform 或 ROS 一键创建云资源,并将应用部署到托管的 Kubernetes 集群(ACK/EKS),最终对外提供服务。
由于我侧重于书写项目的运维结构,这边我将先从docker部署和k8s以及云端部署开始写起。关于项目的前端和后端等到最后再去介绍。
在部署到docker前要确定在本机能正常运行,并且所有的窗口以及功能正常,再去进行封装打包。
本次讲的便是阶段二·Docker容器化。
前期任务:
确保环境安装了以下:
Git:用于克隆或管理代码。
JDK 17:后端运行环境。确认在终端运行 。
java -versionMaven:后端项目构建工具。确认在终端运行。
mvn -versionNode.js:前端运行环境。确认在终端运行。
node -v
项目的大体框架如下:
E:\CloudMart/ ├── cloudmart-server/ # 📁 所有后端 Java 代码 ├── cloudmart-web/ # 📁 所有前端 Vue 代码 ├── ops/ # 📁 核心运维目录 │ ├── docker/ # 📁Docker 相关配置│ ├── k8s/ # 📁 未来 Kubernetes 配置占位 │ └── scripts/ # 📁 存放辅助脚本 └── docs/ # 📁 项目存放文档、截图等这边我先讲述我的打包我后端代码即cloudmart-service的user.service到docker,镜像以及部署的示例演示。
这是我后端的框架:
cloudmart-server/ ├── pom.xml # 父 POM,定义公共依赖和版本 ├── cloudmart-common/ # 公共模块(工具类、统一响应、异常处理) ├── cloudmart-user-service/ # 用户服务(端口 8081) ├── cloudmart-product-service/ # 商品服务(端口 8082) ├── cloudmart-order-service/ # 订单服务(端口 8083) └── cloudmart-seckill-service/ # 秒杀服务(端口 8084)
现在,我们开始将代码变成可以在任何地方运行的 Docker 镜像。
工作流程:
我们采用多阶段构建
(多阶段构建让我们可以在一个Dockerfile中先用大镜像完成编译,再把编译产物复制到一个精简的小镜像中,减小储存)
阶段一(构建阶段):Maven镜像 → 下载依赖 → 编译代码 → 打包JAR ↓ 阶段二(运行阶段):JRE镜像 ← 从阶段一复制JAR ← 配置启动命令1.编写dockerfile
这边我们就以打包user服务为例子。Dockerfile.user 是一个文本文件,里面写的是“如何把 user-service 的源代码变成可运行镜像”的完整说明书。
它不是代码,不是配置文件,而是一份构建清单——Docker 照着它一步步执行,最终产出一个.jar包+运行环境合体的镜像。这边我个人理解是docker的菜谱吧,docker会按照这个file去执行里面命令。
FROM maven:3.8.4-openjdk-17 AS builder # 使用包含Maven和JDK的完整镜像来编译项目 WORKDIR /app # 设置容器内的工作目录。后续所有命令都在这个目录下执行 # 先复制父pom,再复制子模块pom。Docker会缓存每一层的执行结果。 # 只要pom.xml内容不变,后续构建就不会重复执行"下载依赖"这一步, # 可以节省大量构建时间。 COPY cloudmart-server/pom.xml . COPY cloudmart-server/cloudmart-common/pom.xml cloudmart-common/ COPY cloudmart-server/cloudmart-user-service/pom.xml cloudmart-user-service/ # -B参数表示批处理模式(非交互),-o表示离线模式。 # dependency:go-offline会下载所有pom.xml中声明的依赖到本地仓库。 # 这一层会被Docker缓存,只要pom.xml不变就不会重复执行。 RUN mvn dependency:go-offline -B # 此时才复制所有源代码。因为前面已经把依赖下载好了, # 源码的改动不会触发依赖重新下载,只会重新编译。 COPY cloudmart-server/ . # -DskipTests跳过单元测试(加快构建速度) RUN mvn clean package -DskipTests 运行阶段(Runtime) # 使用精简的JRE镜像来运行应用 FROM eclipse-temurin:17-jre-alpine # 设置工作目录 WORKDIR /app # --from=builder 表示从名为"builder"的阶段复制文件 # 使用通配符*匹配版本号,避免每次修改版本号都要改Dockerfile COPY --from=builder /app/cloudmart-user-service/target/cloudmart-user-service-*.jar app.jar # 这只是文档声明,实际端口映射在docker-compose.yml中配置 EXPOSE 8081 # -Xmx256m限制最大堆内存为256MB,防止容器内存溢出 # 使用exec形式(方括号)确保Java进程能正确接收信号 ENTRYPOINT ["java", "-Xmx256m", "-jar", "app.jar"]2.编写dockerignore文件 (可选)
本项目属于小项目,作者并没有编写该文件。这边简单介绍一下这个是什么文件。
.dockerignore是一个文本文件,放在项目根目录,作用类似于 Git 的.gitignore——告诉 Docker 在构建镜像时,哪些文件和目录不要复制到镜像里。用于加快构建速度、减少镜像体积、避免信息泄露。
这边给出我们项目可写的dockerignore文件。
# Git .git/ .gitignore # IDE .idea/ *.iml .vscode/ # 构建产物(避免把旧的JAR包也复制进去) **/target/ **/node_modules/ # 日志 *.log # Docker相关(避免循环复制) ops/ Dockerfile* docker-compose*.yml3.构建镜像
在项目根目录下运行
docker build -f ops/docker/Dockerfile.user -t cloudmart-user:latest .此时,docker会执行dockerfile,并按file文件执行命令。
等待创建完成···
4.验证镜像
输入指令
docker images | findstr cloudmart大概能看到
cloudmart-user latest abc123... 2 minutes ago 215MB
这边对后端服务例子就是这样有什么问题可以来评论区讨论哦,本人也是IT新手,请多多指教。
接下来我也会去介绍如何去打包我的前端,以及sql和redis中间件,以及我在打包redis端口和nginx出现的问题。以及解决方法。
谢谢观看。