Dockerfile 指令详解
约 929 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › Docker › Dockerfile 构建(在新窗口打开) › Dockerfile 指令详解
Dockerfile 是一个文本文件,包含构建镜像所需的指令。每条指令创建一个只读层。
一个最小示例
FROM alpine:3.19
RUN apk add --no-cache curl
CMD ["curl", "--version"]docker build -t my-curl .
docker run --rm my-curlFROM
指定基础镜像,必须是 Dockerfile 的第一条指令。
FROM alpine:3.19 # 精简 Linux,适合 Go/静态编译
FROM node:20-slim # Node 运行时
FROM python:3.12-slim # Python 运行时
FROM openjdk:17-jre-slim # Java 运行时
FROM nginx:alpine # Nginx 静态资源
FROM scratch # 空镜像,适合静态编译二进制选择原则:
- Alpine 基础镜像最小(~5MB),但 musl libc 可能与某些二进制不兼容。
- Slim 版基于 Debian,兼容性好,体积 ~100MB。
scratch适合完全静态编译的 Go/Rust 应用。
WORKDIR
设置工作目录,后续指令在此目录执行。
WORKDIR /app
# 相当于 RUN mkdir -p /app && cd /app最佳实践:始终在文件复制之前设置 WORKDIR,避免 RUN cd ... && ... 的链式写法。
COPY 与 ADD
COPY package.json package-lock.json ./
COPY src/ ./src/
COPY --chown=node:node . .
# ADD 额外支持自动解压和 URL
ADD app.tar.gz /app/ # 自动解压 tar
# ADD https://... /app/ # 不推荐,建议用 curl+wget+RUN始终优先使用
COPY。ADD的自动解压特性有其特定用途,但 URL 功能不推荐(不缓存、不可构建时验证)。
RUN
在构建过程中执行命令,每条 RUN 创建一个新层。
# 不推荐:每条 RUN 建一个层
RUN apt update
RUN apt install -y curl
RUN rm -rf /var/lib/apt/lists/*
# 推荐:链式 RUN,只建一层
RUN apt update && \
apt install -y curl && \
rm -rf /var/lib/apt/lists/*ENV 与 ARG
# ENV:环境变量,运行时仍然存在
ENV NODE_ENV=production
ENV APP_HOME=/app
# ARG:构建参数,仅在构建时可用
ARG VERSION=1.0.0
RUN echo "Building version $VERSION"
# ARG 可以在 docker build 时覆盖
# docker build --build-arg VERSION=2.0.0 -t myapp .EXPOSE
文档性声明,表明容器监听哪个端口。
EXPOSE 80
EXPOSE 3000/tcp
EXPOSE 3000/udp
EXPOSE不实际发布端口。运行时仍需-p 8080:80映射。
CMD 与 ENTRYPOINT
# CMD:提供默认命令,可被 docker run 覆盖
CMD ["node", "app.js"]
# docker run myapp → node app.js
# docker run myapp ls -la → ls -la
# ENTRYPOINT:定义主程序
ENTRYPOINT ["nginx", "-g", "daemon off;"]
# docker run nginx → nginx -g "daemon off;"
# docker run nginx -t → nginx -g "daemon off;" -t
# 组合使用:ENTRYPOINT 固定主程序,CMD 提供默认参数
ENTRYPOINT ["python"]
CMD ["app.py"]
# docker run myapp → python app.py
# docker run myapp test.py → python test.py| 写法 | docker run myapp | docker run myapp arg |
|---|---|---|
CMD ["cmd"] | cmd | arg(覆盖 CMD) |
ENTRYPOINT ["cmd"] | cmd | cmd arg(追加) |
ENTRYPOINT + CMD | entrypoint default_arg | entrypoint arg |
USER
以非 root 用户运行,提升安全性。
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
WORKDIR /app
COPY . .
CMD ["node", "server.js"]HEALTHCHECK
定义容器健康检查。
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1docker inspect --format '{{.State.Health.Status}}' myapp
# healthy / unhealthy / startingLABEL
添加元数据。
LABEL maintainer="team@example.com"
LABEL version="1.0.0"
LABEL description="My web application"完整示例
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "server.js"]小结
FROM必须第一条,选择尽量小的基础镜像。RUN链式合并减少层数,COPY和ADD分离操作系统包安装与源码复制以利用缓存。CMD可被覆盖,ENTRYPOINT不可覆盖但可追加参数,两者常组合使用。USER切换到非 root 提升安全性。HEALTHCHECK让 Docker 自动监控容器健康状态。EXPOSE仅作文档说明,-p才是实际端口映射。
上一节:资源限制 下一节:构建缓存与 .dockerignore
