最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Docker從零到生產(chǎn)環(huán)境部署SpringBoot項目的完整指南:

 更新時間:2026年03月18日 08:46:02   作者:J_liaty  
在當(dāng)今的軟件開發(fā)領(lǐng)域,容器化 技術(shù)已經(jīng)成為應(yīng)用部署的標(biāo)準(zhǔn)實踐,Docker 作為容器技術(shù)的領(lǐng)導(dǎo)者,徹底改變了應(yīng)用的打包、分發(fā)和運行方式,本指南將詳細講解如何使用 Docker 容器化部署 Java Spring Boot 項目,需要的朋友可以參考下

前言

在當(dāng)今的軟件開發(fā)領(lǐng)域,容器化技術(shù)已經(jīng)成為應(yīng)用部署的標(biāo)準(zhǔn)實踐。Docker 作為容器技術(shù)的領(lǐng)導(dǎo)者,徹底改變了應(yīng)用的打包、分發(fā)和運行方式。本指南將詳細講解如何使用 Docker 容器化部署 Java Spring Boot 項目,涵蓋從基礎(chǔ)概念到生產(chǎn)環(huán)境部署的完整流程。

第一章:Docker 基礎(chǔ)概念與優(yōu)勢

1.1 為什么選擇 Docker?

在傳統(tǒng)部署方式中,我們常常遇到以下問題:

  • 環(huán)境不一致:開發(fā)、測試、生產(chǎn)環(huán)境差異導(dǎo)致"在我機器上能運行"的問題
  • 依賴沖突:不同應(yīng)用需要不同版本的運行時環(huán)境
  • 部署復(fù)雜:需要手動安裝配置各種依賴和服務(wù)
  • 資源浪費:每個應(yīng)用獨占完整操作系統(tǒng)資源

Docker 通過容器化技術(shù)解決了這些問題:

  • 一致性:確保應(yīng)用在任何環(huán)境運行一致
  • 隔離性:應(yīng)用運行在獨立容器中,互不干擾
  • 輕量級:容器共享主機操作系統(tǒng)內(nèi)核,資源占用少
  • 可移植性:一次構(gòu)建,隨處運行

1.2 Docker 核心概念

  • 鏡像(Image) :只讀模板,包含運行應(yīng)用所需的所有內(nèi)容
  • 容器(Container) :鏡像的運行實例,是真正的執(zhí)行環(huán)境
  • 倉庫(Registry) :存儲和分發(fā)鏡像的地方(如 Docker Hub)
  • Dockerfile:文本文件,包含構(gòu)建鏡像的指令

第二章:環(huán)境準(zhǔn)備與安裝

2.1 系統(tǒng)要求

  • Linux(Ubuntu 18.04+、CentOS 7+)、macOS 或 Windows 10/11
  • 至少 2GB RAM(建議 4GB 以上)
  • 10GB 可用磁盤空間

2.2 Docker 安裝

Ubuntu/Debian 系統(tǒng)安裝:

# 1. 卸載舊版本(如果存在)
sudo apt-get remove docker docker-engine docker.io containerd runc

# 2. 更新 apt 包索引
sudo apt-get update

# 3. 安裝依賴包
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 4. 添加 Docker 官方 GPG 密鑰
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 5. 設(shè)置穩(wěn)定版?zhèn)}庫
echo \
  "deb [arch=$(dpkg --print-architecture) 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

# 6. 更新 apt 包索引
sudo apt-get update

# 7. 安裝 Docker Engine
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 8. 驗證安裝是否成功
sudo docker --version

# 9. 啟動 Docker 服務(wù)
sudo systemctl start docker
sudo systemctl enable docker

# 10. 測試運行 Hello World
sudo docker run hello-world

CentOS/RHEL 系統(tǒng)安裝:

# 1. 卸載舊版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 2. 安裝必要的包
sudo yum install -y yum-utils

# 3. 設(shè)置倉庫
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 4. 安裝 Docker Engine
sudo yum install docker-ce docker-ce-cli containerd.io

# 5. 啟動 Docker
sudo systemctl start docker
sudo systemctl enable docker

# 6. 驗證安裝
sudo docker --version
sudo docker run hello-world

2.3 配置非 root 用戶運行 Docker(可選但推薦)

# 創(chuàng)建 docker 用戶組(如果不存在)
sudo groupadd docker

# 將當(dāng)前用戶添加到 docker 組
sudo usermod -aG docker $USER

# 重新登錄或使用以下命令立即生效
newgrp docker

# 驗證非 root 用戶是否能運行 Docker 命令
docker run hello-world

2.4 安裝 Docker Compose

# 下載最新版本的 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 賦予執(zhí)行權(quán)限
sudo chmod +x /usr/local/bin/docker-compose

# 創(chuàng)建軟鏈接(如果需要)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 驗證安裝
docker-compose --version

第三章:準(zhǔn)備 Spring Boot 項目

3.1 創(chuàng)建示例 Spring Boot 項目

首先,我們創(chuàng)建一個簡單的 Spring Boot 項目用于演示:

pom.xml(Maven 配置):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>docker-demo</artifactId>
    <version>1.0.0</version>
    <name>docker-demo</name>
    <description>Spring Boot Docker Demo Project</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

項目結(jié)構(gòu):

docker-demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── dockerdemo/
│   │   │               ├── DockerDemoApplication.java
│   │   │               ├── controller/
│   │   │               │   └── HelloController.java
│   │   │               └── service/
│   │ │                   └── HelloService.java
│   │   └── resources/
│   │       ├── application.properties
│   │       └── static/
│   └── test/
├── Dockerfile
├── docker-compose.yml
└── pom.xml

HelloController.java:

package com.example.dockerdemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class HelloController {
    @GetMapping("/hello")
    public Map<String, Object> hello() {
        Map<String, Object> response = new HashMap<>();
        response.put("message", "Hello from Docker!");
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("status", "success");
        return response;
    }
    @GetMapping("/health")
    public Map<String, Object> health() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "docker-demo");
        response.put("timestamp", System.currentTimeMillis());
        return response;
    }
}

application.properties:

# 應(yīng)用配置
server.port=8080
server.servlet.context-path=/
# 應(yīng)用信息
spring.application.name=docker-demo
# Actuator 配置
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
# 日志配置
logging.level.com.example.dockerdemo=DEBUG
logging.file.name=/var/log/docker-demo/app.log

3.2 構(gòu)建項目 JAR 包

# 進入項目根目錄
cd docker-demo

# 使用 Maven 打包項目
mvn clean package

# 或者使用 Maven Wrapper(如果項目中有 mvnw)
./mvnw clean package

# 打包成功后,在 target 目錄下會生成 JAR 文件
# docker-demo-1.0.0.jar

第四章:編寫 Dockerfile

4.1 Dockerfile 基礎(chǔ)結(jié)構(gòu)

Dockerfile 是一個文本文件,包含了一系列構(gòu)建 Docker 鏡像的指令。每條指令都會在鏡像中創(chuàng)建一個新的層。

4.2 完整 Dockerfile 示例

在項目根目錄創(chuàng)建 Dockerfile(注意沒有文件擴展名):

# 第一階段:構(gòu)建階段
# 使用官方 Maven 鏡像作為構(gòu)建環(huán)境
FROM maven:3.8.4-openjdk-11-slim AS builder

# 設(shè)置工作目錄
WORKDIR /app

# 復(fù)制 pom.xml 和源代碼
COPY pom.xml .
COPY src ./src

# 下載依賴(利用 Docker 緩存層,如果 pom.xml 不變則不重新下載)
RUN mvn dependency:go-offline -B

# 構(gòu)建應(yīng)用(跳過測試以加快構(gòu)建速度)
RUN mvn clean package -DskipTests

# 第二階段:運行階段
# 使用更小的 JRE 鏡像作為運行環(huán)境
FROM openjdk:11-jre-slim

# 設(shè)置元數(shù)據(jù)標(biāo)簽(可選)
LABEL maintainer="your-email@example.com"
LABEL version="1.0"
LABEL description="Spring Boot application in Docker"

# 設(shè)置時區(qū)(根據(jù)需求調(diào)整)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 創(chuàng)建一個非 root 用戶運行應(yīng)用(安全最佳實踐)
RUN groupadd -r spring && useradd -r -g spring spring
USER spring

# 設(shè)置工作目錄
WORKDIR /app

# 從構(gòu)建階段復(fù)制構(gòu)建好的 JAR 文件
COPY --from=builder /app/target/docker-demo-*.jar app.jar

# 創(chuàng)建日志目錄并設(shè)置權(quán)限
RUN mkdir -p /var/log/docker-demo && \
    chown -R spring:spring /var/log/docker-demo

# 暴露應(yīng)用端口
EXPOSE 8080

# 設(shè)置 JVM 參數(shù)(根據(jù)實際情況調(diào)整)
ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/docker-demo/heapdump.hprof"

# 啟動應(yīng)用
# 使用 exec 形式啟動,確保 Java 進程成為 PID 1,能正確處理信號
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar

# 健康檢查指令
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:8080/api/health || exit 1

4.3 Dockerfile 指令詳解

FROM:指定基礎(chǔ)鏡像

  • 使用多階段構(gòu)建:第一階段用于構(gòu)建,第二階段用于運行
  • 選擇合適的基礎(chǔ)鏡像:官方鏡像、版本固定、輕量級

WORKDIR:設(shè)置工作目錄

  • 后續(xù)指令都在此目錄下執(zhí)行
  • 如果目錄不存在會自動創(chuàng)建

COPY:復(fù)制文件到鏡像

  • COPY pom.xml .:復(fù)制單個文件
  • COPY src ./src:復(fù)制目錄
  • COPY --from=builder:從上一構(gòu)建階段復(fù)制文件

RUN:執(zhí)行命令

  • 在鏡像構(gòu)建過程中執(zhí)行
  • 每條 RUN 指令都會創(chuàng)建一個新的鏡像層

ENV:設(shè)置環(huán)境變量

  • 在鏡像中設(shè)置環(huán)境變量
  • 可以被后續(xù)指令和容器運行時使用

USER:指定運行用戶

  • 安全最佳實踐:不使用 root 用戶運行應(yīng)用

EXPOSE:聲明端口

  • 僅聲明容器運行時監(jiān)聽的端口
  • 實際映射由 docker rundocker-compose 處理

ENTRYPOINT:容器啟動命令

  • 容器啟動時執(zhí)行的命令
  • 使用 exec 形式確保信號正確傳遞

HEALTHCHECK:健康檢查

  • 定期檢查容器健康狀態(tài)
  • 幫助 Docker 和編排系統(tǒng)了解應(yīng)用狀態(tài)

4.4 優(yōu)化 Dockerfile 的技巧

  1. 利用緩存:將不常變化的指令放在前面
  2. 多階段構(gòu)建:減小最終鏡像大小
  3. 使用 .dockerignore:排除不需要的文件
  4. 合并 RUN 指令:減少鏡像層數(shù)

創(chuàng)建 .dockerignore 文件:

# 忽略所有以 . 開頭的文件
.*
# 忽略 IDE 配置文件
.vscode/
.idea/
*.iml
# 忽略構(gòu)建輸出
target/
build/
out/
# 忽略日志文件
*.log
logs/
# 忽略臨時文件
*.tmp
*.temp
tmp/
temp/
# 忽略 Git 相關(guān)
.git/
.gitignore
# 忽略 Docker 相關(guān)
Dockerfile*
docker-compose*
.dockerignore
# 忽略文檔
*.md
README

第五章:構(gòu)建 Docker 鏡像

5.1 基礎(chǔ)構(gòu)建命令

# 進入項目根目錄(確保 Dockerfile 在此目錄)
cd /path/to/docker-demo

# 構(gòu)建鏡像
# -t: 給鏡像打標(biāo)簽(名稱:版本)
# .: 構(gòu)建上下文路徑(當(dāng)前目錄)
docker build -t docker-demo:1.0.0 .

# 查看構(gòu)建過程輸出
# 可以看到每一層的構(gòu)建情況

5.2 詳細的構(gòu)建過程

讓我們分解構(gòu)建過程:

# 1. 驗證 Dockerfile 語法
# 可以使用 docker build --dry-run 驗證語法(需要 buildx)
docker buildx build --dry-run .

# 2. 實際構(gòu)建鏡像(詳細輸出)
docker build -t docker-demo:1.0.0 --progress=plain .

# 3. 查看構(gòu)建的鏡像
docker images

# 輸出示例:
# REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
# docker-demo   1.0.0     abc123def456   2 minutes ago    215MB

5.3 鏡像構(gòu)建優(yōu)化

# 1. 使用緩存加速構(gòu)建
# 如果依賴沒有變化,Docker 會使用緩存
docker build -t docker-demo:1.0.0 .

# 2. 不使用緩存(強制重新構(gòu)建所有層)
docker build -t docker-demo:1.0.0 --no-cache .

# 3. 指定目標(biāo)構(gòu)建階段
# 多階段構(gòu)建時,可以指定只構(gòu)建到某個階段
docker build -t docker-demo:builder --target builder .

# 4. 清理構(gòu)建緩存
docker builder prune

# 5. 查看鏡像構(gòu)建歷史
docker history docker-demo:1.0.0

5.4 鏡像標(biāo)簽管理

# 給鏡像添加多個標(biāo)簽
docker build -t docker-demo:1.0.0 -t docker-demo:latest .

# 給現(xiàn)有鏡像添加新標(biāo)簽
docker tag docker-demo:1.0.0 docker-demo:stable

# 查看所有鏡像
docker images

# 刪除鏡像
docker rmi docker-demo:1.0.0

# 強制刪除鏡像(即使有容器使用)
docker rmi -f docker-demo:1.0.0

# 清理所有未使用的鏡像
docker image prune -a

第六章:運行 Docker 容器

6.1 基礎(chǔ)運行命令

# 最基本的方式運行容器
docker run docker-demo:1.0.0

# 但這會占用終端,且容器停止后會自動刪除

6.2 完整的運行配置

# 完整的容器運行命令
docker run -d \
  --name docker-demo-app \
  -p 8080:8080 \
  -e "SPRING_PROFILES_ACTIVE=prod" \
  -v /path/to/logs:/var/log/docker-demo \
  --restart unless-stopped \
  --memory=512m \
  --cpus="1.0" \
  --health-cmd="curl -f http://localhost:8080/api/health || exit 1" \
  --health-interval=30s \
  --health-timeout=3s \
  --health-retries=3 \
  docker-demo:1.0.0

參數(shù)解釋:

  1. -d:后臺運行(detached mode)
  2. --name:為容器指定名稱
  3. -p:端口映射(主機端口:容器端口)
  4. -e:設(shè)置環(huán)境變量
  5. -v:卷掛載(主機目錄:容器目錄)
  6. --restart:重啟策略
  7. --memory:內(nèi)存限制
  8. --cpus:CPU 限制
  9. --health-*:健康檢查配置

6.3 容器管理命令

# 查看運行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 查看容器日志
docker logs docker-demo-app

# 實時查看日志
docker logs -f docker-demo-app

# 查看最后 N 行日志
docker logs --tail 100 docker-demo-app

# 查看容器資源使用情況
docker stats docker-demo-app

# 進入容器內(nèi)部(交互式 shell)
docker exec -it docker-demo-app /bin/bash

# 在容器內(nèi)執(zhí)行單個命令
docker exec docker-demo-app ls -la /app

# 停止容器
docker stop docker-demo-app

# 啟動已停止的容器
docker start docker-demo-app

# 重啟容器
docker restart docker-demo-app

# 刪除容器(必須先停止)
docker rm docker-demo-app

# 強制刪除運行中的容器
docker rm -f docker-demo-app

# 查看容器詳細信息
docker inspect docker-demo-app

# 查看容器端口映射
docker port docker-demo-app

# 復(fù)制文件到容器
docker cp localfile.txt docker-demo-app:/app/

# 從容器復(fù)制文件
docker cp docker-demo-app:/app/logs/app.log ./

6.4 網(wǎng)絡(luò)配置

# 創(chuàng)建自定義網(wǎng)絡(luò)(推薦)
docker network create app-network

# 查看網(wǎng)絡(luò)列表
docker network ls

# 在自定義網(wǎng)絡(luò)中運行容器
docker run -d \
  --name docker-demo-app \
  --network app-network \
  docker-demo:1.0.0

# 查看網(wǎng)絡(luò)詳情
docker network inspect app-network

# 連接容器到網(wǎng)絡(luò)
docker network connect app-network docker-demo-app

# 斷開容器與網(wǎng)絡(luò)的連接
docker network disconnect app-network docker-demo-app

# 刪除網(wǎng)絡(luò)
docker network rm app-network

6.5 數(shù)據(jù)持久化

# 1. 使用綁定掛載(bind mount)
docker run -d \
  -v /host/path/logs:/var/log/docker-demo \
  docker-demo:1.0.0

# 2. 使用 Docker 卷(volume)
# 創(chuàng)建卷
docker volume create app-logs

# 使用卷
docker run -d \
  -v app-logs:/var/log/docker-demo \
  docker-demo:1.0.0

# 查看卷列表
docker volume ls

# 查看卷詳情
docker volume inspect app-logs

# 清理未使用的卷
docker volume prune

# 3. 使用臨時文件系統(tǒng)(tmpfs)
docker run -d \
  --tmpfs /tmp \
  docker-demo:1.0.0

第七章:使用 Docker Compose 編排

7.1 為什么需要 Docker Compose?

  • 管理多個容器的啟動順序和依賴關(guān)系
  • 簡化復(fù)雜的容器配置
  • 方便本地開發(fā)環(huán)境搭建
  • 支持環(huán)境變量和配置文件管理

7.2 創(chuàng)建 docker-compose.yml

version: '3.8'
# 定義網(wǎng)絡(luò)(所有服務(wù)共享)
networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
# 定義卷
volumes:
  app-logs:
    driver: local
  mysql-data:
    driver: local
# 定義服務(wù)
services:
  # Spring Boot 應(yīng)用服務(wù)
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - BUILD_VERSION=${BUILD_VERSION:-1.0.0}
    image: docker-demo:${BUILD_VERSION:-1.0.0}
    container_name: docker-demo-app
    restart: unless-stopped
    ports:
      - "8080:8080"
      - "8081:8081"  # 管理端口(如果需要)
    environment:
      - SPRING_PROFILES_ACTIVE=${PROFILE:-dev}
      - JAVA_OPTS=${JAVA_OPTS:--Xms256m -Xmx512m}
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_NAME=docker_demo
      - DB_USER=${DB_USER:-root}
      - DB_PASSWORD=${DB_PASSWORD:-password}
    volumes:
      - app-logs:/var/log/docker-demo
      - ./config:/app/config:ro  # 只讀掛載配置文件
    networks:
      - app-network
    depends_on:
      mysql:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1.0'
        reservations:
          memory: 256M
          cpus: '0.5'
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    # 開發(fā)模式配置(覆蓋默認(rèn))
    profiles: ["dev"]
    ports:
      - "8080:8080"
      - "5005:5005"  # 遠程調(diào)試端口
    environment:
      - JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms256m -Xmx512m
  # MySQL 數(shù)據(jù)庫服務(wù)
  mysql:
    image: mysql:8.0
    container_name: docker-demo-mysql
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-password}
      - MYSQL_DATABASE=docker_demo
      - MYSQL_USER=${DB_USER:-appuser}
      - MYSQL_PASSWORD=${DB_PASSWORD:-password}
    volumes:
      - mysql-data:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
    networks:
      - app-network
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5
    command: 
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
  # Redis 緩存服務(wù)
  redis:
    image: redis:7-alpine
    container_name: docker-demo-redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - app-network
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-redispass}
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
  # Nginx 反向代理
  nginx:
    image: nginx:1.21-alpine
    container_name: docker-demo-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - ./nginx/logs:/var/log/nginx
    networks:
      - app-network
    depends_on:
      - app
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 10s
      retries: 3
  # 監(jiān)控服務(wù)(Prometheus + Grafana)
  monitoring:
    image: prom/prometheus:latest
    container_name: docker-demo-prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    networks:
      - app-network
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
  grafana:
    image: grafana/grafana:latest
    container_name: docker-demo-grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    networks:
      - app-network
    depends_on:
      - monitoring

7.3 創(chuàng)建環(huán)境變量文件

創(chuàng)建 .env 文件(不會被提交到版本控制):

# 應(yīng)用配置
BUILD_VERSION=1.0.0
PROFILE=prod
JAVA_OPTS=-Xms256m -Xmx512m
# 數(shù)據(jù)庫配置
DB_USER=appuser
DB_PASSWORD=StrongPassword123!
DB_NAME=docker_demo
# Redis 配置
REDIS_PASSWORD=RedisPass123!
# Grafana 配置
GRAFANA_PASSWORD=GrafanaAdmin123!

7.4 Docker Compose 命令

# 1. 構(gòu)建并啟動所有服務(wù)(后臺運行)
docker-compose up -d

# 2. 構(gòu)建鏡像(不啟動)
docker-compose build

# 3. 啟動已存在的服務(wù)
docker-compose start

# 4. 停止所有服務(wù)
docker-compose stop

# 5. 停止并刪除所有容器、網(wǎng)絡(luò)
docker-compose down

# 6. 停止并刪除所有容器、網(wǎng)絡(luò)、卷
docker-compose down -v

# 7. 查看服務(wù)狀態(tài)
docker-compose ps

# 8. 查看服務(wù)日志
docker-compose logs

# 9. 查看特定服務(wù)日志
docker-compose logs app

# 10. 實時查看日志
docker-compose logs -f app

# 11. 進入容器
docker-compose exec app /bin/bash

# 12. 在服務(wù)上執(zhí)行命令
docker-compose exec app ls -la

# 13. 重啟服務(wù)
docker-compose restart app

# 14. 擴展服務(wù)實例數(shù)
docker-compose up -d --scale app=3

# 15. 拉取服務(wù)鏡像
docker-compose pull

# 16. 查看服務(wù)配置
docker-compose config

# 17. 暫停服務(wù)
docker-compose pause app

# 18. 恢復(fù)暫停的服務(wù)
docker-compose unpause app

# 19. 使用特定環(huán)境文件
docker-compose --env-file .env.production up -d

# 20. 使用特定配置文件
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 21. 只啟動部分服務(wù)
docker-compose up -d app mysql

# 22. 重新構(gòu)建服務(wù)
docker-compose up -d --build app

# 23. 清理未使用的資源
docker-compose down --rmi local

7.5 多環(huán)境配置

創(chuàng)建 docker-compose.override.yml(用于開發(fā)環(huán)境):

version: '3.8'
services:
  app:
    ports:
      - "8080:8080"
      - "5005:5005"
    environment:
      - SPRING_PROFILES_ACTIVE=dev
      - JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms256m -Xmx512m
    volumes:
      - ./src:/app/src

創(chuàng)建 docker-compose.prod.yml(用于生產(chǎn)環(huán)境):

version: '3.8'
services:
  app:
    restart: always
    deploy:
      resources:
        limits:
          memory: 1g
          cpus: '2.0'
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - JAVA_OPTS=-Xms512m -Xmx1024m -XX:+UseG1GC

第八章:生產(chǎn)環(huán)境部署實踐

8.1 安全最佳實踐

# 1. 使用非 root 用戶運行容器
# 在 Dockerfile 中已設(shè)置
USER spring

# 2. 掃描鏡像安全漏洞
docker scan docker-demo:1.0.0

# 3. 使用內(nèi)容信任
export DOCKER_CONTENT_TRUST=1
docker build -t docker-demo:1.0.0 .

# 4. 限制容器能力
docker run -d \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  docker-demo:1.0.0

# 5. 設(shè)置只讀根文件系統(tǒng)
docker run -d \
  --read-only \
  --tmpfs /tmp \
  -v app-logs:/var/log/docker-demo \
  docker-demo:1.0.0

8.2 日志管理

# docker-compose.yml 中的日志配置
logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"
    compress: "true"
    labels: "production"
    env: "os,customer"
# 查看日志驅(qū)動
docker info --format '{{.LoggingDriver}}'

# 使用日志驅(qū)動
docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  docker-demo:1.0.0

# 使用 syslog 驅(qū)動
docker run -d \
  --log-driver syslog \
  --log-opt syslog-address=udp://syslog-server:514 \
  docker-demo:1.0.0

8.3 資源限制與監(jiān)控

# 設(shè)置資源限制
docker run -d \
  --memory="512m" \
  --memory-swap="1g" \
  --cpus="1.5" \
  --cpu-shares="1024" \
  --blkio-weight="500" \
  docker-demo:1.0.0

# 查看容器資源使用
docker stats docker-demo-app

# 設(shè)置容器重啟策略
docker run -d \
  --restart always \		# 總是重啟
  --restart on-failure \	# 失敗時重啟
  --restart unless-stopped \	# 除非手動停止,否則重啟
  docker-demo:1.0.0

8.4 鏡像倉庫與持續(xù)集成

# 登錄 Docker Hub
docker login
# 給鏡像打標(biāo)簽(用于推送到倉庫)
docker tag docker-demo:1.0.0 yourusername/docker-demo:1.0.0
docker tag docker-demo:1.0.0 yourusername/docker-demo:latest
# 推送到 Docker Hub
docker push yourusername/docker-demo:1.0.0
docker push yourusername/docker-demo:latest
# 從倉庫拉取鏡像
docker pull yourusername/docker-demo:1.0.0
# 使用私有倉庫
docker tag docker-demo:1.0.0 registry.example.com/yourproject/docker-demo:1.0.0
docker push registry.example.com/yourproject/docker-demo:1.0.0
# 配置私有倉庫(非安全)
docker run -d \
  -p 5000:5000 \
  --name registry \
  registry:2
# 推送鏡像到私有倉庫
docker tag docker-demo:1.0.0 localhost:5000/docker-demo:1.0.0
docker push localhost:5000/docker-demo:1.0.0

8.5 備份與恢復(fù)

# 備份容器數(shù)據(jù)
docker run --rm \
  --volumes-from docker-demo-app \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/app-data-$(date +%Y%m%d).tar.gz /var/log/docker-demo

# 備份 Docker 卷
docker run --rm \
  -v app-logs:/data \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/app-logs-$(date +%Y%m%d).tar.gz /data

# 導(dǎo)出容器
docker export docker-demo-app > docker-demo-container.tar

# 導(dǎo)入容器
cat docker-demo-container.tar | docker import - docker-demo:imported

# 保存鏡像為文件
docker save -o docker-demo-1.0.0.tar docker-demo:1.0.0

# 從文件加載鏡像
docker load -i docker-demo-1.0.0.tar

# 創(chuàng)建數(shù)據(jù)卷容器(用于數(shù)據(jù)共享)
docker create -v /var/log/docker-demo \
  --name app-data \
  busybox /bin/true

# 使用數(shù)據(jù)卷容器
docker run -d \
  --volumes-from app-data \
  docker-demo:1.0.0

第九章:常見問題與解決方案

9.1 構(gòu)建問題

問題1:構(gòu)建速度慢

# 解決方案:使用構(gòu)建緩存和鏡像加速器

# 1. 配置 Docker 鏡像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://registry.docker-cn.com"
  ]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

# 2. 使用構(gòu)建緩存
docker build -t docker-demo:1.0.0 --cache-from docker-demo:latest .

問題2:鏡像過大

# 解決方案:使用多階段構(gòu)建和輕量級基礎(chǔ)鏡像
# 使用 alpine 版本的鏡像
FROM openjdk:11-jre-slim  # 而不是 openjdk:11
# 或者使用更小的發(fā)行版
FROM openjdk:11-jre-alpine

9.2 運行問題

問題1:應(yīng)用啟動后立即退出

# 解決方案:檢查日志,確保應(yīng)用在前臺運行

# 錯誤的 CMD:
CMD java -jar app.jar &

# 正確的 CMD:
CMD ["java", "-jar", "app.jar"]
# 或使用 ENTRYPOINT:
ENTRYPOINT ["java", "-jar", "app.jar"]

問題2:端口被占用

# 解決方案:更改端口或停止占用進程

# 檢查端口占用
sudo netstat -tlnp | grep :8080

# 停止占用進程
sudo kill <PID>

# 或者使用不同端口
docker run -d -p 8081:8080 docker-demo:1.0.0

9.3 網(wǎng)絡(luò)問題

問題:容器間無法通信

# 解決方案:使用自定義網(wǎng)絡(luò)

# 創(chuàng)建網(wǎng)絡(luò)
docker network create my-network

# 將容器連接到同一網(wǎng)絡(luò)
docker run -d --network my-network --name app1 docker-demo:1.0.0
docker run -d --network my-network --name app2 docker-demo:1.0.0

# 在容器內(nèi)部可以通過容器名訪問

# 從 app1 訪問 app2
docker exec app1 curl http://app2:8080/api/health

9.4 數(shù)據(jù)持久化問題

問題:容器重啟后數(shù)據(jù)丟失

# 解決方案:使用數(shù)據(jù)卷

# 創(chuàng)建命名卷
docker volume create app-data

# 使用卷
docker run -d \
  -v app-data:/app/data \
  docker-demo:1.0.0

# 或者使用綁定掛載
docker run -d \
  -v /host/path/data:/app/data \
  docker-demo:1.0.0

第十章:進階部署方案

10.1 使用 Docker Swarm(集群部署)

# 初始化 Swarm 集群
docker swarm init

# 查看節(jié)點
docker node ls

# 創(chuàng)建 overlay 網(wǎng)絡(luò)
docker network create --driver overlay app-network

# 部署服務(wù)棧
docker stack deploy -c docker-compose.yml docker-demo

# 查看服務(wù)
docker service ls

# 查看服務(wù)詳情
docker service ps docker-demo_app

# 擴展服務(wù)
docker service scale docker-demo_app=3

# 更新服務(wù)
docker service update --image docker-demo:2.0.0 docker-demo_app

# 回滾服務(wù)
docker service update --rollback docker-demo_app

# 刪除服務(wù)棧
docker stack rm docker-demo

10.2 使用 Kubernetes(生產(chǎn)級編排)

創(chuàng)建 deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-demo-deployment
  labels:
    app: docker-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: docker-demo
  template:
    metadata:
      labels:
        app: docker-demo
    spec:
      containers:
      - name: docker-demo
        image: yourusername/docker-demo:1.0.0
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"
          requests:
            memory: "256Mi"
            cpu: "250m"
        livenessProbe:
          httpGet:
            path: /api/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: docker-demo-service
spec:
  selector:
    app: docker-demo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer

10.3 CI/CD 流水線示例

.gitlab-ci.yml 示例:

stages:
  - build
  - test
  - dockerize
  - deploy
variables:
  DOCKER_IMAGE: registry.example.com/yourproject/docker-demo:$CI_COMMIT_REF_SLUG
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
  paths:
    - .m2/repository/
    - target/
build:
  stage: build
  image: maven:3.8.4-openjdk-11
  script:
    - mvn clean compile
test:
  stage: test
  image: maven:3.8.4-openjdk-11
  script:
    - mvn test
docker-build:
  stage: dockerize
  image: docker:20.10
  services:
    - docker:20.10-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE
deploy:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $DEPLOY_SERVER >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
    - |
      ssh $DEPLOY_USER@$DEPLOY_SERVER "
        docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY &&
        docker pull $DOCKER_IMAGE &&
        docker stop docker-demo-app || true &&
        docker rm docker-demo-app || true &&
        docker run -d \
          --name docker-demo-app \
          -p 8080:8080 \
          --restart unless-stopped \
          $DOCKER_IMAGE
      "
  only:
    - master

總結(jié)

通過本文的詳細講解,您應(yīng)該已經(jīng)掌握了使用 Docker 部署 Spring Boot 項目的完整流程。我們從基礎(chǔ)概念開始,逐步深入,涵蓋了:

  1. 環(huán)境準(zhǔn)備:在不同系統(tǒng)上安裝 Docker 和 Docker Compose
  2. 項目準(zhǔn)備:創(chuàng)建 Spring Boot 項目并配置 Dockerfile
  3. 鏡像構(gòu)建:使用多階段構(gòu)建優(yōu)化鏡像大小
  4. 容器運行:各種運行選項和參數(shù)配置
  5. 服務(wù)編排:使用 Docker Compose 管理多容器應(yīng)用
  6. 生產(chǎn)部署:安全、監(jiān)控、備份等最佳實踐
  7. 問題解決:常見問題排查和解決方案
  8. 進階方案:Docker Swarm 和 Kubernetes 部署

Docker 作為現(xiàn)代應(yīng)用部署的標(biāo)準(zhǔn)工具,掌握它對于開發(fā)者和運維人員都至關(guān)重要。實踐是學(xué)習(xí)的最佳方式,建議您按照本文的步驟實際操作,遇到問題時查閱官方文檔和社區(qū)資源。

記住,好的部署策略應(yīng)該具備:

  • 可重復(fù)性:每次部署結(jié)果一致
  • 可觀測性:完善的日志和監(jiān)控
  • 可恢復(fù)性:快速回滾和故障恢復(fù)能力
  • 安全性:最小權(quán)限原則和安全配置
  • 自動化:盡可能自動化部署流程

以上就是Docker從零到生產(chǎn)環(huán)境部署SpringBoot項目的完整指南:的詳細內(nèi)容,更多關(guān)于Docker部署SpringBoot的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

抚顺市| 大竹县| 镇安县| 扬中市| 桃江县| 陈巴尔虎旗| 休宁县| 宜君县| 新乡市| 金昌市| 同心县| 如东县| 刚察县| 江源县| 德庆县| 万荣县| 寿宁县| 滕州市| 万州区| 长丰县| 济阳县| 洪雅县| 城市| 栾城县| 长垣县| 松原市| 文化| 天台县| 海晏县| 醴陵市| 博兴县| 吉安市| 富阳市| 安西县| 中江县| 南阳市| 梧州市| 嵊泗县| 馆陶县| 昭通市| 启东市|