一、Dockerfile 指令全集
1. FROM
语法:FROM [–platform=]
![]()
[:] [AS]
说明:设置基础镜像,必须是第一条有效指令(ARG除外)
示例:
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”]
说明:执行命令并创建新的镜像层
示例:
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”]
说明:设置容器启动时默认执行的命令
示例:
CMD ["python", "app.py"]
CMD ["$HOME/run.sh"] # 变量不会展开
|
4. LABEL
语法:LABEL==…
说明:添加元数据到镜像
示例:
LABEL version="1.0"
LABEL maintainer="dev@example.com"
LABEL description="This is a \
multi-line description"
|
5. EXPOSE
语法:EXPOSE[/…]
说明:声明容器运行时监听的端口
示例:
EXPOSE 80/tcp
EXPOSE 443
EXPOSE 3000 5000
|
6. ENV
语法:
ENV=…
ENV(不推荐)
说明:设置环境变量
示例:
ENV NODE_ENV=production
ENV APP_HOME=/usr/src/app \
PATH=/usr/local/bin:$PATH
|
7. ADD
语法:ADD [–chown=:]…
说明:复制文件/目录/URL到镜像,支持自动解压
高级特性:
ADD --chown=1000:1000 file.txt /app/
ADD https://example.com/file.tar.gz /tmp/
ADD hom* /mydir/ # 通配符添加
|
8. COPY
语法:COPY [–chown=:]…
说明:复制本地文件到镜像(推荐优先使用)
与ADD区别:
COPY --chown=node:node package*.json ./
COPY ./src /app/src
|
9. ENTRYPOINT
语法:
Exec格式:ENTRYPOINT [“executable”, “param1”, “param2”]
Shell格式:ENTRYPOINT command param1 param2
说明:配置容器启动时运行的命令
与CMD组合:
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
|
10. VOLUME
语法:VOLUME [“/data”]
说明:创建挂载点并标记为外部挂载卷
重要特性:
VOLUME /var/log
VOLUME ["/data1", "/data2"]
|
运行时自动创建匿名卷
11. USER
语法:USER[:]
说明:设置运行用户
示例:
USER nobody
USER 1000:1000
|
12. WORKDIR
语法:WORKDIR /path/to/workdir
说明:设置工作目录
特点:
WORKDIR /app
WORKDIR src
RUN pwd # 输出/app/src
|
13. ARG
语法:ARG[=]
说明:定义构建时的变量
使用场景:
ARG APP_VERSION=latest
FROM nginx:$APP_VERSION
|
构建时:docker build –build-arg APP_VERSION=1.21
14. ONBUILD
语法:ONBUILD
说明:设置镜像被用作基础镜像时执行的指令
示例:
ONBUILD COPY . /app/src
ONBUILD RUN make /app/src
|
15. STOPSIGNAL
语法:STOPSIGNAL signal
说明:设置停止容器的系统信号
示例:
16. HEALTHCHECK
语法:
HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE
选项:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
|
17. SHELL
语法:SHELL [“executable”, “parameters”]
说明:覆盖默认的shell
示例:
SHELL ["/bin/bash", "-c"]
RUN echo hello
|
二、VOLUME 指令深入解析
1. 基本用法
VOLUME ["/data"]
# 等价于
VOLUME /data
|
2. 多卷声明
VOLUME ["/var/log", "/var/db"]
|
3. 运行时行为
自动创建匿名卷
数据会持久化但难以管理(推荐显式挂载)
4. 最佳实践
# 1. 在Dockerfile中声明
VOLUME /data
# 2. 运行时绑定挂载(推荐)
# docker run -v /host/path:/container/path
|
三、多阶段构建完整示例
# 第一阶段:构建应用
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. 构建时变量与运行时变量
ARG BUILD_VERSION
ENV APP_VERSION=${BUILD_VERSION:-1.0}
|
2. 缓存优化
# 先复制依赖文件,利用缓存层
COPY package.json yarn.lock ./
RUN yarn install
# 再复制源代码
COPY . .
|
3. 安全加固
FROM alpine
RUN adduser -D myuser && \
chown -R myuser /app
USER myuser
# 禁止root登录
RUN rm -f /etc/passwd /etc/shadow
|
五、.dockerignore 文件
示例:
# 忽略所有.md文件
*.md
# 除README.md外的md文件
!README.md
# 忽略目录
node_modules/
.git/
# 忽略Dockerfile和.dockerignore本身
Dockerfile
.dockerignore
|
六、构建上下文优化
最小化上下文:
# 创建专用目录
mkdir docker-context && cd docker-context
# 只复制必要文件
cp -r ../src ./ && cp ../package.json .
# 构建
docker build -t myapp .
|
使用远程URL:
ADD https://example.com/file.tar.gz /tmp/
|
七、完整企业级示例
# 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. 权限问题
RUN mkdir -p /data && chown -R 1000:1000 /data
VOLUME /data
USER 1000
|
2. 时区设置
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
3. 清理缓存
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
|
九、性能优化技巧
构建缓存:
# 变化频率低的指令放前面
COPY package.json .
RUN npm install
# 变化频率高的放后面
COPY . .
|
多阶段构建:
FROM node:16 as build
# ...构建步骤
FROM node:16-alpine
COPY --from=build /app/dist /app
使用.dockerignore:
text
.git/
node_modules/
*.log
|
十、安全最佳实践
最小权限原则:
RUN adduser --disabled-password appuser
USER appuser
定期更新基础镜像:
dockerfile
FROM ubuntu:20.04 # 定期检查更新
|
不存储敏感数据:
# 错误做法
ENV DB_PASSWORD=secret
# 正确做法:运行时通过环境变量传入
|