news 2026/4/3 3:40:57

在 Docker 中运行 Java JAR 包实战教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Docker 中运行 Java JAR 包实战教程

📚 目录

  1. 前言与环境准备
  2. 准备 Java 项目
  3. 编写 Dockerfile
  4. 构建与运行镜像
  5. 进阶配置
  6. 使用 Docker Compose
  7. 最佳实践
  8. 常见问题排查

1. 前言与环境准备

1.1 为什么使用 Docker 运行 Java 应用?

┌─────────────────────────────────────────────────────────────────┐ │ 传统部署 vs Docker 部署 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 传统部署: Docker 部署: │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ App.jar │ │ Container │ │ │ ├─────────────┤ │ ┌─────────┐ │ │ │ │ JDK 8 │ ──────► │ │ App.jar │ │ │ │ ├─────────────┤ │ ├─────────┤ │ │ │ │ CentOS │ │ │ JDK │ │ │ │ └─────────────┘ │ ├─────────┤ │ │ │ │ │ Linux │ │ │ │ ❌ 环境不一致 │ └─────────┘ │ │ │ ❌ 依赖冲突 └─────────────┘ │ │ ❌ 部署复杂 │ │ ✅ 环境一致 │ │ ✅ 隔离性好 │ │ ✅ 快速部署 │ └─────────────────────────────────────────────────────────────────┘

1.2 环境准备

# 检查 Docker 是否安装docker --version# Docker version 24.0.0, build xxxxx# 检查 Docker 服务状态systemctl status docker# 如未安装,执行以下命令(以 CentOS 为例)yuminstall-y docker-ce docker-ce-cli containerd.io systemctl start docker systemctlenabledocker

1.3 项目结构

my-java-app/ ├── src/ │ └── main/ │ └── java/ │ └── com/example/ │ └── Application.java ├── target/ │ └── my-app-1.0.0.jar # 打包后的 JAR 文件 ├── Dockerfile # Docker 构建文件 ├── docker-compose.yml # Docker Compose 配置 └── pom.xml

2. 准备 Java 项目

2.1 示例 Spring Boot 应用

// Application.javapackagecom.example;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}@GetMapping("/hello")publicStringhello(){return"Hello from Docker! 🐳";}@GetMapping("/health")publicStringhealth(){return"OK";}}

2.2 Maven 打包配置

<!-- pom.xml --><project><groupId>com.example</groupId><artifactId>my-app</artifactId><version>1.0.0</version><packaging>jar</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><!-- 指定打包后的文件名 --><finalName>my-app</finalName></build></project>

2.3 打包 JAR 文件

# 使用 Maven 打包mvn clean package -DskipTests# 验证 JAR 文件ls-lh target/my-app.jar# 本地测试运行java -jar target/my-app.jar

3. 编写 Dockerfile

3.1 基础版 Dockerfile

# Dockerfile # 使用官方 OpenJDK 镜像作为基础镜像 FROM openjdk:8-jdk-alpine # 维护者信息 LABEL maintainer="your-email@example.com" LABEL version="1.0" LABEL description="My Java Application" # 设置工作目录 WORKDIR /app # 复制 JAR 文件到容器 COPY target/my-app.jar app.jar # 暴露应用端口 EXPOSE 8080 # 启动命令 ENTRYPOINT ["java", "-jar", "app.jar"]

3.2 优化版 Dockerfile(推荐)

# Dockerfile # ============ 第一阶段:构建阶段 ============ FROM maven:3.8.6-openjdk-8-slim AS builder WORKDIR /build # 先复制 pom.xml,利用 Docker 缓存机制 COPY pom.xml . RUN mvn dependency:go-offline -B # 复制源代码并构建 COPY src ./src RUN mvn clean package -DskipTests # ============ 第二阶段:运行阶段 ============ FROM openjdk:8-jre-alpine # 创建非 root 用户(安全最佳实践) RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app # 从构建阶段复制 JAR 文件 COPY --from=builder /build/target/*.jar app.jar # 更改文件所有权 RUN chown -R appuser:appgroup /app # 切换到非 root 用户 USER appuser # 暴露端口 EXPOSE 8080 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:8080/health || exit 1 # JVM 参数优化 ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC" # 启动命令 ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

3.3 不同 JDK 版本选择

# ============ JDK 版本选择参考 ============ # JDK 8 (经典稳定版) FROM openjdk:8-jdk-alpine # 完整 JDK,105MB FROM openjdk:8-jre-alpine # 仅运行时,85MB (推荐) # JDK 11 (LTS 长期支持版) FROM openjdk:11-jdk-slim # 精简版 FROM eclipse-temurin:11-jre # Eclipse Temurin (推荐) # JDK 17 (最新 LTS 版) FROM eclipse-temurin:17-jdk-alpine FROM eclipse-temurin:17-jre-alpine # 推荐 # JDK 21 (最新 LTS 版) FROM eclipse-temurin:21-jre-alpine

3.4 镜像大小对比

┌─────────────────────────────────────────────────────────────┐ │ 镜像大小对比 │ ├─────────────────────────────┬───────────────────────────────┤ │ 基础镜像 │ 大小 │ ├─────────────────────────────┼───────────────────────────────┤ │ openjdk:8 │ ~500MB │ │ openjdk:8-jdk-alpine │ ~105MB │ │ openjdk:8-jre-alpine │ ~85MB ⭐ 推荐 │ │ eclipse-temurin:17-jre │ ~260MB │ │ eclipse-temurin:17-jre-alpine │ ~180MB │ └─────────────────────────────┴───────────────────────────────┘

4. 构建与运行镜像

4.1 构建 Docker 镜像

# 基本构建命令docker build -t my-java-app:1.0.0.# 带详细日志的构建docker build --progress=plain -t my-java-app:1.0.0.# 不使用缓存构建docker build --no-cache -t my-java-app:1.0.0.# 构建时传递参数docker build\--build-argJAR_FILE=target/my-app.jar\-t my-java-app:1.0.0.

4.2 查看镜像信息

# 列出所有镜像docker images# 输出示例:# REPOSITORY TAG IMAGE ID CREATED SIZE# my-java-app 1.0.0 a1b2c3d4e5f6 30 seconds ago 145MB# 查看镜像详细信息docker inspect my-java-app:1.0.0# 查看镜像历史层dockerhistorymy-java-app:1.0.0

4.3 运行容器

# 基本运行docker run -d -p8080:8080 --name my-app my-java-app:1.0.0# 带环境变量运行docker run -d\-p8080:8080\--name my-app\-eSPRING_PROFILES_ACTIVE=prod\-eDATABASE_URL=jdbc:mysql://db:3306/mydb\my-java-app:1.0.0# 带资源限制运行docker run -d\-p8080:8080\--name my-app\--memory=512m\--cpus=1.0\my-java-app:1.0.0# 完整运行命令docker run -d\--name my-app\-p8080:8080\-v /host/logs:/app/logs\-v /host/config:/app/config:ro\-eJAVA_OPTS="-Xms256m -Xmx512m"\-eSPRING_PROFILES_ACTIVE=prod\--memory=512m\--cpus=1.0\--restart=unless-stopped\my-java-app:1.0.0

4.4 运行参数说明

┌──────────────────────────────────────────────────────────────────┐ │ Docker Run 参数说明 │ ├────────────────────┬─────────────────────────────────────────────┤ │ 参数 │ 说明 │ ├────────────────────┼─────────────────────────────────────────────┤ │ -d │ 后台运行容器 │ │ -p 8080:8080 │ 端口映射 (宿主机:容器) │ │ --name my-app │ 指定容器名称 │ │ -e KEY=VALUE │ 设置环境变量 │ │ -v /host:/container│ 挂载数据卷 │ │ --memory=512m │ 限制内存使用 │ │ --cpus=1.0 │ 限制 CPU 使用 │ │ --restart │ 重启策略 (no/always/unless-stopped) │ │ --network │ 指定网络 │ └────────────────────┴─────────────────────────────────────────────┘

4.5 验证运行状态

# 查看运行中的容器dockerps# 查看容器日志docker logs -f my-app# 查看最近 100 行日志docker logs --tail100my-app# 进入容器内部dockerexec-it my-app /bin/sh# 测试应用curlhttp://localhost:8080/hello# 输出: Hello from Docker! 🐳# 查看容器资源使用docker stats my-app

5. 进阶配置

5.1 多环境配置

# Dockerfile with args FROM eclipse-temurin:17-jre-alpine ARG PROFILE=dev ARG APP_PORT=8080 ENV SPRING_PROFILES_ACTIVE=${PROFILE} ENV SERVER_PORT=${APP_PORT} WORKDIR /app COPY target/*.jar app.jar EXPOSE ${APP_PORT} ENTRYPOINT ["sh", "-c", "java -jar app.jar"]
# 构建不同环境的镜像docker build --build-argPROFILE=dev -t my-app:dev.docker build --build-argPROFILE=prod -t my-app:prod.

5.2 配置文件外置

# application.ymlserver:port:${SERVER_PORT:8080}spring:profiles:active:${SPRING_PROFILES_ACTIVE:dev}datasource:url:${DATABASE_URL:jdbc:h2:mem:testdb}username:${DATABASE_USER:sa}password:${DATABASE_PASSWORD:}logging:level:root:${LOG_LEVEL:INFO}file:path:/app/logs
# 运行时挂载外部配置docker run -d\-p8080:8080\-v /opt/config/application-prod.yml:/app/config/application.yml:ro\-v /opt/logs:/app/logs\my-java-app:1.0.0

5.3 JVM 参数优化

# Dockerfile FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY target/*.jar app.jar # 容器环境 JVM 优化参数 ENV JAVA_OPTS="\ -XX:+UseContainerSupport \ -XX:MaxRAMPercentage=75.0 \ -XX:InitialRAMPercentage=50.0 \ -XX:+UseG1GC \ -XX:MaxGCPauseMillis=100 \ -XX:+UseStringDeduplication \ -Djava.security.egd=file:/dev/./urandom \ -Dfile.encoding=UTF-8" EXPOSE 8080 ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

5.4 时区配置

FROM eclipse-temurin:17-jre-alpine # 设置时区为中国 ENV TZ=Asia/Shanghai RUN apk add --no-cache tzdata && \ ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ echo $TZ > /etc/timezone WORKDIR /app COPY target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]

6. 使用 Docker Compose

6.1 基础配置

# docker-compose.ymlversion:'3.8'services:app:build:context:.dockerfile:Dockerfileimage:my-java-app:1.0.0container_name:my-java-appports:-"8080:8080"environment:-SPRING_PROFILES_ACTIVE=prod-TZ=Asia/Shanghaivolumes:-./logs:/app/logsrestart:unless-stoppedhealthcheck:test:["CMD","wget","-q","--spider","http://localhost:8080/health"]interval:30stimeout:10sretries:3start_period:60s

6.2 完整微服务配置

# docker-compose.ymlversion:'3.8'services:# Java 应用app:build:.image:my-java-app:1.0.0container_name:my-java-appports:-"8080:8080"environment:-SPRING_PROFILES_ACTIVE=prod-DATABASE_URL=jdbc:mysql://mysql:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai-DATABASE_USER=root-DATABASE_PASSWORD=rootpassword-REDIS_HOST=redis-REDIS_PORT=6379volumes:-app-logs:/app/logsdepends_on:mysql:condition:service_healthyredis:condition:service_startednetworks:-app-networkrestart:unless-stoppeddeploy:resources:limits:cpus:'1.0'memory:512M# MySQL 数据库mysql:image:mysql:8.0container_name:my-mysqlenvironment:-MYSQL_ROOT_PASSWORD=rootpassword-MYSQL_DATABASE=mydb-TZ=Asia/Shanghaivolumes:-mysql-data:/var/lib/mysql-./init.sql:/docker-entrypoint-initdb.d/init.sql:roports:-"3306:3306"networks:-app-networkhealthcheck:test:["CMD","mysqladmin","ping","-h","localhost"]interval:10stimeout:5sretries:5restart:unless-stopped# Redis 缓存redis:image:redis:7-alpinecontainer_name:my-redisports:-"6379:6379"volumes:-redis-data:/datanetworks:-app-networkrestart:unless-stopped# Nginx 反向代理nginx:image:nginx:alpinecontainer_name:my-nginxports:-"80:80"-"443:443"volumes:-./nginx.conf:/etc/nginx/nginx.conf:ro-./ssl:/etc/nginx/ssl:rodepends_on:-appnetworks:-app-networkrestart:unless-stoppednetworks:app-network:driver:bridgevolumes:app-logs:mysql-data:redis-data:

6.3 Docker Compose 常用命令

# 启动所有服务docker-compose up -d# 查看服务状态docker-composeps# 查看服务日志docker-compose logs -f app# 重新构建并启动docker-compose up -d --build# 停止所有服务docker-compose down# 停止并删除数据卷docker-compose down -v# 重启单个服务docker-compose restart app# 扩展服务实例docker-compose up -d --scaleapp=3

7. 最佳实践

7.1 Dockerfile 最佳实践

# ✅ 最佳实践示例 FROM eclipse-temurin:17-jre-alpine # 1. 使用标签 LABEL maintainer="dev@example.com" \ version="1.0.0" \ description="Production Java Application" # 2. 创建非 root 用户 RUN addgroup -S appgroup && adduser -S appuser -G appgroup # 3. 设置工作目录 WORKDIR /app # 4. 最小化层数,清理缓存 RUN apk add --no-cache tzdata curl && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone && \ apk del tzdata # 5. 复制文件并设置权限 COPY --chown=appuser:appgroup target/*.jar app.jar # 6. 切换用户 USER appuser # 7. 设置健康检查 HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1 # 8. 暴露端口 EXPOSE 8080 # 9. 使用 ENTRYPOINT ENTRYPOINT ["java", \ "-XX:+UseContainerSupport", \ "-XX:MaxRAMPercentage=75.0", \ "-jar", "app.jar"]

7.2 安全最佳实践

┌─────────────────────────────────────────────────────────────────┐ │ Docker 安全最佳实践 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ✅ 使用非 root 用户运行应用 │ │ ✅ 使用最小化基础镜像 (alpine) │ │ ✅ 定期更新基础镜像 │ │ ✅ 扫描镜像漏洞 (Trivy, Snyk) │ │ ✅ 不在镜像中存储敏感信息 │ │ ✅ 使用 secrets 管理敏感数据 │ │ ✅ 限制容器资源使用 │ │ ✅ 只暴露必要端口 │ │ ✅ 使用只读文件系统 (--read-only) │ │ │ └─────────────────────────────────────────────────────────────────┘

7.3 镜像优化清单

# 1. 使用多阶段构建减少镜像大小# 2. 使用 .dockerignore 排除无关文件# .dockerignore.git .gitignore README.md .idea *.iml target/!target/*.jar node_modules *.log docker-compose*.yml

8. 常见问题排查

8.1 问题排查命令

# 查看容器日志docker logs my-app# 实时查看日志docker logs -f my-app# 进入容器调试dockerexec-it my-app /bin/sh# 查看容器进程dockertopmy-app# 查看容器资源使用docker stats my-app# 检查容器详细信息docker inspect my-app# 查看容器文件系统变化dockerdiffmy-app

8.2 常见问题与解决方案

┌─────────────────────────────────────────────────────────────────┐ │ 常见问题排查 │ ├────────────────────────┬────────────────────────────────────────┤ │ 问题 │ 解决方案 │ ├────────────────────────┼────────────────────────────────────────┤ │ OOM (内存不足) │ 增加 --memory 限制 │ │ │ 调整 JVM 参数 -Xmx │ ├────────────────────────┼────────────────────────────────────────┤ │ 容器启动后立即退出 │ 检查 ENTRYPOINT/CMD │ │ │ 查看 docker logs │ ├────────────────────────┼────────────────────────────────────────┤ │ 端口无法访问 │ 检查端口映射 -p │ │ │ 检查防火墙设置 │ ├────────────────────────┼────────────────────────────────────────┤ │ 时区不正确 │ 设置 TZ 环境变量 │ │ │ 挂载时区文件 │ ├────────────────────────┼────────────────────────────────────────┤ │ 中文乱码 │ 设置 LANG=C.UTF-8 │ │ │ 安装字体包 │ ├────────────────────────┼────────────────────────────────────────┤ │ 无法连接数据库 │ 检查网络配置 │ │ │ 使用容器名作为主机名 │ └────────────────────────┴────────────────────────────────────────┘

8.3 性能监控

# 实时监控资源使用docker stats# 使用 jps 查看 Java 进程dockerexecmy-app jps -l# 查看 JVM 堆内存使用dockerexecmy-app jmap -heap<PID># 导出堆转储文件dockerexecmy-app jmap -dump:format=b,file=/tmp/heap.hprof<PID>dockercpmy-app:/tmp/heap.hprof ./heap.hprof

📝 总结

┌─────────────────────────────────────────────────────────────────┐ │ Docker 部署 Java 应用流程 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. 准备阶段 │ │ └── 打包 JAR 文件 (mvn package) │ │ │ │ 2. 容器化阶段 │ │ ├── 编写 Dockerfile │ │ ├── 构建镜像 (docker build) │ │ └── 测试运行 (docker run) │ │ │ │ 3. 部署阶段 │ │ ├── 推送镜像到仓库 (docker push) │ │ ├── 拉取镜像 (docker pull) │ │ └── 运行容器 (docker-compose up) │ │ │ │ 4. 运维阶段 │ │ ├── 日志监控 (docker logs) │ │ ├── 性能监控 (docker stats) │ │ └── 故障排查 (docker exec) │ │ │ └─────────────────────────────────────────────────────────────────┘

快速参考命令

# 完整工作流mvn clean package -DskipTests# 1. 打包docker build -t my-app:1.0.0.# 2. 构建镜像docker run -d -p8080:8080 my-app:1.0.0# 3. 运行容器curlhttp://localhost:8080/hello# 4. 验证docker logs -f<container-id># 5. 查看日志
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/30 18:45:04

【气象预测Agent模型更新全攻略】:揭秘高效迭代背后的三大核心技术

第一章&#xff1a;气象预测Agent模型更新概述 随着人工智能在气象科学中的深度应用&#xff0c;基于Agent的预测模型正经历快速迭代。新一代气象预测Agent不仅融合了多源观测数据与数值天气预报输出&#xff0c;还引入了自适应学习机制&#xff0c;以动态优化预测精度。这些智…

作者头像 李华
网站建设 2026/3/27 10:00:40

终极Web条码解决方案:ZXing.js如何重塑JavaScript条码处理生态

终极Web条码解决方案&#xff1a;ZXing.js如何重塑JavaScript条码处理生态 【免费下载链接】library Multi-format 1D/2D barcode image processing library, usable in JavaScript ecosystem. 项目地址: https://gitcode.com/gh_mirrors/lib/library 在数字化转型浪潮中…

作者头像 李华
网站建设 2026/3/31 23:30:00

Kotaemon Google Cloud Vertex AI 集成方案

Kotaemon 与 Google Cloud Vertex AI 集成方案&#xff1a;构建生产级智能对话系统 在企业智能化转型的浪潮中&#xff0c;一个常见的挑战浮出水面&#xff1a;如何让 AI 助手不仅能“说话”&#xff0c;还能说“对的话”&#xff1f;传统聊天机器人依赖预设规则和静态知识库&a…

作者头像 李华
网站建设 2026/4/3 0:01:01

Layui-Admin:企业级后台管理系统的快速开发实践

Layui-Admin&#xff1a;企业级后台管理系统的快速开发实践 【免费下载链接】Layui-admin 一个现成的 LayuiVue的后台系统模板&#xff0c;开箱即用 项目地址: https://gitcode.com/gh_mirrors/layu/Layui-admin 在数字化转型的浪潮中&#xff0c;企业普遍面临后台管理系…

作者头像 李华
网站建设 2026/3/11 20:42:24

高效组网解决方案

需求背景客户为达成系统与数据的统一管理&#xff0c;推动分支机构轻量化、低成本运维&#xff0c;正逐步将各系统集中部署至总部&#xff0c;以实现数据集中与集中运维的 IT 管理目标。在系统与数据集中的过程中&#xff0c;首要挑战是解决分支与总部间长距离&#xff08;跨省…

作者头像 李华
网站建设 2026/3/27 15:00:38

Apache SeaTunnel Web:如何零基础构建企业级数据集成平台?

Apache SeaTunnel Web&#xff1a;如何零基础构建企业级数据集成平台&#xff1f; 【免费下载链接】seatunnel-web SeaTunnel is a distributed, high-performance data integration platform for the synchronization and transformation of massive data (offline & real…

作者头像 李华