贷后资料部 發表於 2025-12-19 08:33:02

在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;">&lt;!-- pom.xml --&gt;
&lt;project&gt;
    &lt;groupId&gt;com.example&lt;/groupId&gt;
    &lt;artifactId&gt;my-app&lt;/artifactId&gt;
    &lt;version&gt;1.0.0&lt;/version&gt;
    &lt;packaging&gt;jar&lt;/packaging&gt;
   
    &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
      &lt;version&gt;2.7.0&lt;/version&gt;
    &lt;/parent&gt;
   
    &lt;dependencies&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
   
    &lt;build&gt;
      &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
      &lt;/plugins&gt;
      &lt;!-- 指定打包后的文件名 --&gt;
      &lt;finalName&gt;my-app&lt;/finalName&gt;
    &lt;/build&gt;
&lt;/project&gt;
</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 &amp;&amp; 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 &amp;&amp; \
    ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &amp;&amp; \
    echo $TZ &gt; /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&amp;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 &amp;&amp; adduser -S appuser -G appgroup

# 3. 设置工作目录
WORKDIR /app

# 4. 最小化层数,清理缓存
RUN apk add --no-cache tzdata curl &amp;&amp; \
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &amp;&amp; \
    echo "Asia/Shanghai" &gt; /etc/timezone &amp;&amp; \
    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 &lt;PID&gt;

# 导出堆转储文件
docker exec my-app jmap -dump:format=b,file=/tmp/heap.hprof &lt;PID&gt;
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 &lt;container-id&gt;                     # 5. 查看日志
</pre></div>
<p>以上就是在Docker中运行Java JAR包的实战教程的详细内容,更多关于Docker运行Java JAR包的资料请关注琼殿技术社区其它相关文章!</p>
頁: [1]
查看完整版本: 在Docker中运行Java JAR包的实战教程