在Docker中运行Java JAR包的实战教程
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 前言与环境准备</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1.1 为什么使用 Docker 运行 Java 应用?</a></li><li><a href="#_lab2_0_1">1.2 环境准备</a></li><li><a href="#_lab2_0_2">1.3 项目结构</a></li></ul><li><a href="#_label1">2. 准备 Java 项目</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_3">2.1 示例 Spring Boot 应用</a></li><li><a href="#_lab2_1_4">2.2 Maven 打包配置</a></li><li><a href="#_lab2_1_5">2.3 打包 JAR 文件</a></li></ul><li><a href="#_label2">3. 编写 Dockerfile</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_6">3.1 基础版 Dockerfile</a></li><li><a href="#_lab2_2_7">3.2 优化版 Dockerfile(推荐)</a></li><li><a href="#_lab2_2_8">3.3 不同 JDK 版本选择</a></li><li><a href="#_lab2_2_9">3.4 镜像大小对比</a></li></ul><li><a href="#_label3">4. 构建与运行镜像</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_10">4.1 构建 Docker 镜像</a></li><li><a href="#_lab2_3_11">4.2 查看镜像信息</a></li><li><a href="#_lab2_3_12">4.3 运行容器</a></li><li><a href="#_lab2_3_13">4.4 运行参数说明</a></li><li><a href="#_lab2_3_14">4.5 验证运行状态</a></li></ul><li><a href="#_label4">5. 进阶配置</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_15">5.1 多环境配置</a></li><li><a href="#_lab2_4_16">5.2 配置文件外置</a></li><li><a href="#_lab2_4_17">5.3 JVM 参数优化</a></li><li><a href="#_lab2_4_18">5.4 时区配置</a></li></ul><li><a href="#_label5">6. 使用 Docker Compose</a></li><ul class="second_class_ul"><li><a href="#_lab2_5_19">6.1 基础配置</a></li><li><a href="#_lab2_5_20">6.2 完整微服务配置</a></li><li><a href="#_lab2_5_21">6.3 Docker Compose 常用命令</a></li></ul><li><a href="#_label6">7. 最佳实践</a></li><ul class="second_class_ul"><li><a href="#_lab2_6_22">7.1 Dockerfile 最佳实践</a></li><li><a href="#_lab2_6_23">7.2 安全最佳实践</a></li><li><a href="#_lab2_6_24">7.3 镜像优化清单</a></li></ul><li><a href="#_label7">8. 常见问题排查</a></li><ul class="second_class_ul"><li><a href="#_lab2_7_25">8.1 问题排查命令</a></li><li><a href="#_lab2_7_26">8.2 常见问题与解决方案</a></li><li><a href="#_lab2_7_27">8.3 性能监控</a></li></ul><li><a href="#_label8">📝 总结</a></li><ul class="second_class_ul"><li><a href="#_lab2_8_28">快速参考命令</a></li></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>1. 前言与环境准备</h2><p class="maodian"><a name="_lab2_0_0"></a></p><h3>1.1 为什么使用 Docker 运行 Java 应用?</h3>
<div class="jb51code"><pre class="brush:bash;">┌─────────────────────────────────────────────────────────────────┐
│ 传统部署 vs Docker 部署 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 传统部署: Docker 部署: │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ App.jar │ │Container│ │
│ ├─────────────┤ │ ┌─────────┐ │ │
│ │ JDK 8 │──────► │ │ App.jar │ │ │
│ ├─────────────┤ │ ├─────────┤ │ │
│ │ CentOS │ │ │ JDK │ │ │
│ └─────────────┘ │ ├─────────┤ │ │
│ │ │Linux│ │ │
│ ❌ 环境不一致 │ └─────────┘ │ │
│ ❌ 依赖冲突 └─────────────┘ │
│ ❌ 部署复杂 │
│ ✅ 环境一致 │
│ ✅ 隔离性好 │
│ ✅ 快速部署 │
└─────────────────────────────────────────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>1.2 环境准备</h3>
<div class="jb51code"><pre class="brush:bash;"># 检查 Docker 是否安装
docker --version
# Docker version 24.0.0, build xxxxx
# 检查 Docker 服务状态
systemctl status docker
# 如未安装,执行以下命令(以 CentOS 为例)
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker
</pre></div>
<p class="maodian"><a name="_lab2_0_2"></a></p><h3>1.3 项目结构</h3>
<div class="jb51code"><pre class="brush:bash;">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
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>2. 准备 Java 项目</h2>
<p class="maodian"><a name="_lab2_1_3"></a></p><h3>2.1 示例 Spring Boot 应用</h3>
<div class="jb51code"><pre class="brush:java;">// Application.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/hello")
public String hello() {
return "Hello from Docker! 🐳";
}
@GetMapping("/health")
public String health() {
return "OK";
}
}
</pre></div>
<p class="maodian"><a name="_lab2_1_4"></a></p><h3>2.2 Maven 打包配置</h3>
<div class="jb51code"><pre class="brush:xml;"><!-- 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>
</pre></div>
<p class="maodian"><a name="_lab2_1_5"></a></p><h3>2.3 打包 JAR 文件</h3>
<div class="jb51code"><pre class="brush:bash;"># 使用 Maven 打包
mvn clean package -DskipTests
# 验证 JAR 文件
ls -lh target/my-app.jar
# 本地测试运行
java -jar target/my-app.jar
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>3. 编写 Dockerfile</h2>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>3.1 基础版 Dockerfile</h3>
<div class="jb51code"><pre class="brush:bash;"># 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"]
</pre></div>
<p class="maodian"><a name="_lab2_2_7"></a></p><h3>3.2 优化版 Dockerfile(推荐)</h3>
<div class="jb51code"><pre class="brush:bash;"># 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"]
</pre></div>
<p class="maodian"><a name="_lab2_2_8"></a></p><h3>3.3 不同 JDK 版本选择</h3>
<div class="jb51code"><pre class="brush:bash;"># ============ 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
</pre></div>
<p class="maodian"><a name="_lab2_2_9"></a></p><h3>3.4 镜像大小对比</h3>
<div class="jb51code"><pre class="brush:bash;">┌─────────────────────────────────────────────────────────────┐
│ 镜像大小对比 │
├─────────────────────────────┬───────────────────────────────┤
│基础镜像 │大小 │
├─────────────────────────────┼───────────────────────────────┤
│openjdk:8 │~500MB │
│openjdk:8-jdk-alpine │~105MB │
│openjdk:8-jre-alpine │~85MB ⭐ 推荐 │
│eclipse-temurin:17-jre │~260MB │
│eclipse-temurin:17-jre-alpine │ ~180MB │
└─────────────────────────────┴───────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>4. 构建与运行镜像</h2>
<p class="maodian"><a name="_lab2_3_10"></a></p><h3>4.1 构建 Docker 镜像</h3>
<div class="jb51code"><pre class="brush:bash;"># 基本构建命令
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-arg JAR_FILE=target/my-app.jar \
-t my-java-app:1.0.0 .
</pre></div>
<p class="maodian"><a name="_lab2_3_11"></a></p><h3>4.2 查看镜像信息</h3>
<div class="jb51code"><pre class="brush:bash;"># 列出所有镜像
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
# 查看镜像历史层
docker history my-java-app:1.0.0
</pre></div>
<p class="maodian"><a name="_lab2_3_12"></a></p><h3>4.3 运行容器</h3>
<div class="jb51code"><pre class="brush:bash;"># 基本运行
docker run -d -p 8080:8080 --name my-app my-java-app:1.0.0
# 带环境变量运行
docker run -d \
-p 8080:8080 \
--name my-app \
-e SPRING_PROFILES_ACTIVE=prod \
-e DATABASE_URL=jdbc:mysql://db:3306/mydb \
my-java-app:1.0.0
# 带资源限制运行
docker run -d \
-p 8080:8080 \
--name my-app \
--memory=512m \
--cpus=1.0 \
my-java-app:1.0.0
# 完整运行命令
docker run -d \
--name my-app \
-p 8080:8080 \
-v /host/logs:/app/logs \
-v /host/config:/app/config:ro \
-e JAVA_OPTS="-Xms256m -Xmx512m" \
-e SPRING_PROFILES_ACTIVE=prod \
--memory=512m \
--cpus=1.0 \
--restart=unless-stopped \
my-java-app:1.0.0
</pre></div>
<p class="maodian"><a name="_lab2_3_13"></a></p><h3>4.4 运行参数说明</h3>
<div class="jb51code"><pre class="brush:bash;">┌──────────────────────────────────────────────────────────────────┐
│ 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 │指定网络 │
└────────────────────┴─────────────────────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_lab2_3_14"></a></p><h3>4.5 验证运行状态</h3>
<div class="jb51code"><pre class="brush:bash;"># 查看运行中的容器
docker ps
# 查看容器日志
docker logs -f my-app
# 查看最近 100 行日志
docker logs --tail 100 my-app
# 进入容器内部
docker exec -it my-app /bin/sh
# 测试应用
curl http://localhost:8080/hello
# 输出: Hello from Docker! 🐳
# 查看容器资源使用
docker stats my-app
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>5. 进阶配置</h2>
<p class="maodian"><a name="_lab2_4_15"></a></p><h3>5.1 多环境配置</h3>
<div class="jb51code"><pre class="brush:bash;"># 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"]
</pre></div>
<div class="jb51code"><pre class="brush:bash;"># 构建不同环境的镜像
docker build --build-arg PROFILE=dev -t my-app:dev .
docker build --build-arg PROFILE=prod -t my-app:prod .
</pre></div>
<p class="maodian"><a name="_lab2_4_16"></a></p><h3>5.2 配置文件外置</h3>
<div class="jb51code"><pre class="brush:yaml;"># application.yml
server:
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
</pre></div>
<div class="jb51code"><pre class="brush:bash;"># 运行时挂载外部配置
docker run -d \
-p 8080:8080 \
-v /opt/config/application-prod.yml:/app/config/application.yml:ro \
-v /opt/logs:/app/logs \
my-java-app:1.0.0
</pre></div>
<p class="maodian"><a name="_lab2_4_17"></a></p><h3>5.3 JVM 参数优化</h3>
<div class="jb51code"><pre class="brush:bash;"># 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"]
</pre></div>
<p class="maodian"><a name="_lab2_4_18"></a></p><h3>5.4 时区配置</h3>
<div class="jb51code"><pre class="brush:bash;">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"]
</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>6. 使用 Docker Compose</h2>
<p class="maodian"><a name="_lab2_5_19"></a></p><h3>6.1 基础配置</h3>
<div class="jb51code"><pre class="brush:yaml;"># docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: my-java-app:1.0.0
container_name: my-java-app
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- TZ=Asia/Shanghai
volumes:
- ./logs:/app/logs
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
</pre></div>
<p class="maodian"><a name="_lab2_5_20"></a></p><h3>6.2 完整微服务配置</h3>
<div class="jb51code"><pre class="brush:yaml;"># docker-compose.yml
version: '3.8'
services:
# Java 应用
app:
build: .
image: my-java-app:1.0.0
container_name: my-java-app
ports:
- "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=6379
volumes:
- app-logs:/app/logs
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
networks:
- app-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
# MySQL 数据库
mysql:
image: mysql:8.0
container_name: my-mysql
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=mydb
- TZ=Asia/Shanghai
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
ports:
- "3306:3306"
networks:
- app-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# Redis 缓存
redis:
image: redis:7-alpine
container_name: my-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- app-network
restart: unless-stopped
# Nginx 反向代理
nginx:
image: nginx:alpine
container_name: my-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
networks:
- app-network
restart: unless-stopped
networks:
app-network:
driver: bridge
volumes:
app-logs:
mysql-data:
redis-data:
</pre></div>
<p class="maodian"><a name="_lab2_5_21"></a></p><h3>6.3 Docker Compose 常用命令</h3>
<div class="jb51code"><pre class="brush:bash;"># 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
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 --scale app=3
</pre></div>
<p class="maodian"><a name="_label6"></a></p><h2>7. 最佳实践</h2>
<p class="maodian"><a name="_lab2_6_22"></a></p><h3>7.1 Dockerfile 最佳实践</h3>
<div class="jb51code"><pre class="brush:bash;"># ✅ 最佳实践示例
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"]
</pre></div>
<p class="maodian"><a name="_lab2_6_23"></a></p><h3>7.2 安全最佳实践</h3>
<div class="jb51code"><pre class="brush:bash;">┌─────────────────────────────────────────────────────────────────┐
│ Docker 安全最佳实践 │
├─────────────────────────────────────────────────────────────────┤
│ │
│✅ 使用非 root 用户运行应用 │
│✅ 使用最小化基础镜像 (alpine) │
│✅ 定期更新基础镜像 │
│✅ 扫描镜像漏洞 (Trivy, Snyk) │
│✅ 不在镜像中存储敏感信息 │
│✅ 使用 secrets 管理敏感数据 │
│✅ 限制容器资源使用 │
│✅ 只暴露必要端口 │
│✅ 使用只读文件系统 (--read-only) │
│ │
└─────────────────────────────────────────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_lab2_6_24"></a></p><h3>7.3 镜像优化清单</h3>
<div class="jb51code"><pre class="brush:bash;"># 1. 使用多阶段构建减少镜像大小
# 2. 使用 .dockerignore 排除无关文件
# .dockerignore
.git
.gitignore
README.md
.idea
*.iml
target/
!target/*.jar
node_modules
*.log
docker-compose*.yml
</pre></div>
<p class="maodian"><a name="_label7"></a></p><h2>8. 常见问题排查</h2>
<p class="maodian"><a name="_lab2_7_25"></a></p><h3>8.1 问题排查命令</h3>
<div class="jb51code"><pre class="brush:bash;"># 查看容器日志
docker logs my-app
# 实时查看日志
docker logs -f my-app
# 进入容器调试
docker exec -it my-app /bin/sh
# 查看容器进程
docker top my-app
# 查看容器资源使用
docker stats my-app
# 检查容器详细信息
docker inspect my-app
# 查看容器文件系统变化
docker diff my-app
</pre></div>
<p class="maodian"><a name="_lab2_7_26"></a></p><h3>8.2 常见问题与解决方案</h3>
<div class="jb51code"><pre class="brush:bash;">┌─────────────────────────────────────────────────────────────────┐
│ 常见问题排查 │
├────────────────────────┬────────────────────────────────────────┤
│问题 │解决方案 │
├────────────────────────┼────────────────────────────────────────┤
│OOM (内存不足) │增加 --memory 限制 │
│ │调整 JVM 参数 -Xmx │
├────────────────────────┼────────────────────────────────────────┤
│容器启动后立即退出 │检查 ENTRYPOINT/CMD │
│ │查看 docker logs │
├────────────────────────┼────────────────────────────────────────┤
│端口无法访问 │检查端口映射 -p │
│ │检查防火墙设置 │
├────────────────────────┼────────────────────────────────────────┤
│时区不正确 │设置 TZ 环境变量 │
│ │挂载时区文件 │
├────────────────────────┼────────────────────────────────────────┤
│中文乱码 │设置 LANG=C.UTF-8 │
│ │安装字体包 │
├────────────────────────┼────────────────────────────────────────┤
│无法连接数据库 │检查网络配置 │
│ │使用容器名作为主机名 │
└────────────────────────┴────────────────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_lab2_7_27"></a></p><h3>8.3 性能监控</h3>
<div class="jb51code"><pre class="brush:bash;"># 实时监控资源使用
docker stats
# 使用 jps 查看 Java 进程
docker exec my-app jps -l
# 查看 JVM 堆内存使用
docker exec my-app jmap -heap <PID>
# 导出堆转储文件
docker exec my-app jmap -dump:format=b,file=/tmp/heap.hprof <PID>
docker cp my-app:/tmp/heap.hprof ./heap.hprof
</pre></div>
<p class="maodian"><a name="_label8"></a></p><h2>📝 总结</h2>
<div class="jb51code"><pre class="brush:bash;">┌─────────────────────────────────────────────────────────────────┐
│ 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) │
│ │
└─────────────────────────────────────────────────────────────────┘
</pre></div>
<p class="maodian"><a name="_lab2_8_28"></a></p><h3>快速参考命令</h3>
<div class="jb51code"><pre class="brush:bash;"># 完整工作流
mvn clean package -DskipTests # 1. 打包
docker build -t my-app:1.0.0 . # 2. 构建镜像
docker run -d -p 8080:8080 my-app:1.0.0 # 3. 运行容器
curl http://localhost:8080/hello # 4. 验证
docker logs -f <container-id> # 5. 查看日志
</pre></div>
<p>以上就是在Docker中运行Java JAR包的实战教程的详细内容,更多关于Docker运行Java JAR包的资料请关注琼殿技术社区其它相关文章!</p>
頁:
[1]