开发者

Java项目打包Docker镜像全流程

目录
  • 环境准备
    • 1. 开发环境要求
    • 2. 安装docker
    • 3. 验证安装
  • 项目结构说明
    • Docker基础概念
      • 编写Dockerfile
        • 基础Dockerfile示例
          • 逐行解析
      • 多阶段构建优化
        • 进阶优化技巧
        • 构建与运行镜像
          • 1. 构建镜像
            • 2. 查看镜像
              • 3. 运行容器
                • 4. 查看运行状态
                  • 5. 查看日志
                    • 6. 停止和删除容器
                    • 推送镜像到仓库
                      • 1. 登录Docker Hub
                        • 2. 标记镜像
                          • 3. 推送镜像
                            • 4. 从仓库拉取运行
                            • 生产环境部署
                              • 1. 使用docker-compose
                                • 2. Kubernetes部署示例
                                • 总结与最佳实践
                                  • 最佳实践总结
                                    • 常见问题解决
                                      • 下一步学习建议

                                      环境准备

                                      1. 开发环境要求

                                      • JDK 8+ (推荐JDK 11/17 LTS版本)
                                      • Maven 3.6+ 或 Gradle 7+
                                      • Docker Desktop (MAC/Windows) 或 Docker Engine (linux)
                                      • 推荐IDE: IntelliJ IDEA (社区版即可)

                                      2. 安装Docker

                                      不同操作系统的安装方式:

                                      Linux (Ubuntu为例):

                                      # 卸载旧版本
                                      sudo apt-get remove docker docker-engine docker.io containerd runc
                                      
                                      # 安装依赖
                                      sudo apt-get update
                                      sudo apt-get install \
                                          apt-transport-https \
                                          ca-certificates \
                                          curl \
                                          gnupg \
                                          lsb-release
                                      
                                      # 添加Docker官方GPG密钥
                                      curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
                                      
                                      # 设置稳定版仓库
                                      echo \
                                        "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
                                        $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
                                      
                                      # 安装Docker引擎
                                      sudo apt-get update
                                      sudo apt-get install docker-ce docker-ce-cli containerd.io
                                      
                                      # 验证安装
                                      sudo docker run hello-world
                                      

                                      Mac/Windows:直接下载Docker Desktop安装包:

                                      https://www.docker.c编程客栈om/products/docker-desktop

                                      3. 验证安装

                                      docker --version
                                      # 输出类似: Docker version 20.10.12, build e91ed57
                                      
                                      docker-compose --version
                                      # 输出类似: docker-compose version 1.29.2, build 5becea4c
                                      

                                      项目结构说明

                                      我们以一个典型的Spring Boot项目为例:

                                      my-Java-app/
                                      ├── src/
                                      │   ├── main/
                                      │   │   ├── java/com/example/demo/
                                      │   │   │   ├── DemoApplication.java
                                      │   │   │   └── controllers/
                                      │   │   └── resources/
                                      │   │       ├── application.properties
                                      │   │       └── static/
                                      │   └── test/
                                      ├── target/
                                      │   ├── my-java-app-0.0.1-SNAPSHOT.jar
                                      │   └── ...
                                      ├── pom.XML
                                      └── Dockerfile
                                      

                                      Docker基础概念

                                      在开始之前,先了解几个核心概念:

                                      • 镜像(Image): 只读模板,包含运行应用所需的所有内容
                                      • 容器(Container): 镜像的运行实例
                                      • Dockerfile: 构建镜像的指令文件
                                      • Registry: 镜像仓库(如Docker Hub)

                                      Docker的优势:

                                      • 一致的运行环境
                                      • 快速部署和扩展
                                      • 资源隔离
                                      • 易于版本管理和回滚

                                      编写Dockerfile

                                      基础Dockerfile示例

                                      # 第一阶段:构建
                                      FROM maven:3.8.4-openjdk-11 AS build
                                      WORKDIR /app
                                      COPY pom.xml .
                                      # 利用缓存下载依赖
                                      RUN mvn dependency:go-offline
                                      COPY src ./src
                                      RUN mvn package -DskipTests
                                      
                                      # 第二阶段:运行
                                      FROM openjdk:11-jre-slim
                                      WORKDIR /app
                                      # 从构建阶段复制jar包
                                      COPY --from=build /app/target/my-java-app-*.jar app.jar
                                      # 暴露端口
                                      EXPOSE 8080
                                      # 启动命令
                                      Ewww.devze.comNTRYPOINT ["java", "-jar", "app.jar"]
                                      

                                      逐行解析

                                      1. FROM maven:3.8.4-openjdk-11 AS build

                                        使用Maven镜像作为构建阶段的基础镜像,并命名为"build"

                                      2. WORKDIR /app

                                        设置工作目录为/app

                                      3. COPY pom.xml .

                                        复制pom.xml到工作目录

                                      4. RUN mvn dependency:go-offline

                                        下载所有依赖项(利用Docker缓存层)

                                      5. COPY src ./src

                                        复制源代码

                                      6. RUN mvn package -DskipTests

                                        打包应用(跳过测试)

                                      7. FROM openjdk:11-jre-slim

                                        第二阶段使用更小的JRE镜像

                                      8. COPY --from=build /app/target/my-java-app-*.jar app.jar

                                        从构建阶段复制生成的jar包

                                      9. EXPOSE 8080

                                        声明容器暴露的端口

                                      10. ENTRYPOINT ["java", "-jar", "app.jar"]

                                        容器启动时执行的命令

                                      多阶段构建优化

                                      多阶段构建有三大优势:

                                      1. 减小镜像体积 - 最终镜像只包含运行时必要内容
                                      2. 提高安全性 - 构建工具不会出现在生产镜像中
                                      3. 更清晰的构建流程 - 分离构建和运行环境

                                      进阶优化技巧

                                      1. 使用.dockerignore文件

                                        避免将不必要的文件复制到镜像中:

                                      .git
                                      .idea
                                      *.iml
                                      target/
                                      *.log
                                      *.tmp
                                      
                                      1. 选择合适的基础镜像

                                        • openjdk:11-jdk - 完整JDK(较大)
                                        • openjdk:11-jre - 仅运行时(较小)
                                        • openjdk:11-jre-slim - 更精简版本
                                        • openjdk:11-alpine - 基于Alpine Linux(最小)
                                      2. 层缓存优化

                                        将不常变化的指令放在前面,充分利用缓存:

                                      # 先复制pom.xml并下载依赖
                                      COPY pom.xml .
                                      RUN mvn dependency:go-offline
                                      
                                      # 然后复制源代码
                                      COPY src ./src
                                      

                                      构建与运行镜像

                                      1. 构建镜像

                                      # -t 指定镜像名称和标签
                                      # . 表示使用当前目录的Dockerfile
                                      docker build -t my-java-app:1.0 .
                                      

                                      构建过程输出示例:

                                      [+] Building 45.3s (12/12) FINISHED
                                       => [internal] load build definition from Dockerfile                       0.0s
                                       => => transferring dockerfile: 37B                                        0.0s
                                       => [internal] load .dockerignore                                          0.0s
                                       => => transferring context: 35B                                           0.0s
                                       => [internal] load metadata for docker.io/library/openjdk:11-jre-slim    1.5s
                                       => [internal] load metadata for docker.io/library/maven:3.8.4-openjdk-11  1.5s
                                       => [build 1/5] FROM docker.io/library/maven:3.8.4-openjdk-11@sha256:9c... 0.0s
                                       => [internal] load build context                                          0.1s
                                       => => transferring context: 3.01kB                                        0.0s
                                       => CACHED [build 2/5] WORKDIR /app                                        0.0s
                                       => [build 3/5] COPY pom.xml .                                             0.0s
                                       => [build 4/5] RUN mvn dependency:go-offline                              20.1s
                                       => [build 5/5] COPY src ./src                                             0.0s
                                       => [build 6/5] RUN mvn package -DskipTests                               18.2s
                                       => [stage-1 1/2] FROM docker.io/library/openjdk:11-jre-slim@sha256:9c... 0.0s
                                       => [stage-1 2/2] COPY --from=build /app/target/my-java-app-*.jar app.jar  0.1s
                                       => exporting to image                                                     0.1s
                                       => => exporting layers                                                    0.1s
                                       => => writing image sha256:7e9b6e5ba...                                   0.0s
                                       => => naming to docker.io/library/my-java-app:1.0                         0.0s
                                      

                                      2. 查看镜像

                                      docker images
                                      
                                      # 输出示例
                                      REPOSITORY     TAG       IMAGE ID       CREATED         SIZE
                                      my-java-app    1.0       7e9b6e5ba123   2 minutes ago   215MB
                                      

                                      3. 运行容器

                                      # -d 后台运行
                                      # -p 端口映射(主机端口:容器端口)
                                      # --name 容器名称
                                      docker run -d -p 8080:8080 --name my-app my-java-app:1.0
                                      

                                      4. 查看运行状态

                                      docker ps
                                      
                                      # 输出示例
                                      CONTAINER ID   IMAGE             COMMAND               CREATED         STATUS         PORTS                    NAMES
                                      a3b8d7e6f5g4   my-java-app:1.0   "java -jar app.jar"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->8080/tcp   my-app
                                      

                                      5. 查看日志

                                      docker logs -f my-app
                                      
                                      # 输出示例
                                        .   ____          _            __ _ _
                                       /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
                                      ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
                                       \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
                                        '  |____| .__|_| |_|_| |_\__, | / / / /
                                       =========|_|==============|___/=/_/_/_/
                                       :: Spring Boot ::                (v2.6.3)
                                      

                                      6. 停止和删除容器

                                      # 停止容器
                                      docker stop my-app
                                      
                                      # 删除容器
                                      docker rm my-app
                                      
                                      # 删除镜像
                                      docker rmi my-java-app:1.0
                                      

                                      推送镜像到仓库

                                      1. 登录Docker Hub

                                      docker login -u your-username
                                      

                                      2. 标记镜像

                                      # 格式: docker tag local-image:tagname username/repository:tagname
                                      docker tag my-java-app:1.0 your-username/my-java-app:1.0
                                      

                                      3. 推送镜像

                                      docker push your-username/my-java-app:1.0
                                      

                                      4. 从仓库拉取运行

                                      docker run -d -p 8080:8080 your-username/my-java-app:1.0
                                      

                                      生产环境部署

                                      1. 使用docker-compose

                                      创建docker-compose.yml文件:

                                      version: '3.8'
                                      
                                      services:
                                        app:
                                          image: yojsur-username/my-java-app:1.0
                                          container_name: my-java-app
                                          ports:
                                            - "8080:8080"
                                          environment:
                                            - SPRING_PROFILES_ACTIVE=prod
                                          restart: unless-stopped
                                          volumes:
                                            - ./logs:/app/logs
                                          healthcheck:
                                            test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
                                            interval: 30s
                                            timeout: 10s
                                            retries: 3
                                      

                                      启动服务:

                                      docker-compose up -d
                                      

                                      2. Kubernetes部署示例

                                      创建deployment.yaml:

                                      apiVersion: apps/v1
                                      kind: Deployment
                                      metadata:
                                        name: java-app
                                      spec:
                                        replicas: 3
                                        selector:
                                          matchLabels:
                                            app: java-app
                                        template:
                                          metadata:
                                            labels:
                                              app: java-app
                                          spec:
                                            containers:
                                            - name: java-app
                                              image: your-username/my-java-app:1.0
                                              ports:
                                              - containerPort: 8080
                                              resources:
                                                requests:
                                                  cpu: "50www.devze.com0m"
                                                  memory: "512Mi"
                                                limits:
                                                  cpu: "1000m"
                                                  memory: "1024Mi"
                                              livenessProbe:
                                                httpGet:
                                                  path: /actuator/health
                                                  port: 8080
                                                initialDelaySeconds: 30
                                                periodSeconds: 10
                                              readinessProbe:
                                                httpGet:
                                                  path: /actuator/health
                                                  port: 8080
                                                initialDelaySeconds: 20
                                                periodSeconds: 5
                                      

                                      总结与最佳实践

                                      最佳实践总结

                                      1. 镜像优化

                                        • 使用多阶段构建减小镜像体积
                                        • 选择合适的基础镜像(Alpine/slim版本)
                                        • 定期更新基础镜像以获取安全补丁
                                      2. 构建优化

                                        • 合理利用层缓存(.dockerignore + 指令顺序)
                                        • 固定基础镜像版本(避免使用latest标签)
                                        • 在CI/CD中实现自动化构建
                                      3. 运行优化

                                        • 限制容器资源(cpu/memory)
                                        • 配置健康检查
                                        • 使用非root用户运行
                                        • 正确处理信号(如SIGTERM)
                                      4. 安全建议

                                        • 不要将敏感信息硬编码在镜像中(使用环境变量/secret)
                                        • 扫描镜像中的漏洞(使用docker scan)
                                        • 最小化容器权限(避免–privileged)

                                      常见问题解决

                                      Q: 构建时下载依赖很慢怎么办?

                                      A: 配置Maven镜像仓库:

                                      RUN mkdir -p /root/.m2 && \
                                          echo 'aliyunhttps://maven.aliyun.com/repository/publiccentral' > /root/.m2/settings.xml
                                      

                                      Q: 容器启动后立即退出?

                                      A: 可能原因:

                                      1. 应用启动失败 - 查看日志docker logs
                                      2. 没有前台进程 - 确保应用不是以daemon方式运行
                                      3. 端口冲突 - 检查端口映射

                                      Q: 如何调试容器内的应用?

                                      A: 进入运行中的容器:

                                      docker exec -it  /bin/bash
                                      

                                      或者直接附加到进程:

                                      docker attach 
                                      

                                      下一步学习建议

                                      1. 学习Docker网络和存储卷配置
                                      2. 掌握Docker Compose编排多容器应用
                                      3. 了解Kubernetes容器编排
                                      4. 探索CI/CD流水线与Docker集成
                                      5. 学习服务网格(如Istio)与容器化应用

                                      通过本文的学习,你已经掌握了Java项目容器化的核心技能。Docker的世界还有很多值得探索的地方,继续实践,你将发现更多容器化带来的便利与效率提升!

                                      以上就是Java项目打包Docker镜像全流程的详细内容,更多关于Java打包Docker镜像的资料请关注编程客栈(www.cppcns.cojavascriptm)其它相关文章!

                                      0

                                      上一篇:

                                      下一篇:

                                      精彩评论

                                      暂无评论...
                                      验证码 换一张
                                      取 消

                                      最新开发

                                      开发排行榜