更新Docker安装、镜像、Dockerfile和Compose等文档内容

This commit is contained in:
yeasy
2026-03-29 11:40:34 -07:00
parent 59bfe9cff6
commit 3bad07c41a
21 changed files with 265 additions and 8 deletions
+10
View File
@@ -2,6 +2,16 @@
本节将通过一个简单的 Web 应用例子带你快速体验 Docker 的核心流程构建镜像运行容器
### 为什么选择 Nginx + HTML 作为入门例子
在学习 Docker 之前我们先来理解为什么这个例子是最适合初学者的Docker 的核心价值在于**一致性交付**无论你在本地云端还是他人的机器上运行容器应用的行为都是完全一致的这个 Nginx + 静态 HTML 的例子之所以被广泛采用是因为它展现了 Docker 工作流的三个核心阶段
1. **镜像定义Image Layer**通过 Dockerfile 描述如何把应用打包成一个自包含的单元
2. **镜像构建Build**执行 `docker build`Docker 根据 Dockerfile 逐层构建镜像
3. **容器运行Runtime**通过 `docker run` 启动容器实例应用真正开始提供服务
Nginx 是一个轻量级使用广泛的 Web 服务器学习完这个例子后你可以轻松扩展到部署 Node.jsPythonGo 等任何语言的应用
### 1.1.1 准备代码
创建一个名为 `hello-docker` 的文件夹并在其中创建一个 `index.html` 文件
+11
View File
@@ -2,6 +2,17 @@
Ubuntu Docker 最常用的运行环境之一本节将介绍如何在 Ubuntu 系统上安装 Docker并配置国内镜像加速
### 为什么推荐 APT 源安装而不是脚本
虽然 Docker 官方提供了便捷的安装脚本`get.docker.com`但笔者在生产环境中**强烈推荐 APT 源安装**原因如下
- **版本管理**通过 APT 源安装的 Docker后续可以像管理其他系统软件包一样进行更新和版本管理
- **安全补丁**Ubuntu 官方仓库会及时推送 Docker 的安全更新这在生产环境中至关重要
- **一致性**同一 Ubuntu 版本上的团队成员安装的 Docker 版本完全一致避免了"在我的机器上可以运行"的问题
- **卸载干净**APT 包管理系统会负责清理所有相关文件脚本安装的清理往往不够彻底
如果你只是想快速尝试 Docker脚本安装没有问题但一旦涉及持久运维APT 源是更成熟的选择
> 警告切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker
### 3.1.1 准备工作
+4
View File
@@ -2,6 +2,10 @@
Debian 以其稳定性著称 Docker 的理想宿主系统本节将指导你在 Debian 上完成 Docker 的安装
### APT 源安装的必要性
Ubuntu 类似Debian 用户在安装 Docker 时同样应该优先选择 APT 源安装Debian 对系统稳定性的极致追求使得通过官方仓库来管理 Docker 生命周期变得尤为重要特别是在服务器环境APT 源提供的版本控制和安全更新流程是不可或缺的
> 警告切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker
### 3.2.1 准备工作
+4
View File
@@ -2,6 +2,10 @@
Fedora 作为技术前沿的 Linux 发行版 Docker 有着良好的支持本节介绍在 Fedora 上的安装步骤
### YUM/DNF 源安装的策略建议
Fedora 的快速发布周期 6 个月发布新版本决定了它的用户群体多为开发者和技术爱好者虽然通过 DNF 可以直接安装 Docker但笔者建议仍然通过 Docker 官方 YUM 源进行安装原因是Fedora 官方仓库的 Docker 版本往往滞后而官方源能确保你获得最新的 Docker 功能和安全补丁特别是在开发环境需要用到最新 Docker 特性时这一点显得尤为重要
> 警告切勿在没有配置 Docker dnf 源的情况下直接使用 dnf 命令安装 Docker
### 3.3.1 准备工作
+4
View File
@@ -2,6 +2,10 @@
CentOS (及其替代品 Rocky LinuxAlmaLinux) 是企业级服务器常用的操作系统本节介绍在这些系统上安装 Docker 的步骤
### 企业级部署的版本选择
值得注意的是**CentOS 8 已停止维护CentOS 7 已停止支持**如果你正在规划新的生产部署强烈建议选择 Rocky Linux AlmaLinux这两个项目是由社区维护的 CentOS 替代品延续了 CentOS 的企业级特性同时提供了更长的生命周期承诺选择稳定的基础系统才能为 Docker 的长期运维奠定坚实基础
> 警告切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker
### 3.4.1 准备工作
+20
View File
@@ -2,6 +2,26 @@
树莓派等 ARM 架构设备在物联网和边缘计算领域应用广泛本节介绍如何在树莓派上安装 Docker
### 树莓派运行 Docker 的现实考虑
树莓派是 Docker 在边缘计算的一个优秀用例但在安装前笔者建议你了解几个实际情况
**性能特性**
- Raspberry Pi 4 及以上才能流畅运行 Docker 和基本容器
- Raspberry Pi Zero 2 可以运行但性能受限
- 磁盘 I/O 是主要瓶颈特别是使用 microSD 卡时
**镜像可用性**
- 并非所有 Docker 镜像都有 ARM 版本arm64 armv7
- 官方镜像通常提供多架构支持但第三方镜像可能没有
- 某些依赖 Intel 特定指令的应用无法在 ARM 上运行
**存储和内存**
- 容器镜像会占用较多存储空间128GB microSD 卡建议最多运行 3-4 个中等大小的容器
- 512MB 1GB 内存的树莓派运行多个容器会非常吃力
**实践建议**树莓派 Docker 部署最适合轻量级应用单个微服务监控代理Web 服务器等复杂多容器应用还是应该部署在性能更强的硬件上
> 警告切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker
### 3.5.1 系统要求
+13
View File
@@ -1,5 +1,18 @@
## 3.7 macOS
### Mac 用户的特殊考虑
macOS 上没有原生 Linux 内核Docker 需要运行在一个轻量级虚拟机中Docker Desktop 完全封装了这个复杂性 Mac 用户可以像 Linux 用户一样使用 Docker但有几点需要特别了解
**性能特性**
- Apple SiliconM 系列芯片 Intel Mac 的性能更好且拥有原生支持
- 文件 I/O 性能macOS 与容器之间的卷挂载性能不如 Linux这是虚拟化的代价
- 内存使用Docker Desktop 本身会消耗一定内存用于虚拟机管理
**许可考虑**
- 个人开发和小团队可免费使用
- 商业企业需要关注许可费用
### 3.7.1 系统要求
[Docker Desktop for Mac](https://docs.docker.com/desktop/setup/install/mac-install/) 支持当前版本及前两个主要版本的 macOS,并且至少需要 4 GB 内存。对于 Apple Silicon 机型,若需要兼容部分 Intel 命令行工具,官方建议安装 Rosetta 2。
+17
View File
@@ -2,6 +2,23 @@
Windows 平台上Docker Desktop 提供了完整的 Docker 开发环境本节介绍在 Windows 10/11 上的安装和配置
### Windows 上的 Docker运行原理理解
macOS 类似Windows 也没有原生 Linux 容器支持Docker Desktop for Windows 有两种运行后端可选
**WSL 2Windows Subsystem for Linux 2** - 推荐
- 利用 Hyper-V 虚拟化运行真正的 Linux 内核
- 性能更好文件系统集成更深
- 现代 Windows 10/11 的标准选择
- 支持在 Linux Windows 之间的无缝文件访问
**Hyper-V** - 传统方案
- 纯虚拟化方式
- 性能略低于 WSL 2
- 在某些企业网络环境下仍被使用
**实践建议**如果你的系统支持 WSL 2强烈推荐使用 WSL 2在安装 Docker Desktop 如果 WSL 2 环境检测无问题安装程序会自动使用 WSL 2
### 3.8.1 系统要求
[Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/) 支持 Docker 官方文档列出的受支持 Windows 10/11 64 位版本。若使用 WSL 2 后端,需要启用 WSL 2,并满足官方要求的 `WSL 2.1.5` 或更高版本;若使用 Hyper-V 后端,则需要启用 Hyper-V 和 Containers 功能。Windows 10 64 位支持 Enterprise、Pro 和 Education 22H2 (build 19045)Windows 11 64 位支持 Enterprise、Pro 和 Education 23H2 (build 22631) 或更高版本。
+29
View File
@@ -4,6 +4,35 @@ Docker 分为 `stable` `test` 和 `nightly` 三个更新频道。
官方网站上有各种环境下的[安装指南](https://docs.docker.com/get-docker/),这里主要介绍 Docker 在 `Linux`、`Windows 10` 和 `macOS` 上的安装。
## 安装方式选择指南
在开始安装前笔者建议你根据以下决策树选择最合适的安装方式
### 生产环境 vs 开发环境
**生产环境**服务器部署
- 优先使用**官方 APT/YUM 源安装**UbuntuDebianFedoraCentOS
- 优势获得官方安全更新长期技术支持版本管理清晰
- 安装步骤稍多一些但这种"麻烦"是值得的它为你的生产系统争取了稳定性和可维护性
**开发环境**本地开发机测试服务器
- 使用**脚本自动安装****包管理器直接安装**
- 如果你想快速上手官方脚本`get.docker.com`是最便捷的选择
- 国内用户注意这一步一定要选对镜像源否则网络卡顿会严重影响体验
### 国内用户的网络优化建议
值得注意的是国内直接访问 Docker 官方源速度较慢建议
- **安装过程**使用阿里云腾讯云等国内镜像源
- **镜像拉取**安装完成后配置 Docker 镜像加速器详见 [3.9 镜像加速器](3.9_mirror.md)这一步对日常开发的体验提升最明显
### 特殊场景
- **Raspberry Pi/ARM 平台** [3.5 Raspberry Pi](3.5_raspberry-pi.md)
- **离线环境** [3.6 Linux 离线安装](3.6_offline.md)
- **macOS/Windows**Docker Desktop 是官方推荐的一站式解决方案
- **需要实验特性** [3.10 开启实验特性](3.10_experimental.md)
## 详细安装指南
* [Ubuntu](3.1_ubuntu.md)
+1 -1
View File
@@ -17,6 +17,6 @@ Docker 运行容器前需要本地存在对应的镜像,如果本地不存在
* [镜像的实现原理](4.7_internal.md)
> **版本提示镜像存储后端的变迁**
>
>
> Docker Engine v29 及后续版本中Docker 全新安装默认启用了 **containerd image store**替代了传统的 classic store这一底层架构级别的变迁意味着 Docker 解锁了对 OCI Image Index Attestations 例如原生的 provenance 来源证明与 SBOM 软件物料清单的全量本地支持
> 读者在执行类似 `docker buildx build --provenance=mode=min --sbom=true` 甚至使用后续审查工具 `docker buildx imagetools inspect`其元数据能够与镜像数据一并完好地管理于本地存储系统中为供应链安全验证补齐了最后一块拼图
+22
View File
@@ -6,6 +6,28 @@
大部分时候并不需要严格区分这两者的概念
## 为什么需要私有仓库
在讨论具体的安装和配置前让我们先理解**什么时候你应该建设私有仓库**
**开发团队**有专利代码不能公开
- 需要私有仓库存储内部镜像
- 涉及访问控制和审计
- 强烈推荐使用托管方案 Harbor 或云厂商提供的镜像仓库
**开源项目或个人学习**
- Docker Hub 公开仓库足够
- 无需自建私有仓库的成本
**企业级部署**
- 需要高可用备份灾难恢复
- 推荐使用专业级方案Nexus 3Harbor而非简单的 Registry
本章涵盖的方案从简到复杂
- Docker Registry最小化部署适合简单场景
- 私有仓库高级配置添加认证HTTPS 等生产必需项
- Nexus 3企业级完整解决方案支持权限管理备份等
## 本章内容
* [Docker Hub](6.1_dockerhub.md)
+11
View File
@@ -1,5 +1,16 @@
## 7.1 RUN 执行命令
### 何时使用 RUN
`RUN` Dockerfile 中最常用的指令主要用于在镜像构建阶段执行命令来修改镜像具体来说
- **安装依赖**`RUN apt-get install nginx`
- **编译程序**`RUN gcc -o app main.c`
- **下载文件**`RUN curl -O https://example.com/file.tar.gz`
- **配置系统**`RUN mkdir -p /app/data`
理解 RUN 的核心是理解**镜像分层**每一个 RUN 都会在当前层之上创建新的一层这会影响镜像大小因此合理使用 RUN特别是合并多个 RUN是构建轻量级镜像的关键
### 7.1.1 基本语法
```docker
+11
View File
@@ -1,5 +1,16 @@
## 7.2 COPY 复制文件
### 何时使用 COPY
`COPY` 是在构建镜像时将构建上下文Dockerfile 所在目录及其子目录中的文件或目录复制到容器内的指令它是处理应用代码配置文件最常用的方式
典型场景
- 复制应用源码`COPY . /app`
- 复制配置文件`COPY nginx.conf /etc/nginx/nginx.conf`
- 复制静态资源`COPY public /app/public`
**为什么 COPY ADD 更值得推荐** 笔者建议在 90% 的情况下使用 COPY原因是 COPY 的语义更清晰它就是简单地复制文件 ADD 有额外的功能自动解压支持 URL这些功能往往会带来意外的行为除非你明确需要 ADD 的自动解压功能否则用 COPY详见 [7.3 ADD 指令](7.3_add.md) 中的详细对比
### 7.2.1 基本语法
```docker
+13 -2
View File
@@ -1,5 +1,16 @@
## 7.3 ADD 更高级的复制文件
### 何时使用 ADD何时用 COPY
在开始前让我们直言不讳**在大多数情况下你应该使用 COPY而不是 ADD**
`ADD` `COPY` 基础上增加了两个额外功能但这些功能往往引入复杂性而非便利
1. 自动解压 tar 压缩包有时你想复制一个 .tar.gz 本身 ADD 会意外地解压它
2. 支持从 URL 下载文件这个功能由于网络不稳定已被广泛认为是反模式
**实践中的建议**除非你明确需要自动解压功能比如官方基础镜像构建根文件系统否则始终使用 COPY原因很简单显式优于隐式你的 Dockerfile 6 个月后被接手维护时清晰的意图会让团队少走很多弯路
### 7.3.1 基本语法
```docker
@@ -13,7 +24,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
---
### 7.3.2 ADD vs COPY
### 7.3.2 ADD vs COPY 详细对比
| 特性 | COPY | ADD |
|------|------|-----|
@@ -23,7 +34,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
| 行为可预测性 | | |
| 推荐程度 | **优先使用** | 仅解压场景 |
> 笔者建议除非需要自动解压 tar 文件否则始终使用 COPY明确的行为比隐式的魔法更好
> **笔者建议**除非需要自动解压 tar 文件否则始终使用 COPY明确的行为比隐式的魔法更好
---
+15
View File
@@ -1,5 +1,20 @@
## 7.4 CMD 容器启动命令
### 何时使用 CMD何时使用 ENTRYPOINT
在深入 CMD 的细节之前我们需要理解一个关键问题**CMD ENTRYPOINT 应该在什么时候使用**
这是 Dockerfile 使用中最常见的困惑之一简单的答案是
- **CMD**定义容器的默认命令如果用户在 `docker run` 时提供命令CMD 会被覆盖
- **ENTRYPOINT**定义容器的入口脚本通常用于启动应用的某个特定部分
**决策树**
1. **你的容器是否有不可变的启动逻辑** 比如需要先做一些初始化工作然后才运行应用 使用 ENTRYPOINT
2. **用户经常会在 `docker run` 时传入不同的命令吗** 使用 CMD让用户灵活覆盖
3. **大多数情况下你希望容器始终以相同的方式启动** 使用 ENTRYPOINT
更多细节见 [7.5 ENTRYPOINT 指令](7.5_entrypoint.md)
### 7.4.1 什么是 CMD
`CMD` 指令用于指定容器启动时默认执行的命令它定义了容器的 主进程
+28
View File
@@ -1,5 +1,33 @@
## 7.5 ENTRYPOINT 入口点
### 何时使用 ENTRYPOINT"容器""命令"
如果说 CMD "容器中的默认程序"那么 ENTRYPOINT 就是"把容器变成一个命令"这个思维转变决定了你何时使用 ENTRYPOINT
**使用 ENTRYPOINT 的典型场景**
1. **命令行工具**你想让镜像像 `curl` `wget` 一样使用
```dockerfile
ENTRYPOINT ["curl"]
# docker run myimage http://example.com → curl http://example.com
```
2. **应用启动脚本**你有一个初始化脚本需要接收命令行参数
```dockerfile
ENTRYPOINT ["/app/entrypoint.sh"]
# docker run myimage --debug /app/entrypoint.sh --debug
```
3. ** CMD 结合**ENTRYPOINT 定义入口CMD 定义默认参数
```dockerfile
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8000"]
# docker run myimage python app.py --port 8000
# docker run myimage --port 9000 python app.py --port 9000
```
**对比 CMD**如果没有这些"把容器当命令用"的需求通常使用 CMD 就足够了
### 7.5.1 什么是 ENTRYPOINT
`ENTRYPOINT` 指定容器启动时运行的入口程序 CMD 不同ENTRYPOINT 定义的命令不会被 `docker run` 的参数覆盖而是 **接收这些参数**
+12
View File
@@ -13,6 +13,18 @@ Dockerfile 是一个文本文件,其内包含了一条条的 **指令 (Instruc
* **版本控制**Dockerfile 可以纳入版本控制系统 ( Git)便于追踪变更
* **透明性**任何人都可以通过阅读 Dockerfile 了解镜像的构建过程
## Dockerfile 编写哲学
在深入每个指令的细节之前笔者想强调一个至关重要的原则**Dockerfile 不是脚本而是镜像的"设计图"**这个区别决定了你如何思考每条指令的作用
相比编写 Bash 脚本的思维"按顺序执行这些命令"Dockerfile 的思维应该是"这一层镜像应该如何构建,下一层如何分层"这个思维转变会影响你的决策
- **合并命令**一个 `RUN apt-get update && apt-get install ...` 应该写在一起而不是分开成多个 `RUN` 指令因为它们是同一个"层"的逻辑
- **选择合适的指令**`COPY` vs `ADD``CMD` vs `ENTRYPOINT` 这些选择不是随意的而是根据镜像分层的语义来决定的
- **优化镜像大小**最后才清理缓存删除临时文件让这些"瘦身"操作在同一层完成
这个章节将详细介绍各个指令在学习指令语法时请始终思考"这个指令为什么要以这样的方式工作?如果我是 Docker,我应该如何设计它?"
## Dockerfile 基本结构
Dockerfile 一般分为四部分基础镜像信息维护者信息镜像操作指令和容器启动时执行指令
+3 -3
View File
@@ -11,7 +11,7 @@ graph TD
subgraph Host [宿主机]
eth0[物理网卡 eth0<br>192.168.1.100]
docker0[docker0 网桥<br>172.17.0.1]
subgraph Containers
subgraph ContainerA [容器 A]
eth0_A[eth0<br>172.17.0.2]
@@ -20,12 +20,12 @@ graph TD
eth0_B[eth0<br>172.17.0.3]
end
end
eth0 <--> docker0
docker0 <--> eth0_A
docker0 <--> eth0_B
end
Internet((互联网)) <--> eth0
```
本章将详细介绍 Docker 网络配置的各个方面
+22
View File
@@ -2,6 +2,28 @@
Docker Compose 提供了丰富的命令来管理项目和容器本节将详细介绍这些命令的使用格式和常用选项
### 何时用哪个命令场景化指南
在学习具体命令前让我们从使用场景出发这样可以帮助你更快地找到需要的命令
**项目启动与停止**
- `docker compose up`第一次启动项目拉取镜像创建容器
- `docker compose start`启动已停止的容器项目已存在
- `docker compose stop`优雅地停止容器不删除容器
- `docker compose down`完全清理删除容器和网络开发时常用
**调试与查看**
- `docker compose ps`查看项目中的容器状态
- `docker compose logs`查看容器日志排查问题的第一步
- `docker compose exec`进入正在运行的容器执行命令
**构建与更新**
- `docker compose build`重新构建镜像修改 Dockerfile
- `docker compose pull`更新所有镜像到最新版本
**配置验证**
- `docker compose config`验证 docker-compose.yml 格式是否正确
### 11.4.1 命令对象与格式
对于 Compose 来说大部分命令的对象既可以是项目本身也可以指定为项目中的服务或者容器如果没有特别的说明命令对象将是项目这意味着项目中所有的服务都会受到命令影响
+14 -1
View File
@@ -3,9 +3,22 @@
`Docker Compose` Docker 官方编排 (Orchestration) 项目之一负责快速的部署分布式应用
> **重要提示Compose V1 已停止支持**
>
>
> 早期基于 Python 编写的 Compose V1命令为 `docker-compose`已于 2023 年中正式停止支持现已全面升级为基于 Go 编写的 Compose V2作为 Docker CLI 的官方插件提供命令为 `docker compose`中间为空格本书强烈推荐且后续章节均以 V2 为核心标准进行讲解
## Docker Compose 解决什么问题
在学习 Compose 之前笔者想强调它的真正价值假设你正在开发一个微服务应用前端后端数据库三个服务如果你用 Docker 容器分别运行它们你会遇到这些问题
1. **启动顺序**需要先启数据库再启后端最后启前端
2. **网络连接**三个容器需要能彼此通信
3. **卷挂载**本地代码需要映射到容器内
4. **环境变量**每个服务的配置需要逐个设置
使用 `docker run` 逐个启动的话需要记住 3 条复杂的命令 **Docker Compose 的核心价值就是用一个 YAML 文件来定义整个应用**然后一条命令 `docker compose up` 启动所有服务这是 Compose 被广泛采用的原因它极大地简化了本地开发和测试的复杂性
**谁应该学 Compose** 任何使用 Docker 进行本地开发的人以及需要快速部署多容器应用的团队
本章将介绍 `Compose` 项目情况以及安装和使用
* [简介](11.1_introduction.md)
+1 -1
View File
@@ -15,7 +15,7 @@ flowchart LR
Host["Host OS"]
Guest --> Hyper --> Host
end
subgraph Container ["容器安全模型:<br/>进程隔离(轻量但需加固)"]
direction TB
Proc["容器进程<br/>(共享内核)"]