15.7.3 构建上下文与忽略规则(.dockerignore)

构建上下文(build context)是 docker build 可访问的文件集合,来源于构建命令的路径或 Git URL。Docker 会先将上下文打包发送到守护进程,上下文越大,构建越慢、缓存命中越差,因此必须控制目录范围并用 .dockerignore 过滤无关文件。

原理草图(上下文打包与忽略规则):

文章图片

关键命令与目录组织示例#

目录结构(推荐最小上下文)

app/
├── docker/
│   ├── Dockerfile
│   └── .dockerignore
├── src/
│   └── app.py
├── requirements.txt
└── .git/

构建命令(指定上下文为 app/)

cd app
docker build -f docker/Dockerfile -t demo:ctx .

Dockerfile(仅从上下文内复制)

# 文件路径: app/docker/Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY src/ /app/src/
CMD ["python", "/app/src/app.py"]

命令解释:
-f docker/Dockerfile 指向 Dockerfile;. 表示上下文为 app/ 目录;COPY 只能读取上下文内文件。

.dockerignore 规则与示例#

.dockerignore 示例

# 文件路径: app/docker/.dockerignore
.git
__pycache__/
*.log
*.tmp
dist/
build/
node_modules/
# 排除大文件或私有配置
*.pem
.env

规则说明与预期效果
- 排除 .git/node_modules/ 可显著减少上下文体积。
- .env、密钥文件避免被打进镜像。
- 被忽略的文件无法被 ADD/COPY 使用。

构建上下文验证与排错#

1)查看上下文大小

# 观察发送上下文大小
DOCKER_BUILDKIT=0 docker build -f docker/Dockerfile -t demo:ctx . 2>&1 | grep -i "Sending build context"

预期输出包含:

Sending build context to Docker daemon  12.3MB

2)误用上下文导致 COPY 失败

# 在 Dockerfile 中写了 COPY ../secrets /app/
# 构建时报错:
COPY failed: file not found in build context or excluded by .dockerignore

原因../secrets 不在上下文内或被忽略。
修复:将 secrets 放入上下文并移除忽略规则,或通过构建参数/运行时挂载替代。

3)缓存频繁失效
- 现象:每次 pip install 都重新执行。
- 原因:COPY . /app 导致任意文件变化破坏缓存。
- 修复:先复制依赖文件,再复制代码(参考上方 Dockerfile)。

练习#

  1. app/ 目录下创建 logs/app.log,加入 .dockerignore 排除后构建,观察上下文大小变化。
  2. COPY src/ /app/src/ 改为 COPY . /app/,比较缓存命中情况。
  3. 尝试把 .env 放入上下文,构建后用 docker history 验证是否进入镜像(应通过忽略避免进入)。