欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java項(xiàng)目打包Docker鏡像全流程

 更新時(shí)間:2025年04月10日 09:58:45   作者:魔道不誤砍柴功  
本文是一份超詳細(xì)的Java項(xiàng)目Docker化實(shí)戰(zhàn)手冊(cè),從環(huán)境準(zhǔn)備到最終上線,手把手帶你完成整個(gè)容器化部署流程,無(wú)論你是剛接觸Docker的新手,還是想系統(tǒng)梳理容器化流程的開(kāi)發(fā)者,這篇文章都能給你帶來(lái)實(shí)實(shí)在在的幫助,需要的朋友可以參考下

環(huán)境準(zhǔn)備

1. 開(kāi)發(fā)環(huán)境要求

  • JDK 8+ (推薦JDK 11/17 LTS版本)
  • Maven 3.6+ 或 Gradle 7+
  • Docker Desktop (Mac/Windows) 或 Docker Engine (Linux)
  • 推薦IDE: IntelliJ IDEA (社區(qū)版即可)

2. 安裝Docker

不同操作系統(tǒng)的安裝方式:

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

# 設(shè)置穩(wěn)定版?zhèn)}庫(kù)
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

# 驗(yàn)證安裝
sudo docker run hello-world

Mac/Windows:直接下載Docker Desktop安裝包:
https://www.docker.com/products/docker-desktop

3. 驗(yàn)證安裝

docker --version
# 輸出類似: Docker version 20.10.12, build e91ed57

docker-compose --version
# 輸出類似: docker-compose version 1.29.2, build 5becea4c

項(xiàng)目結(jié)構(gòu)說(shuō)明

我們以一個(gè)典型的Spring Boot項(xiàng)目為例:

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基礎(chǔ)概念

在開(kāi)始之前,先了解幾個(gè)核心概念:

  • 鏡像(Image): 只讀模板,包含運(yùn)行應(yīng)用所需的所有內(nèi)容
  • 容器(Container): 鏡像的運(yùn)行實(shí)例
  • Dockerfile: 構(gòu)建鏡像的指令文件
  • Registry: 鏡像倉(cāng)庫(kù)(如Docker Hub)

Docker的優(yōu)勢(shì):

  • 一致的運(yùn)行環(huán)境
  • 快速部署和擴(kuò)展
  • 資源隔離
  • 易于版本管理和回滾

編寫(xiě)Dockerfile

基礎(chǔ)Dockerfile示例

# 第一階段:構(gòu)建
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

# 第二階段:運(yùn)行
FROM openjdk:11-jre-slim
WORKDIR /app
# 從構(gòu)建階段復(fù)制jar包
COPY --from=build /app/target/my-java-app-*.jar app.jar
# 暴露端口
EXPOSE 8080
# 啟動(dòng)命令
ENTRYPOINT ["java", "-jar", "app.jar"]

逐行解析

  1. FROM maven:3.8.4-openjdk-11 AS build
    使用Maven鏡像作為構(gòu)建階段的基礎(chǔ)鏡像,并命名為"build"

  2. WORKDIR /app
    設(shè)置工作目錄為/app

  3. COPY pom.xml .
    復(fù)制pom.xml到工作目錄

  4. RUN mvn dependency:go-offline
    下載所有依賴項(xiàng)(利用Docker緩存層)

  5. COPY src ./src
    復(fù)制源代碼

  6. RUN mvn package -DskipTests
    打包應(yīng)用(跳過(guò)測(cè)試)

  7. FROM openjdk:11-jre-slim
    第二階段使用更小的JRE鏡像

  8. COPY --from=build /app/target/my-java-app-*.jar app.jar
    從構(gòu)建階段復(fù)制生成的jar包

  9. EXPOSE 8080
    聲明容器暴露的端口

  10. ENTRYPOINT ["java", "-jar", "app.jar"]
    容器啟動(dòng)時(shí)執(zhí)行的命令

多階段構(gòu)建優(yōu)化

多階段構(gòu)建有三大優(yōu)勢(shì):

  1. 減小鏡像體積 - 最終鏡像只包含運(yùn)行時(shí)必要內(nèi)容
  2. 提高安全性 - 構(gòu)建工具不會(huì)出現(xiàn)在生產(chǎn)鏡像中
  3. 更清晰的構(gòu)建流程 - 分離構(gòu)建和運(yùn)行環(huán)境

進(jìn)階優(yōu)化技巧

  1. 使用.dockerignore文件
    避免將不必要的文件復(fù)制到鏡像中:

.git
.idea
*.iml
target/
*.log
*.tmp
  1. 選擇合適的基礎(chǔ)鏡像

    • openjdk:11-jdk - 完整JDK(較大)
    • openjdk:11-jre - 僅運(yùn)行時(shí)(較小)
    • openjdk:11-jre-slim - 更精簡(jiǎn)版本
    • openjdk:11-alpine - 基于Alpine Linux(最小)
  2. 層緩存優(yōu)化
    將不常變化的指令放在前面,充分利用緩存:

# 先復(fù)制pom.xml并下載依賴
COPY pom.xml .
RUN mvn dependency:go-offline

# 然后復(fù)制源代碼
COPY src ./src

構(gòu)建與運(yùn)行鏡像

1. 構(gòu)建鏡像

# -t 指定鏡像名稱和標(biāo)簽
# . 表示使用當(dāng)前目錄的Dockerfile
docker build -t my-java-app:1.0 .

構(gòu)建過(guò)程輸出示例:

[+] 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. 運(yùn)行容器

# -d 后臺(tái)運(yùn)行
# -p 端口映射(主機(jī)端口:容器端口)
# --name 容器名稱
docker run -d -p 8080:8080 --name my-app my-java-app:1.0

4. 查看運(yùn)行狀態(tài)

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

推送鏡像到倉(cāng)庫(kù)

1. 登錄Docker Hub

docker login -u your-username

2. 標(biāo)記鏡像

# 格式: 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. 從倉(cāng)庫(kù)拉取運(yùn)行

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

生產(chǎn)環(huán)境部署

1. 使用docker-compose

創(chuàng)建docker-compose.yml文件:

version: '3.8'

services:
  app:
    image: your-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

啟動(dòng)服務(wù):

docker-compose up -d

2. Kubernetes部署示例

創(chuàng)建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: "500m"
            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

總結(jié)與最佳實(shí)踐

最佳實(shí)踐總結(jié)

  1. 鏡像優(yōu)化

    • 使用多階段構(gòu)建減小鏡像體積
    • 選擇合適的基礎(chǔ)鏡像(Alpine/slim版本)
    • 定期更新基礎(chǔ)鏡像以獲取安全補(bǔ)丁
  2. 構(gòu)建優(yōu)化

    • 合理利用層緩存(.dockerignore + 指令順序)
    • 固定基礎(chǔ)鏡像版本(避免使用latest標(biāo)簽)
    • 在CI/CD中實(shí)現(xiàn)自動(dòng)化構(gòu)建
  3. 運(yùn)行優(yōu)化

    • 限制容器資源(cpu/memory)
    • 配置健康檢查
    • 使用非root用戶運(yùn)行
    • 正確處理信號(hào)(如SIGTERM)
  4. 安全建議

    • 不要將敏感信息硬編碼在鏡像中(使用環(huán)境變量/secret)
    • 掃描鏡像中的漏洞(使用docker scan)
    • 最小化容器權(quán)限(避免–privileged)

常見(jiàn)問(wèn)題解決

Q: 構(gòu)建時(shí)下載依賴很慢怎么辦?
A: 配置Maven鏡像倉(cāng)庫(kù):

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

Q: 容器啟動(dòng)后立即退出?
A: 可能原因:

  1. 應(yīng)用啟動(dòng)失敗 - 查看日志docker logs
  2. 沒(méi)有前臺(tái)進(jìn)程 - 確保應(yīng)用不是以daemon方式運(yùn)行
  3. 端口沖突 - 檢查端口映射

Q: 如何調(diào)試容器內(nèi)的應(yīng)用?
A: 進(jìn)入運(yùn)行中的容器:

docker exec -it  /bin/bash

或者直接附加到進(jìn)程:

docker attach 

下一步學(xué)習(xí)建議

  1. 學(xué)習(xí)Docker網(wǎng)絡(luò)和存儲(chǔ)卷配置
  2. 掌握Docker Compose編排多容器應(yīng)用
  3. 了解Kubernetes容器編排
  4. 探索CI/CD流水線與Docker集成
  5. 學(xué)習(xí)服務(wù)網(wǎng)格(如Istio)與容器化應(yīng)用

通過(guò)本文的學(xué)習(xí),你已經(jīng)掌握了Java項(xiàng)目容器化的核心技能。Docker的世界還有很多值得探索的地方,繼續(xù)實(shí)踐,你將發(fā)現(xiàn)更多容器化帶來(lái)的便利與效率提升!

以上就是Java項(xiàng)目打包Docker鏡像全流程的詳細(xì)內(nèi)容,更多關(guān)于Java打包Docker鏡像的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談java switch如果case后面沒(méi)有break,會(huì)出現(xiàn)什么情況?

    淺談java switch如果case后面沒(méi)有break,會(huì)出現(xiàn)什么情況?

    這篇文章主要介紹了淺談java switch如果case后面沒(méi)有break,會(huì)出現(xiàn)什么情況?具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨想小編過(guò)來(lái)看看吧
    2020-09-09
  • 使用arthas命令redefine實(shí)現(xiàn)Java熱更新(推薦)

    使用arthas命令redefine實(shí)現(xiàn)Java熱更新(推薦)

    今天分享一個(gè)非常重要的命令 redefine ,主要作用是加載外部的 .class 文件,用來(lái)替換 JVM 已經(jīng)加載的類,總結(jié)起來(lái)就是實(shí)現(xiàn)了 Java 的熱更新,感興趣的朋友跟隨小編一起看看吧
    2020-05-05
  • async-excel實(shí)現(xiàn)多sheet異步導(dǎo)出方法詳解

    async-excel實(shí)現(xiàn)多sheet異步導(dǎo)出方法詳解

    這篇文章主要介紹了async-excel實(shí)現(xiàn)多sheet異步導(dǎo)出方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • MyBatis實(shí)現(xiàn)萬(wàn)能Map和模糊查詢

    MyBatis實(shí)現(xiàn)萬(wàn)能Map和模糊查詢

    本文主要介紹了MyBatis實(shí)現(xiàn)萬(wàn)能Map和模糊查詢,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • JMS 之 Active MQ 的消息傳輸(詳解)

    JMS 之 Active MQ 的消息傳輸(詳解)

    下面小編就為大家?guī)?lái)一篇JMS 之 Active MQ 的消息傳輸(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 淺談Java循環(huán)中的For和For-each哪個(gè)更快

    淺談Java循環(huán)中的For和For-each哪個(gè)更快

    本文主要介紹了淺談Java循環(huán)中的For和For-each哪個(gè)更快,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java實(shí)現(xiàn)整合文件上傳到FastDFS的方法詳細(xì)

    Java實(shí)現(xiàn)整合文件上傳到FastDFS的方法詳細(xì)

    FastDFS是一個(gè)開(kāi)源的輕量級(jí)分布式文件系統(tǒng),對(duì)文件進(jìn)行管理,功能包括:文件存儲(chǔ)、文件同步、文件上傳、文件下載等,解決了大容量存儲(chǔ)和負(fù)載均衡的問(wèn)題。本文將提供Java將文件上傳至FastDFS的示例代碼,需要的參考一下
    2022-02-02
  • Java如何把int類型轉(zhuǎn)換成byte

    Java如何把int類型轉(zhuǎn)換成byte

    這篇文章主要介紹了Java如何把int類型轉(zhuǎn)換成byte,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Mysql中備份表的多種方法

    Mysql中備份表的多種方法

    本文給大家分享Mysql中備份表的四種方法,第一種方式是小表的備份,第二種是對(duì)整個(gè)數(shù)據(jù)庫(kù)的備份與恢復(fù),第三種是對(duì)某個(gè)數(shù)據(jù)表進(jìn)行備份,每種方式給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明

    Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明

    這篇文章主要介紹了Mybatis日期格式自動(dòng)轉(zhuǎn)換需要用到的兩個(gè)注解說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論