news 2026/4/15 1:32:50

在 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/4/14 10:37:27

抖音内容高效管理工具:douyin-downloader全方位使用手册

在数字化内容创作的时代&#xff0c;抖音已经成为内容创作者、营销人员和研究者的重要资源平台。然而&#xff0c;面对海量的优质内容&#xff0c;如何高效地保存、管理和分析这些资源成为了一个普遍痛点。今天&#xff0c;让我们一起来探索这款专业的抖音内容批量下载工具——…

作者头像 李华
网站建设 2026/4/12 20:45:02

Tesseract OCR 完全指南:从零开始掌握开源文字识别技术

Tesseract OCR 完全指南&#xff1a;从零开始掌握开源文字识别技术 【免费下载链接】tesseract Tesseract Open Source OCR Engine (main repository) 项目地址: https://gitcode.com/gh_mirrors/tes/tesseract Tesseract OCR 是一款功能强大的开源光学字符识别引擎&…

作者头像 李华
网站建设 2026/4/15 9:11:37

2025年GEO服务商优质推荐:综合实力+垂直领域实测,选型避坑必看

权威第三方机构Gartner预测&#xff0c;截至2026年全球传统搜索引擎访问量将下滑25%&#xff0c;近四分之一的搜索流量将加速向AI聊天机器人、智能问答助手等新兴载体迁移&#xff08;来源&#xff1a;第一财经&#xff09;。这一趋势直接推动GEO&#xff08;生成式引擎优化&am…

作者头像 李华
网站建设 2026/4/11 4:01:45

三步打造企业级智能对话系统:从零部署到实战应用

三步打造企业级智能对话系统&#xff1a;从零部署到实战应用 【免费下载链接】kimi-free-api &#x1f680; KIMI AI 长文本大模型白嫖服务&#xff0c;支持高速流式输出、联网搜索、长文档解读、图像解析、多轮对话&#xff0c;零配置部署&#xff0c;多路token支持&#xff0…

作者头像 李华
网站建设 2026/4/13 14:15:22

Kotaemon临床指南问答:医生辅助决策工具开发

Kotaemon临床指南问答&#xff1a;医生辅助决策工具开发 在三甲医院的早交班现场&#xff0c;一位年轻医生正为是否给慢性心衰患者加用ARNI类药物犹豫不决——患者肾功能轻度下降&#xff0c;血压偏低&#xff0c;最新指南推荐与个体风险之间如何权衡&#xff1f;如果此时他的电…

作者头像 李华
网站建设 2026/4/13 12:16:04

My Mind 思维导图:释放创意潜能的全新方式

My Mind 思维导图&#xff1a;释放创意潜能的全新方式 【免费下载链接】my-mind Online Mindmapping Software 项目地址: https://gitcode.com/gh_mirrors/my/my-mind 在数字化时代&#xff0c;思维管理变得前所未有的重要。My Mind作为一款精心设计的在线思维导图工具&…

作者头像 李华