前置说明

  1. Dockerfile 是构建 Docker 镜像的脚本文件,指令必须大写,按从上到下顺序执行
  2. FROM 必须是第一条指令(注释除外)
  3. 每条指令都会生成一层镜像,尽量合并指令减少镜像层数

一、基础核心指令(必背)

1. FROM - 指定基础镜像

作用:定义构建的起点,所有镜像必须依赖基础镜像

FROM [--platform=<平台>] <镜像名>[:<标签>] [AS <别名>]

常用选项

  • --platform:指定系统架构(如 linux/amd64linux/arm64
  • AS 别名多阶段构建(精简镜像必备)

示例

# 基础用法
FROM ubuntu:22.04
# 多阶段构建(最终镜像只保留最后阶段)
FROM node:18 AS build
FROM nginx:alpine

2. LABEL - 添加镜像元数据

作用:给镜像添加描述信息(作者、版本、描述等),替代废弃的 MAINTAINER

LABEL <key>=<value> <key>=<value> ...

示例

LABEL author="张三" version="1.0" desc="SpringBoot 项目镜像"

二、环境变量指令

3. ARG - 构建参数

作用仅构建镜像时生效,容器运行后失效(用于构建时传参)

ARG <参数名>[=<默认值>]

示例

ARG VERSION=8.0
FROM mysql:${VERSION}

使用:构建时传参 docker build --build-arg VERSION=8.0 .

4. ENV - 环境变量

作用构建 + 容器运行时都生效,可被后续所有指令调用

ENV <key>=<value> <key>=<value> ...

示例

ENV JAVA_HOME=/usr/local/jdk PATH=$PATH:$JAVA_HOME/bin

三、文件操作指令(核心)

5. COPY - 复制本地文件到镜像

作用:将宿主机文件 / 目录复制到镜像内(纯复制,无额外功能)

COPY [--chown=<用户>:<用户组>] <源路径> <目标路径>

常用选项

  • --chown:指定复制后文件的所属用户 / 组(Linux 镜像必备)

示例

COPY --chown=root:root ./target/app.jar /app/

6. ADD - 增强版复制

作用:比 COPY 多两个功能:自动解压压缩包支持远程 URL 下载

ADD [--chown=<用户>:<用户组>] <源路径> <目标路径>

示例

# 自动解压 tar.gz 到镜像内
ADD jdk-17.tar.gz /usr/local/
# 下载远程文件(不推荐,会增加镜像层数)
ADD https://nginx.org/download/nginx.tar.gz /tmp/

最佳实践:优先用 COPY,仅解压时用 ADD

四、执行命令指令

7. RUN - 构建时执行命令

作用构建镜像时执行命令(安装软件、创建目录等)两种格式

1.Shell 格式(默认,自动调用 /bin/sh -c

RUN apt-get update && apt-get install -y nginx

2.Exec 格式(推荐,无 shell 环境,更轻量)

RUN ["apt-get", "update"]

避坑合并 RUN 命令,减少镜像层数

# 推荐
RUN apt-get update && \
    apt-get install -y nginx && \
    rm -rf /var/lib/apt/lists/*

五、容器运行配置指令

8. WORKDIR - 设置工作目录

作用:指定后续所有命令的执行目录,自动创建不存在的目录

WORKDIR <目录路径>

示例

WORKDIR /app
# 后续 COPY/RUN/CMD 都在 /app 目录执行
COPY app.jar .

9. USER - 指定运行用户

作用:切换容器运行的用户(默认 root,建议用普通用户提升安全性)

USER <用户名/UID>[:<用户组/GID>]

示例

RUN useradd -m appuser
USER appuser

10. EXPOSE - 声明暴露端口

作用仅声明容器要暴露的端口,不会实际发布端口(需配合 docker run -p

EXPOSE <端口号>[/协议]

示例

EXPOSE 80/tcp 443/tcp

11. VOLUME - 声明匿名数据卷

作用:声明容器内需要持久化的目录,防止数据丢失

VOLUME ["<目录路径>"]

示例

VOLUME ["/data", "/logs"]

六、容器启动命令(最重要!二选一)

12. CMD - 容器默认启动命令

作用容器启动时执行,可被 docker run 后的命令覆盖三种格式

1.Exec 格式(推荐)

CMD ["java", "-jar", "app.jar"]

2.shell格式

ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]
CMD java -jar app.jar

3.ENTRYPOINT 传参

CMD ["--param=1"]

13. ENTRYPOINT - 容器入口命令

作用固定启动命令不会被 docker run 覆盖(固定程序,只传动态参数)

# 语法(Exec 格式推荐)
ENTRYPOINT ["<执行程序>", "<参数>"]

经典组合:ENTRYPOINT + CMD

ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]
  • 启动:docker run 镜像 → 执行 java -jar app.jar
  • 传参:docker run 镜像 app-v2.jar → 执行 java -jar app-v2.jar

七、进阶指令

14. HEALTHCHECK - 健康检查

作用:检查容器是否正常运行

# 语法
HEALTHCHECK [选项] CMD <检查命令>

常用选项

  • --interval=5s:检查间隔
  • --timeout=3s:超时时间
  • --retries=3:重试次数

示例

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

5. ONBUILD - 子镜像构建触发

作用:当前镜像作为基础镜像时,子镜像构建时自动执行

ONBUILD COPY . /app

八、完整实战 Dockerfile 示例

# 1. 基础镜像
FROM openjdk:17-jdk-slim

# 2. 元数据
LABEL author="test" version="1.0"

# 3. 环境变量
ENV TZ=Asia/Shanghai
ENV APP_HOME=/app

# 4. 工作目录
WORKDIR $APP_HOME

# 5. 复制文件
COPY target/demo.jar ./app.jar

# 6. 暴露端口
EXPOSE 8080

# 7. 启动命令
ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]

九、Dockerfile 最佳实践

  1. 合并 RUN 命令,减少镜像层数
  2. 优先用 COPY,少用 ADD
  3. WORKDIR 替代 RUN mkdir
  4. 多阶段构建,精简最终镜像
  5. 清理安装缓存(rm -rf
  6. 非必要不使用 root 用户

总结

  1. 核心FROM(基础)、COPY(文件)、ENTRYPOINT/CMD(启动)
  2. 构建用 RUN运行用 CMD/ENTRYPOINT
  3. 变量用 ENV参数用 ARG
  4. 端口仅声明用 EXPOSE,数据持久化用 VOLUME

更多推荐