Dockerfile 是 Docker 镜像构建的脚本,每条指令都会在镜像中生成一层(Layer),理解这些指令对优化镜像体积、构建速度和安全性非常重要。
1️⃣ FROM:基础镜像
-
作用:指定基础镜像。如果不指定,镜像必须完全自建。
-
语法:
FROM <image>[:<tag>] [AS <stage_name>]
-
参数:
-
<image>:镜像名,如python、ubuntu。 -
<tag>:可选,镜像版本或变体,如3.12-slim。 -
AS <stage_name>:多阶段构建时命名阶段。
-
-
注意事项:
-
如果使用
AS <stage>,后续COPY --from=<stage>可从该阶段获取文件。
-
-
示例:
FROM python:3.12-slim AS builder
2️⃣ LABEL:元数据
-
作用:为镜像添加元信息。
-
语法:
LABEL <key>=<value> ...
-
常用场景:
-
作者信息:
maintainer -
版本号:
version -
描述:
description
-
-
示例:
LABEL maintainer="维青 童 <weiqing@example.com>" LABEL version="1.0" LABEL description="Python web application" -
底层原理:
-
LABEL实际是镜像元数据的一部分,便于docker inspect查看。
-
3️⃣ ENV:环境变量
-
作用:定义运行时环境变量,可被镜像内所有进程使用。
-
语法:
ENV <key>=<value> ...
-
注意事项:
-
ENV 可以在后续指令中引用:
$VAR或${VAR}。
-
-
示例:
ENV APP_HOME=/app ENV PYTHONUNBUFFERED=1
4️⃣ ARG:构建参数
-
作用:定义构建时可传入的参数。
-
语法:
ARG <name>[=<default_value>]
-
注意事项:
-
ARG 只能在构建过程中使用,运行时不可见。
-
ARG 可以和 ENV 配合使用。
-
-
示例:
ARG VERSION=1.0 ENV APP_VERSION=$VERSION
5️⃣ WORKDIR:工作目录
-
作用:指定镜像内工作目录。
-
语法:
WORKDIR /path/to/workdir
-
注意事项:
-
目录不存在会自动创建。
-
后续所有相对路径操作(COPY、RUN、CMD)基于此目录。
-
-
示例:
WORKDIR /app
6️⃣ COPY / ADD:复制文件
-
COPY
-
作用:从宿主机复制文件/目录到镜像。
-
语法:
-
COPY [--chown=<user>:<group>] <src> <dest>
-
ADD
-
作用:功能类似 COPY,但支持:
-
自动解压
.tar文件 -
支持 URL 下载
-
-
-
示例:
COPY requirements.txt ./ ADD https://example.com/file.tar.gz /tmp/
-
底层原理:
-
COPY/ADD 创建新层,增加镜像体积。
-
尽量只 COPY 必须文件,避免复制整个项目(减少缓存失效风险)。
-
7️⃣ RUN:运行命令
-
作用:在镜像构建阶段执行命令。
-
语法:
RUN <command> # shell 形式
RUN ["executable", "param1"] # exec 形式,推荐
-
示例:
RUN apt-get update && apt-get install -y curl
RUN pip install -r requirements.txt
-
注意事项:
-
每条 RUN 会创建新层,合并命令可减少层数。
-
建议使用
exec形式,避免 shell 解析问题。
-
8️⃣ USER:切换用户
-
作用:指定镜像内运行命令或容器的用户。
-
语法:
USER <user>[:<group>]
-
示例:
USER root USER appuser
-
安全建议:
-
尽量避免用 root 运行应用,降低安全风险。
-
9️⃣ EXPOSE:声明端口
-
作用:声明容器监听端口(仅文档作用,不自动开放)。
-
语法:
EXPOSE <port>[/<protocol>]
-
示例:
EXPOSE 8000/tcp
🔟 VOLUME:挂载卷
-
作用:声明容器可挂载数据卷。
-
语法:
VOLUME ["/data"]
-
注意事项:
-
容器运行时挂载外部卷,可持久化数据。
-
每次创建容器时都会生成匿名卷,如果不指定外部卷。
-
1️⃣1️⃣ ENTRYPOINT / CMD:启动命令
-
ENTRYPOINT
-
固定容器入口命令。
-
-
CMD
-
默认启动命令,可被 docker run 覆盖。
-
-
组合使用
ENTRYPOINT ["python"] CMD ["app.py"] # 实际运行: python app.py
-
注意事项:
-
推荐使用 exec 形式(数组),避免 shell 解析错误。
-
ENTRYPOINT + CMD 是推荐组合,用于参数化命令。
-
1️⃣2️⃣ HEALTHCHECK:健康检查
-
作用:定义容器运行时健康检查命令。
-
语法:
HEALTHCHECK [OPTIONS] CMD <command>
-
选项:
-
--interval:检查间隔 -
--timeout:超时 -
--retries:重试次数 -
--start-period:初始等待
-
-
示例:
HEALTHCHECK --interval=30s --timeout=5s CMD curl -f http://localhost:8000/health || exit 1
1️⃣3️⃣ 注释
-
作用:文档说明,不执行。
-
语法:
# 这是注释
1️⃣4️⃣ 多阶段构建(Multi-stage)
-
作用:减少最终镜像体积,只保留需要的文件。
-
示例:
FROM python:3.12 AS builder
WORKDIR /app
COPY . .
RUN pip install --target ./packages -r requirements.txt
FROM python:3.12-slim
COPY --from=builder /app /app
WORKDIR /app
CMD ["python", "app.py"]
-
优势:
-
依赖和构建工具不会进入最终镜像。
-
显著减小镜像体积。
-
🔹 Dockerfile 构建层次与缓存策略
-
每条指令生成一层(Layer):
-
RUN、COPY、ADD 都会生成新层。
-
-
缓存机制:
-
Docker 会使用缓存,如果上一层未改变,则复用。
-
最小化不必要修改可以加快构建速度。
-
-
优化建议:
-
将不常修改的步骤放前面。
-
合并 RUN 指令减少层数。
-
1700

被折叠的 条评论
为什么被折叠?



