更新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
+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 一般分为四部分基础镜像信息维护者信息镜像操作指令和容器启动时执行指令