Java进阶全套教程(八)—— Docker超详细实战详解

Java进阶全套教程(八)------ Docker超详细实战详解

一、Docker 核心认知

1.1 什么是Docker

Docker 是一款基于 Go 语言开发、遵循 Apache2.0 开源协议的开源应用容器引擎,主打轻量化虚拟化技术。它可以将应用程序、运行依赖、系统环境、配置文件统一打包为可移植的镜像,实现应用在任意支持 Docker 的 Linux/Windows 环境中一致性运行,彻底解决"本地运行正常、服务器部署报错"的环境兼容问题。

Docker 名称直译是"码头工人",其品牌标识为鲸鱼承载多个集装箱,完美贴合技术理念:IT 领域的"集装箱"就是容器,标准化的容器可以封装各类应用,统一规格、相互隔离、可批量部署、可跨环境迁移,这也是 Docker 容器技术的核心精髓。

1.2 集装箱技术核心思想

传统软件部署最大的痛点是环境差异化:不同服务器的系统版本、依赖库、配置参数各不相同,导致应用部署、迁移、维护成本极高。

Docker 借鉴现实码头集装箱的标准化理念:现实中集装箱统一尺寸、独立密封、互不干扰、可堆叠运输;对应到 IT 领域,Docker 容器标准化应用运行环境,实现三大核心价值:

  • 环境标准化:一次打包,所有环境运行一致,消除环境差异Bug

  • 应用隔离化:不同容器独立运行,进程、资源、环境互不冲突

  • 部署轻量化:无需重复配置环境,直接通过镜像快速部署

1.3 Docker 核心定位与核心优势

Docker 的核心定位:打包程序+完整运行环境,实现一次构建、随处运行的容器化部署工具,是当下 DevOps 开发运维一体化的核心工具。

相较于传统部署方式,Docker 在开发、测试、生产全流程具备显著优势:

  • 极速交付部署:镜像构建完成后,秒级完成部署上线,无需繁琐环境配置

  • 超高资源利用率:共享宿主机内核,无需虚拟化完整系统,内存、磁盘占用极低

  • 灵活迁移扩展:镜像跨服务器、跨平台无缝迁移,支持横向批量扩容容器

  • 极简版本管理:支持镜像版本迭代、回滚,精准控制应用版本,更新无风险

1.4 Docker 与传统虚拟机深度对比

传统虚拟机属于硬件级虚拟化,需要模拟完整硬件、安装完整操作系统;Docker 属于操作系统级虚拟化,共享宿主机系统内核,仅隔离应用运行环境,轻量化优势极其明显。

对比维度 Docker 容器 传统虚拟机
启动速度 秒级启动,无系统初始化过程 分钟级启动,需加载完整系统
磁盘占用 MB 级,仅存储应用与依赖 GB 级,包含完整系统镜像
运行性能 接近原生物理机,无性能损耗 存在虚拟化损耗,性能低于原生
单机承载量 单机可部署上千个容器 单机仅支持几十个虚拟机
隔离级别 进程级资源隔离 系统级完全隔离

二、虚拟化技术体系与Docker技术归属

2.1 虚拟化技术概述

虚拟化是通过软件方式对物理硬件、系统资源进行逻辑划分的技术,核心是"逻辑隔离、资源复用",旨在提升硬件资源利用率,是云计算、容器化技术的底层基础。

通俗类比:一套物理房屋(物理机),直接使用仅能单人独享;通过虚拟化改造,可分割为多个独立单间(虚拟机/容器),多用户独立使用,提升资源利用率。

2.2 虚拟化技术分类

  • 完全虚拟化:完整模拟硬件设备,可运行任意操作系统,代表:VMware、KVM

  • 硬件辅助虚拟化:依托CPU虚拟化指令集加速,提升虚拟化性能,主流虚拟机均采用此技术

  • 部分虚拟化:仅对部分硬件资源虚拟化,系统内核仍共享,隔离性较弱

  • 超虚拟化:修改客户机内核,适配虚拟化环境,降低性能损耗

  • 操作系统虚拟化 :共享宿主机操作系统内核,仅隔离用户空间,轻量化、高性能,Docker 属于此类虚拟化

2.3 物理机、虚拟机、Docker容器三者区别

  • 物理机:真实物理服务器,完整硬件+原生系统,资源独占,无虚拟化损耗,部署繁琐、迁移困难

  • 虚拟机:硬件级虚拟化,独立系统内核、独立硬件资源,隔离性极强,但笨重、启动慢、资源占用高

  • Docker容器:系统级虚拟化,共享宿主机内核,仅隔离应用进程与环境,轻量、极速、高并发,隔离性满足业务部署需求

三、Docker 三大核心核心概念

Docker 所有操作均围绕镜像、容器、仓库三大核心概念展开,三者层层关联、缺一不可,是掌握 Docker 的基础。

3.1 镜像(Image)------ 应用模板

Docker 镜像属于只读模板,是创建容器的唯一依据,包含应用运行所需的系统环境、依赖库、程序文件、配置脚本等所有资源。镜像采用分层存储结构,每一层都是独立的只读文件系统,支持复用、缓存加速构建。

镜像来源主要分为两种:

  • 官方公共仓库拉取:从 Docker Hub、阿里云 ACR 下载现成镜像(JDK、MySQL、Nginx 等)

  • 自定义构建:通过 Dockerfile 脚本,基于基础镜像封装专属业务镜像

3.2 容器(Container)------ 运行实例

容器是镜像的动态运行实例,镜像为静态模板,容器为动态运行的进程。一个镜像可以批量创建多个相互隔离的容器,容器支持启动、停止、重启、删除等操作。

核心公式:容器 = 只读镜像 + 可读写临时层

所有容器运行时的修改、日志、缓存数据,均存储在顶层可读写层,删除容器后,临时层数据默认丢失(可通过数据卷持久化保存)。

3.3 仓库(Repository)------ 镜像存储中心

Docker 仓库是集中存储、管理镜像的远程服务器,用于镜像的上传、下载、版本管理,理念与 Maven 仓库、Git 仓库高度相似。

主流仓库分类:

  • 官方公共仓库:Docker Hub(全球最大镜像仓库,海量官方镜像)

  • 国内镜像仓库:阿里云 ACR、腾讯云 TCR、华为云 SWR(解决国外仓库访问慢问题)

  • 私有仓库:企业自建 Registry,存储内部业务专属镜像,保障数据安全

3.4 Docker 核心口号解读

  • Build, Ship and Run:一次构建、统一分发、任意运行

  • Build once,Run anywhere:单次打包构建,适配所有支持 Docker 的运行环境

四、Docker 环境搭建与基础配置

4.1 部署环境要求

  • 操作系统:CentOS 7+/Ubuntu 16.04+

  • 内核版本:Linux 内核 3.8 及以上(CentOS7 默认内核 3.10,完全兼容)

4.2 环境初始化配置(生产必备)

Docker 部署前需关闭防火墙与 SELinux,避免端口拦截、权限限制导致容器访问异常

bash 复制代码
# 1. 临时关闭防火墙(重启失效)
systemctl stop firewalld

# 2. 永久关闭防火墙开机自启
systemctl disable firewalld

# 3. 永久关闭SELinux(重启生效)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 4. 临时关闭SELinux(无需重启立即生效)
setenforce 0

4.3 Docker 安装与启停配置

bash 复制代码
# 1. 更新yum依赖源
yum update -y

# 2. 安装Docker引擎
yum install -y docker-ce

# 3. 启动Docker服务
systemctl start docker

# 4. 设置Docker开机自启
systemctl enable docker

# 5. 查看Docker运行状态
systemctl status docker

# 6. 测试Docker安装成功(运行测试镜像)
docker run hello-world

4.4 配置国内镜像加速(解决拉取镜像缓慢问题)

默认 Docker Hub 服务器在国外,拉取镜像速度极慢,配置阿里云镜像加速器提升下载速度

bash 复制代码
# 1. 创建Docker配置目录
mkdir -p /etc/docker

# 2. 写入阿里云镜像加速配置
tee /etc/docker/daemon.json <<-EOF
{
  "registry-mirrors": ["https://mirror.aliyuncs.com"]
}
EOF

# 3. 重新加载配置、重启Docker
systemctl daemon-reload
systemctl restart docker

五、Docker 核心镜像命令(实操高频)

镜像是容器运行的基础,所有容器操作都依赖本地镜像,以下为生产环境高频镜像管理命令。

5.1 查看本地镜像

bash 复制代码
# 查看所有本地镜像基础信息
docker images

# 查看本地镜像详细信息(层数、大小、创建时间、元数据)
docker images --verbose

# 仅查看所有镜像ID(批量操作专用)
docker images -q

字段说明:REPOSITORY(镜像名称)、TAG(版本标签,latest为最新版)、IMAGE ID(镜像唯一ID)、CREATED(创建时间)、SIZE(镜像大小)

5.2 搜索远程镜像

bash 复制代码
# 搜索Docker Hub远程指定镜像
docker search nginx

# 筛选星级大于100的官方镜像
docker search --filter=stars=100 --filter=is-official=true nginx

5.3 拉取远程镜像

bash 复制代码
# 拉取最新版本镜像(默认latest)
docker pull nginx

# 拉取指定版本镜像(生产必须指定版本,避免版本迭代兼容问题)
docker pull nginx:1.24.0

# 拉取Java8官方镜像
docker pull openjdk:8-jdk-alpine

5.4 删除本地镜像

bash 复制代码
# 根据镜像名称+版本删除
docker rmi nginx:1.24.0

# 根据镜像ID删除
docker rmi 23f6481799cb

# 强制删除所有未使用的镜像
docker image prune -a -f

5.5 镜像打包与导入导出

用于镜像跨服务器迁移,无需重新拉取、构建,直接复用镜像

bash 复制代码
# 1. 导出本地镜像为tar压缩包
docker save -o nginx-1.24.0.tar nginx:1.24.0

# 2. 导入tar镜像包到本地Docker
docker load -i nginx-1.24.0.tar

六、Docker 核心容器命令(生产实操核心)

容器是 Docker 业务运行的核心,所有应用均以容器形式运行,熟练掌握容器启停、查看、运维命令是部署关键。

6.1 创建与启动容器

容器启动分为两步:创建容器、启动容器,也可通过 run 命令一步完成创建+启动

bash 复制代码
# 1. 仅创建容器(停止状态,无运行进程)
docker create --name nginx-demo nginx:1.24.0

# 2. 启动已创建的停止态容器
docker start nginx-demo

# 3. 新建并后台启动容器(常用)
# --name:指定容器名称 -d:后台守护态运行 -p:端口映射
docker run -d --name nginx-web -p 80:80 nginx:1.24.0

# 4. 交互式启动容器(进入容器终端,前台运行)
docker run -it --name centos-test centos:7 /bin/bash

6.2 查看容器状态

bash 复制代码
# 查看当前正在运行的容器
docker ps

# 查看所有容器(包含停止状态)
docker ps -a

# 仅查看所有容器ID
docker ps -aq

# 查看容器详细运行信息(IP、端口、挂载、网络等)
docker inspect nginx-web

6.3 容器启停与重启

bash 复制代码
# 停止单个容器
docker stop nginx-web

# 重启容器
docker restart nginx-web

# 批量停止所有容器
docker stop $(docker ps -aq)

# 批量重启所有容器
docker restart $(docker ps -aq)

6.4 进入容器内部操作

后台运行的容器无法直接操作,需通过 exec 命令进入容器终端,是线上运维核心命令

bash 复制代码
# 进入容器终端,执行bash交互命令
docker exec -it nginx-web /bin/bash

# 退出容器(不停止容器)
exit

核心区别:attach 命令进入容器会同步窗口日志,阻塞操作;exec 命令独立终端,生产环境优先使用 exec。

6.5 容器日志与进程查看

bash 复制代码
# 查看容器全部运行日志
docker logs nginx-web

# 实时跟踪容器最新日志(线上排查问题必备)
docker logs -f nginx-web

# 查看近100行最新日志
docker logs -f --tail=100 nginx-web

# 查看容器内部运行进程
docker top nginx-web

6.6 容器文件拷贝

实现宿主机与容器之间的文件双向传输,无需挂载数据卷即可临时同步文件

bash 复制代码
# 宿主机文件拷贝到容器内
docker cp /home/test.html nginx-web:/usr/share/nginx/html/

# 容器内文件拷贝到宿主机
docker cp nginx-web:/var/log/nginx/access.log /home/nginx/log/

6.7 删除容器

bash 复制代码
# 删除停止状态的容器
docker rm centos-test

# 强制删除正在运行的容器
docker rm -f nginx-web

# 批量删除所有容器
docker rm -f $(docker ps -aq)

七、Docker 实战部署常用服务

通过 Docker 快速部署 Java 开发常用环境,无需复杂配置,一键部署即用。

7.1 部署 JDK11 运行环境

bash 复制代码
# 1. 拉取JDK11轻量化镜像
docker pull openjdk:11-jre-slim

# 2. 后台启动Java环境容器
docker run -d --name java11-demo openjdk:11-jre-slim

# 3. 验证Java环境
docker exec -it java11-demo java -version

7.2 部署 Tomcat9 服务

bash 复制代码
# 1. 拉取Tomcat9镜像
docker pull tomcat:9.0-jdk11

# 2. 启动Tomcat容器,映射8080端口
docker run -d --name tomcat9-web -p 8080:8080 \
--restart always \
tomcat:9.0-jdk11

# 参数说明:--restart always 容器异常自动重启,适配生产环境

7.3 部署 MySQL5.7 数据库(生产常用)

bash 复制代码
# 1. 拉取MySQL5.7镜像
docker pull mysql:5.7

# 2. 启动MySQL容器,配置密码、端口、字符集
docker run -d --name mysql5.7 \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=Root@123456 \
--restart always \
--privileged=true \
mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci

参数说明:自定义宿主机3307端口避免与本地MySQL冲突,默认开启utf8mb4字符集,支持emoji表情存储。

八、Docker 数据卷核心技术(数据持久化)

8.1 数据卷核心作用

容器默认数据存储在可读写临时层,容器删除,数据丢失。数据卷(Volume)是宿主机与容器的文件挂载映射技术,实现数据持久化、文件同步、容器数据共享。

核心价值:

  • 容器删除后,数据卷文件保留,实现数据持久化

  • 宿主机直接修改文件,容器实时生效,无需进入容器

  • 支持多容器挂载同一数据卷,实现容器间数据共享

8.2 三种数据卷挂载方式

8.2.1 指定路径挂载(生产首选)

手动指定宿主机绝对路径与容器路径映射,路径不存在自动创建

bash 复制代码
# Tomcat挂载项目目录,实现项目持久化部署
docker run -d --name tomcat-web -p 8080:8080 \
-v /home/tomcat/webapps:/usr/local/tomcat/webapps \
-v /home/tomcat/logs:/usr/local/tomcat/logs \
tomcat:9.0-jdk11

8.2.2 具名挂载

自定义数据卷名称,Docker 统一管理存储路径,无需手动指定宿主机路径

bash 复制代码
# 创建具名数据卷
docker volume create tomcat-data

# 挂载具名数据卷
docker run -d --name tomcat-test -p 8081:8080 \
-v tomcat-data:/usr/local/tomcat/webapps \
tomcat:9.0-jdk11

8.2.3 匿名挂载

仅指定容器路径,Docker 自动生成随机名称数据卷,适合临时使用

bash 复制代码
docker run -d --name nginx-test -p 8082:80 \
-v /usr/share/nginx/html \
nginx:1.24.0

8.3 数据卷权限控制

挂载时可指定文件读写权限,保障数据安全

  • rw:默认权限,可读可写

  • ro:只读权限,容器仅可读取文件,无法修改

bash 复制代码
# 只读挂载示例
docker run -d --name nginx-ro -p 8083:80 \
-v /home/nginx/html:/usr/share/nginx/html:ro \
nginx:1.24.0

8.4 MySQL数据卷持久化实战

挂载MySQL数据目录、配置目录,实现数据库数据永久保存

bash 复制代码
# 创建宿主机挂载目录
mkdir -p /home/mysql/data /home/mysql/conf

# 启动MySQL并挂载数据卷
docker run -d --name mysql-prod \
-p 3308:3306 \
-e MYSQL_ROOT_PASSWORD=Root@123456 \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/conf:/etc/mysql/conf.d \
--restart always \
mysql:5.7

九、Dockerfile 自定义镜像(核心进阶)

官方镜像无法满足个性化业务需求,通过 Dockerfile 脚本自定义封装专属镜像,支持定制环境、预装依赖、配置启动命令,是企业级镜像构建核心方式。

9.1 Dockerfile 概述

Dockerfile 是纯文本配置文件,由多条指令组成,每条指令对应一层镜像层,Docker 逐行执行指令,自动构建定制化镜像。核心优势:版本可控、环境统一、批量复用。

Dockerfile 四大组成部分:基础镜像、维护信息、镜像构建指令、容器启动指令。

9.2 Dockerfile 13大核心指令详解

9.2.1 FROM(必选)

指定基础镜像,必须为文件第一行指令,所有自定义镜像均基于已有基础镜像构建

bash 复制代码
# 基于JDK8基础镜像构建Java项目镜像
FROM openjdk:8-jdk-alpine

# 基于CentOS7基础镜像构建环境镜像
FROM centos:7

9.2.2 MAINTAINER

声明镜像维护者信息(姓名、邮箱),非必选,规范项目镜像管理

bash 复制代码
MAINTAINER Java-Dev 123456@qq.com

9.2.3 WORKDIR

设置容器工作目录,等效于 cd 命令,后续所有指令均在该目录执行,目录不存在自动创建

bash 复制代码
# 设置项目工作目录
WORKDIR /home/project

9.2.4 RUN

镜像构建阶段执行的命令,用于安装依赖、配置环境、初始化文件,每层RUN生成一个镜像层

bash 复制代码
# 安装常用工具、更新依赖
RUN yum update -y && yum install -y wget curl net-tools

9.2.5 ADD/COPY

均用于拷贝文件到镜像,核心区别:ADD 支持自动解压压缩包、拉取网络资源;COPY 仅拷贝本地文件,纯净无额外操作,生产优先使用 COPY。

bash 复制代码
# 拷贝本地jar包到镜像工作目录
COPY app.jar /home/project/

# 解压压缩包到指定目录
ADD tomcat.tar.gz /usr/local/

9.2.6 ENV

设置环境变量,全局生效,构建阶段、容器运行阶段均可调用

bash 复制代码
# 设置项目端口、JDK环境变量
ENV SERVER_PORT=8080
ENV JAVA_OPTS="-Xms512m -Xmx1024m"

9.2.7 EXPOSE

声明容器对外暴露的端口,仅为标识作用,不会自动开放端口,端口映射需配合 run -p 命令

bash 复制代码
# 暴露项目8080端口
EXPOSE 8080

9.2.8 CMD

容器启动时执行的命令,仅最后一条 CMD 生效,可被 docker run 命令覆盖

9.2.9 ENTRYPOINT

与 CMD 类似,为容器启动常驻命令,不可被覆盖,可配合 CMD 追加启动参数

9.2.10 VOLUME

声明镜像数据卷,自动创建持久化目录,用于存储日志、数据文件

9.2.11 USER

指定容器运行用户,默认 root,可配置普通用户提升安全性

9.2.12 ONBUILD

延迟执行指令,基于当前镜像二次构建时自动触发,用于通用基础镜像封装

9.2.13 LABEL

添加镜像元数据标签,记录版本、描述、用途,方便镜像管理

9.3 实战:自定义SpringBoot项目镜像

编写完整 Dockerfile,封装可直接部署的 Java 项目镜像,优化分层构建、减少镜像体积

9.3.1 编写Dockerfile文件

bash 复制代码
# 基础镜像:轻量化JDK8
FROM openjdk:8-jdk-alpine

# 镜像维护信息
MAINTAINER Java-Dev Team

# 镜像标签
LABEL version="1.0" description="SpringBoot Web Project Image"

# 设置工作目录
WORKDIR /home/app

# 拷贝项目jar包
COPY demo-web.jar app.jar

# 配置JVM参数环境变量
ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"

# 暴露项目端口
EXPOSE 8080

# 容器启动命令
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar app.jar"]

9.3.2 构建镜像

bash 复制代码
# 构建镜像 -t 指定镜像名称和版本 . 代表当前目录Dockerfile
docker build -t springboot-demo:1.0 .

# 查看构建完成的镜像
docker images | grep springboot-demo

9.3.3 启动自定义镜像容器

bash 复制代码
docker run -d --name springboot-web -p 8080:8080 \
--restart always \
springboot-demo:1.0

9.4 镜像分层优化技巧

Docker 镜像分层缓存机制:未变更的指令层会复用缓存,大幅提升构建速度,优化核心技巧:

  • 频繁变更的指令(拷贝项目文件、启动命令)放在文件末尾

  • 合并多条 RUN 命令,减少镜像层数,降低镜像体积

  • 使用 alpine 轻量化基础镜像,替代完整版系统镜像

bash 复制代码
# 优化前(多层冗余)
RUN yum update -y
RUN yum install wget -y
RUN yum install curl -y

# 优化后(合并为一层,节省空间、提升速度)
RUN yum update -y && yum install -y wget curl && yum clean all

十、Docker 网络原理与网络配置

10.1 Docker0默认网桥原理

Docker 安装后自动创建 docker0 虚拟网桥,采用veth-pair虚拟设备对技术实现容器网络通信。每创建一个容器,会生成一对虚拟网卡,一端绑定容器,一端绑定 docker0 网桥,实现容器与宿主机、容器与容器之间的网络互通。

核心特点:虚拟设备转发效率高、无硬件损耗,容器删除后对应虚拟网卡自动销毁,无残留资源。

10.2 Docker四大网络模式

10.2.1 Bridge桥接模式(默认)

容器独立网络命名空间,连接 docker0 网桥,自动分配内网 IP,容器间可互通,是默认网络模式,适合绝大多数业务场景。

10.2.2 Host主机模式

容器与宿主机共享网络命名空间,无独立 IP,直接使用宿主机 IP 和端口,网络性能最优,适合高并发、端口固定的服务。

bash 复制代码
# 指定host网络模式启动容器
docker run -d --name nginx-host --net=host nginx:1.24.0

10.2.3 None封闭模式

容器仅保留回环网卡,无任何网络配置,完全隔离外网和内网,安全性极高,适合纯本地运行、无需网络交互的任务。

bash 复制代码
docker run -d --name test-none --net=none centos:7

10.2.4 Container共享模式

新容器与已有容器共享网络命名空间,共用 IP 和端口,适合服务附属容器(日志收集、监控组件)。

bash 复制代码
# 与已有nginx容器共享网络
docker run -d --name nginx-log --net=container:nginx-web centos:7

10.3 容器互联与自定义网络

10.3.1 --link容器互联

实现容器间通过容器名称通信,无需依赖固定IP,解决IP变动导致的服务连接失败问题

bash 复制代码
# 启动数据库容器
docker run -d --name mysql-link mysql:5.7

# 启动项目容器,关联数据库容器
docker run -d --name web-link --link mysql-link:mysql springboot-demo:1.0

10.3.2 自定义网桥网络(生产推荐)

自定义专属网段与网桥,隔离不同业务容器,提升网络安全性与稳定性

bash 复制代码
# 1. 创建自定义网络,指定网段、网关
docker network create --driver bridge --subnet=192.168.100.0/24 --gateway=192.168.100.1 biz-network

# 2. 查看所有网络
docker network ls

# 3. 容器接入自定义网络
docker run -d --name web-biz --net biz-network -p 8080:8080 springboot-demo:1.0

# 4. 查看网络详细信息
docker network inspect biz-network

十一、Docker 镜像仓库管理

11.1 镜像仓库分类

  • Docker Hub公共仓库:官方公共仓库,免费存储开源镜像,适合个人学习

  • 阿里云ACR仓库:国内加速镜像仓库,支持免费私有镜像存储,企业开发首选

  • 企业私有仓库:自建Registry仓库,存储内部业务镜像,保障数据安全

11.2 镜像提交与打包推送

11.2.1 容器提交为镜像

将运行中的容器修改内容,保存为新镜像,适合快速封装定制化环境

bash 复制代码
# 提交容器为镜像
docker commit -m "新增项目配置" -a "Java-Dev" springboot-web springboot-custom:1.0

11.2.2 推送镜像到阿里云ACR

bash 复制代码
# 1. 登录阿里云镜像仓库
docker login registry.cn-hangzhou.aliyuncs.com -u 你的阿里云账号

# 2. 镜像标签重命名(适配仓库地址)
docker tag springboot-custom:1.0 registry.cn-hangzhou.aliyuncs.com/自定义命名空间/springboot:1.0

# 3. 推送镜像到远程仓库
docker push registry.cn-hangzhou.aliyuncs.com/自定义命名空间/springboot:1.0

# 4. 从远程仓库拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/自定义命名空间/springboot:1.0

十二、Docker 核心架构与底层原理

12.1 C/S架构模型

Docker 采用标准客户端/服务端(C/S)架构:

  • 服务端(Docker Daemon):后台守护进程,监听客户端请求,负责镜像构建、容器创建、资源调度等核心操作

  • 客户端(Docker Client):用户执行 docker 命令的终端,通过 RESTful API 与服务端通信,发送操作指令

12.2 联合文件系统(UnionFS)原理

UnionFS 是 Docker 镜像分层存储的底层核心,支持将多个文件系统分层叠加、统一挂载展示。所有镜像层只读、独立存储,共享底层基础层,极大节省磁盘空间、提升镜像复用效率。

分层核心优势:

  • 底层镜像更新后,所有依赖该镜像的上层镜像自动同步基础环境

  • 相同基础层镜像共享存储,无需重复占用磁盘空间

  • 构建缓存复用,未变更层级无需重新构建,大幅提升构建速度

十三、Docker Compose 多容器编排实战

13.1 Docker Compose 核心认知

在实际业务部署中,一个完整应用通常包含多个容器(如 Nginx、SpringBoot、MySQL、Redis),若手动逐个启动、配置端口、关联网络、挂载数据,操作繁琐且易出错,无法统一管理服务生命周期。

Docker Compose 是 Docker 官方推出的多容器编排工具 ,专为单主机多容器应用设计,核心作用是通过一个标准化的 docker-compose.yml 配置文件,统一定义所有服务的镜像、端口、数据卷、网络、依赖关系、启动规则,实现一键启动、一键停止、一键重启整套应用服务,彻底解决多容器运维繁琐问题。

核心定位:批量管理多容器、标准化多服务部署、简化微服务单机运维,是 Java 项目、中小型微服务部署的必备工具。

核心特性:

  • 单一文件管理所有服务配置,环境统一、可复用、可版本控制

  • 自动创建专属网络,实现服务间通过服务名互通,无需配置固定IP

  • 支持启动顺序、服务依赖、健康检查,解决服务启动报错问题

  • 一键启停整套服务,无需逐个操作容器,运维效率大幅提升

13.2 Docker Compose 安装与验证

新版 Docker 已默认集成 Compose 插件,无需单独安装,旧版本需手动安装,以下为通用安装与验证命令(CentOS/Ubuntu 通用)。

bash 复制代码
# 1. 查看Compose版本(验证是否安装成功)
docker compose version

# 2. 若未安装,执行一键安装命令
yum install -y docker-compose-plugin

# 3. 安装完成后再次验证,输出版本号即成功
docker compose version

注意:新版命令为 docker compose(无横线),旧版为 docker-compose(有横线),语法完全兼容,推荐使用新版命令。

13.3 docker-compose.yml 核心语法详解

docker-compose.yml 是 Compose 的核心配置文件,采用 YAML 语法,层级严格、缩进敏感(必须使用2个空格缩进,禁止使用Tab),核心包含五大核心模块:services、networks、volumes、configs、secrets,日常开发重点使用前三者。

13.3.1 核心顶级模块

  • version:指定Compose配置文件版本,适配Docker版本,推荐3.8及以上通用版本

  • services:核心模块,定义所有需要编排的容器服务(每个服务对应一个容器)

  • networks:自定义网络配置,实现服务隔离与互通

  • volumes:统一声明数据卷,实现容器数据持久化

13.3.2 服务(services)常用核心参数

yaml 复制代码
# 示例:单服务完整配置模板
version: "3.8"  # 配置文件通用版本
services:
  # 服务名称(自定义,服务间通信的域名)
  springboot-app:
    image: springboot-demo:1.0  # 指定镜像名称:版本
    container_name: springboot-compose  # 自定义容器名称
    ports:
      - "8080:8080"  # 端口映射 宿主机端口:容器端口
    volumes:
      - app-logs:/home/app/logs  # 挂载具名数据卷
      - ./config:/home/app/config  # 挂载宿主机目录
    environment:  # 配置环境变量
      - SERVER_PORT=8080
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/test_db?useUnicode=true&characterEncoding=utf-8
      - SPRING_DATASOURCE_USERNAME=root
      - SPRING_DATASOURCE_PASSWORD=Root@123456
    depends_on:  # 服务依赖,指定启动顺序
      - mysql
    restart: always  # 容器重启策略,异常自动重启
    networks:
      - app-network  # 加入自定义网络
    healthcheck:  # 服务健康检查(精准控制启动依赖)
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 10s
      timeout: 5s
      retries: 3

# 自定义网络
networks:
  app-network:
    driver: bridge

# 声明数据卷
volumes:
  app-logs:

关键参数详解:

  • depends_on:定义服务启动依赖,当前服务会在依赖服务启动后再启动,但仅控制启动顺序,不等待依赖服务初始化完成

  • healthcheck:健康检查机制,弥补depends_on缺陷,确保依赖服务完全启动就绪后再启动当前服务,生产必备

  • restart:重启策略,always代表容器退出、服务器重启后自动拉起服务,保障服务高可用

  • 服务名通信 :同一自定义网络下,服务可直接通过服务名称相互访问,无需使用IP地址

13.4 实战:SpringBoot+MySQL+Nginx 多容器完整编排

搭建企业常用完整业务架构:Nginx反向代理 + SpringBoot后端服务 + MySQL数据库,通过Compose一键编排部署,包含端口映射、数据持久化、服务依赖、健康检查、网络隔离全套配置。

13.4.1 项目目录结构

bash 复制代码
/home/docker-compose-demo
├── docker-compose.yml  # 核心编排配置文件
├── nginx/
│   └── nginx.conf      # Nginx反向代理配置文件
├── mysql/
│   └── init.sql        # MySQL初始化脚本
└── app.jar             # SpringBoot项目jar包

13.4.2 编写Nginx配置文件(nginx.conf)

nginx 复制代码
user nginx;
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;

    # 反向代理配置,转发请求到SpringBoot服务
    server {
        listen 80;
        server_name localhost;

        location / {
            # 直接使用compose服务名通信
            proxy_pass http://springboot-app:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

13.4.3 编写MySQL初始化脚本(init.sql)

sql 复制代码
# 创建项目数据库
CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 创建测试表
USE test_db;
CREATE TABLE IF NOT EXISTS user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    age INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 插入测试数据
INSERT INTO user(username,age) VALUES ('test',20);

13.4.4 编写核心docker-compose.yml配置

yaml 复制代码
version: "3.8"

# 定义所有业务服务
services:
  # 1. MySQL数据库服务
  mysql:
    image: mysql:5.7
    container_name: mysql-compose
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=Root@123456
      - MYSQL_DATABASE=test_db
    volumes:
      - mysql-data:/var/lib/mysql  # 数据持久化
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql  # 初始化脚本
    restart: always
    networks:
      - app-network
    # MySQL健康检查,确保数据库完全启动
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-uroot", "-pRoot@123456"]
      interval: 10s
      timeout: 5s
      retries: 5

  # 2. SpringBoot后端服务
  springboot-app:
    build: .  # 基于当前目录Dockerfile构建镜像
    container_name: springboot-compose
    ports:
      - "8080:8080"
    depends_on:
      mysql:
        condition: service_healthy  # 等待MySQL健康检查通过再启动
    environment:
      - SERVER_PORT=8080
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/test_db?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
      - SPRING_DATASOURCE_USERNAME=root
      - SPRING_DATASOURCE_PASSWORD=Root@123456
    restart: always
    networks:
      - app-network

  # 3. Nginx反向代理服务
  nginx:
    image: nginx:1.24.0
    container_name: nginx-compose
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf  # 挂载自定义配置
    depends_on:
      - springboot-app
    restart: always
    networks:
      - app-network

# 自定义统一网络
networks:
  app-network:
    driver: bridge

# 统一声明数据卷
volumes:
  mysql-data:

13.4.5 编写SpringBoot服务Dockerfile

在项目根目录创建Dockerfile,用于构建SpringBoot项目镜像

bash 复制代码
FROM openjdk:8-jdk-alpine
MAINTAINER Java-Dev Team
WORKDIR /home/app
COPY app.jar app.jar
ENV JAVA_OPTS="-Xms256m -Xmx512m"
EXPOSE 8080
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar app.jar"]

13.5 Docker Compose 高频实操命令

所有命令需在docker-compose.yml所在目录执行,核心命令全覆盖,适配日常运维。

bash 复制代码
# 1. 后台启动所有服务(常用,生产必备)
docker compose up -d

# 2. 查看所有服务运行状态
docker compose ps

# 3. 实时查看所有服务日志(排查问题必备)
docker compose logs -f

# 4. 查看指定服务日志
docker compose logs -f springboot-app

# 5. 重启指定服务
docker compose restart springboot-app

# 6. 停止所有服务,不删除容器、网络、数据卷
docker compose stop

# 7. 启动已停止的服务
docker compose start

# 8. 停止并删除所有容器、网络(保留数据卷和镜像)
docker compose down

# 9. 停止并删除所有容器、网络、数据卷(彻底清空环境)
docker compose down -v

# 10. 重新构建镜像并启动服务(修改配置/代码后生效)
docker compose up -d --build

13.6 生产环境核心优化与避坑指南

13.6.1 服务启动顺序优化

单纯使用 depends_on 仅能控制容器启动顺序,无法保证服务初始化完成,极易出现数据库未初始化完成、业务服务连接失败的问题。生产环境必须搭配 healthcheck 健康检查 + condition: service_healthy,精准控制服务启动时机,确保依赖服务完全就绪后再启动当前服务。

13.6.2 数据持久化优化

数据库、日志类数据必须使用具名数据卷 或固定宿主机路径挂载,禁止使用匿名挂载。执行 docker compose down 不会删除具名数据卷,避免误操作导致数据丢失,保障生产数据安全。

13.6.3 网络通信优化

统一使用 Compose 自定义网络,默认隔离外部容器,仅当前编排服务互通,安全性更高;服务间通信强制使用服务名代替IP地址,避免容器重启IP变动导致服务连接异常。

13.6.4 生产重启策略配置

所有业务服务统一配置 restart: always,服务器重启、容器异常退出后自动拉起服务,无需人工干预,保障服务7*24小时可用。

13.6.5 常见报错避坑

  • YAML文件缩进错误:必须使用2个空格,禁止Tab键,缩进层级严格对应

  • 端口冲突:启动前检查宿主机端口是否被占用,避免端口映射失败

  • 权限不足:挂载宿主机目录时,确保目录权限足够,可临时添加 --privileged=true 提升权限

  • 镜像不存在:确保配置的镜像名称、版本本地存在,或配置正确的镜像拉取地址

相关推荐
JunLa1 小时前
Java语法糖
java·python·哈希算法
灰灰勇闯IT1 小时前
pto-isa:昇腾 Graph Compiler 的虚拟指令集
linux·运维·服务器
发光小北1 小时前
单通道串口服务器如何应用?
运维·服务器·单片机
Mr.Java.1 小时前
Spring AI MCP Server分布式翻车现场:Streamable协议的甜蜜与危险,以及无状态救赎
java·后端·spring·ai·负载均衡
夕除1 小时前
spring boot 11
java·spring boot·后端
我是谁??1 小时前
【5】基于 Docker + YOLOv8 环境实现模型量化(GTX1660S + Ubuntu22.04)
yolo·docker·容器
水木流年追梦1 小时前
大模型入门-RL基础
开发语言·python·算法·leetcode·正则表达式
TechPioneer_lp1 小时前
就业指导|中九非科班毕业,华为 OD 做 Java 后端想转 C++,能找到深度学习挂钩的岗工作吗?
java·c++·华为od·华为·就业指导·校招指导
.千余1 小时前
【Linux】Socket编程UDP
linux·运维·服务器·开发语言·网络协议·学习·udp