Dockerfile 完全指南:所有指令语法详解及实战示例

一、Dockerfile 指令全集

1. FROM

语法:FROM [–platform=][:] [AS]
说明:设置基础镜像,必须是第一条有效指令(ARG除外)
示例:

1
2
3
4
5
FROM ubuntu:20.04
# 多阶段构建时命名阶段
FROM python:3.9 AS builder
# 指定平台
FROM --platform=linux/amd64 node:16

2. RUN

语法:

Shell格式:RUN

Exec格式:RUN [“executable”, “param1”, “param2”]
说明:执行命令并创建新的镜像层
示例:

1
2
3
4
5
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
RUN ["/bin/bash", "-c", "echo hello"]

3. CMD

语法:

Exec格式(推荐):CMD [“executable”,”param1”,”param2”]

Shell格式:CMD command param1 param2

作为ENTRYPOINT参数:CMD [“param1”,”param2”]
说明:设置容器启动时默认执行的命令
示例:

1
2
CMD ["python", "app.py"]
CMD ["$HOME/run.sh"] # 变量不会展开

4. LABEL

语法:LABEL==
说明:添加元数据到镜像
示例:

1
2
3
4
LABEL version="1.0"
LABEL maintainer="dev@example.com"
LABEL description="This is a \
multi-line description"

5. EXPOSE

语法:EXPOSE[/…]
说明:声明容器运行时监听的端口
示例:

1
2
3
EXPOSE 80/tcp
EXPOSE 443
EXPOSE 3000 5000

6. ENV

语法:

ENV=

ENV(不推荐)
说明:设置环境变量
示例:

1
2
3
ENV NODE_ENV=production
ENV APP_HOME=/usr/src/app \
PATH=/usr/local/bin:$PATH

7. ADD

语法:ADD [–chown=:]
说明:复制文件/目录/URL到镜像,支持自动解压
高级特性:

1
2
3
ADD --chown=1000:1000 file.txt /app/
ADD https://example.com/file.tar.gz /tmp/
ADD hom* /mydir/ # 通配符添加

8. COPY

语法:COPY [–chown=:]
说明:复制本地文件到镜像(推荐优先使用)
与ADD区别:

1
2
COPY --chown=node:node package*.json ./
COPY ./src /app/src

9. ENTRYPOINT

语法:

Exec格式:ENTRYPOINT [“executable”, “param1”, “param2”]

Shell格式:ENTRYPOINT command param1 param2
说明:配置容器启动时运行的命令
与CMD组合:

1
2
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

10. VOLUME

语法:VOLUME [“/data”]
说明:创建挂载点并标记为外部挂载卷
重要特性:

1
2
VOLUME /var/log
VOLUME ["/data1", "/data2"]

运行时自动创建匿名卷

11. USER

语法:USER[:]
说明:设置运行用户
示例:

1
2
USER nobody
USER 1000:1000

12. WORKDIR

语法:WORKDIR /path/to/workdir
说明:设置工作目录
特点:

1
2
3
WORKDIR /app
WORKDIR src
RUN pwd # 输出/app/src

13. ARG

语法:ARG[=]
说明:定义构建时的变量
使用场景:

1
2
ARG APP_VERSION=latest
FROM nginx:$APP_VERSION

构建时:docker build –build-arg APP_VERSION=1.21

14. ONBUILD

语法:ONBUILD
说明:设置镜像被用作基础镜像时执行的指令
示例:

1
2
ONBUILD COPY . /app/src
ONBUILD RUN make /app/src

15. STOPSIGNAL

语法:STOPSIGNAL signal
说明:设置停止容器的系统信号
示例:

1
STOPSIGNAL SIGTERM

16. HEALTHCHECK

语法:

HEALTHCHECK [OPTIONS] CMD command

HEALTHCHECK NONE
选项:

1
2
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1

17. SHELL

语法:SHELL [“executable”, “parameters”]
说明:覆盖默认的shell
示例:

1
2
SHELL ["/bin/bash", "-c"]
RUN echo hello

二、VOLUME 指令深入解析

1. 基本用法

1
2
3
VOLUME ["/data"]
# 等价于
VOLUME /data

2. 多卷声明

1
VOLUME ["/var/log", "/var/db"]

3. 运行时行为

自动创建匿名卷

数据会持久化但难以管理(推荐显式挂载)

4. 最佳实践

1
2
3
4
5
# 1. 在Dockerfile中声明
VOLUME /data

# 2. 运行时绑定挂载(推荐)
# docker run -v /host/path:/container/path

三、多阶段构建完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 第一阶段:构建应用
FROM golang:1.18 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/bin

# 第二阶段:运行环境
FROM alpine:latest
WORKDIR /root/
# 从builder阶段复制二进制文件
COPY --from=builder /app/bin /usr/local/bin/
# 声明数据卷
VOLUME /data
# 设置健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD pgrep app || exit 1
# 设置非root用户
RUN adduser -D appuser && chown -R appuser /data
USER appuser
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/app"]

四、高级特性实战

1. 构建时变量与运行时变量

1
2
ARG BUILD_VERSION
ENV APP_VERSION=${BUILD_VERSION:-1.0}

2. 缓存优化

1
2
3
4
5
# 先复制依赖文件,利用缓存层
COPY package.json yarn.lock ./
RUN yarn install
# 再复制源代码
COPY . .

3. 安全加固

1
2
3
4
5
6
7
FROM alpine
RUN adduser -D myuser && \
chown -R myuser /app
USER myuser

# 禁止root登录
RUN rm -f /etc/passwd /etc/shadow

五、.dockerignore 文件

示例:

1
2
3
4
5
6
7
8
9
10
# 忽略所有.md文件
*.md
# 除README.md外的md文件
!README.md
# 忽略目录
node_modules/
.git/
# 忽略Dockerfile和.dockerignore本身
Dockerfile
.dockerignore

六、构建上下文优化

最小化上下文:

1
2
3
4
5
6
# 创建专用目录
mkdir docker-context && cd docker-context
# 只复制必要文件
cp -r ../src ./ && cp ../package.json .
# 构建
docker build -t myapp .

使用远程URL:

1
ADD https://example.com/file.tar.gz /tmp/

七、完整企业级示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# syntax=docker/dockerfile:1.4
ARG PYTHON_VERSION=3.9
FROM python:${PYTHON_VERSION}-slim as base

# 元数据
LABEL org.opencontainers.image.authors="team@example.com"
LABEL org.opencontainers.image.version="1.2.3"

# 系统设置
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1

# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# 创建工作目录
WORKDIR /app

# 安装Python依赖
COPY requirements.txt .
RUN pip install --user -r requirements.txt

# 复制应用代码
COPY . .

# 数据卷
VOLUME /app/data
VOLUME /app/logs

# 非root用户
RUN useradd -m appuser && chown -R appuser /app
USER appuser

# 健康检查
HEALTHCHECK --interval=30s --timeout=5s \
CMD curl -f http://localhost:8000/health || exit 1

# 暴露端口
EXPOSE 8000

# 启动命令
ENTRYPOINT ["python"]
CMD ["manage.py", "runserver", "0.0.0.0:8000"]

八、常见问题解决方案

1. 权限问题

1
2
3
RUN mkdir -p /data && chown -R 1000:1000 /data
VOLUME /data
USER 1000

2. 时区设置

1
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

3. 清理缓存

1
2
3
4
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*

九、性能优化技巧

构建缓存:

1
2
3
4
5
# 变化频率低的指令放前面
COPY package.json .
RUN npm install
# 变化频率高的放后面
COPY . .

多阶段构建:

1
2
3
4
5
6
7
8
9
10
FROM node:16 as build
# ...构建步骤
FROM node:16-alpine
COPY --from=build /app/dist /app
使用.dockerignore:

text
.git/
node_modules/
*.log

十、安全最佳实践

最小权限原则:

1
2
3
4
5
6
RUN adduser --disabled-password appuser
USER appuser
定期更新基础镜像:

dockerfile
FROM ubuntu:20.04 # 定期检查更新

不存储敏感数据:

1
2
3
# 错误做法
ENV DB_PASSWORD=secret
# 正确做法:运行时通过环境变量传入