欢迎光临
我们一直在努力

Dockerfile 指令

一.Dockerfile概述


1. 什么是 Dockerfile

Dockerfile 是一个用于构建 Docker 镜像的文本文件,其中包含一系列 指令(Instruction)。
Docker 引擎会根据这些指令,自上而下、逐条执行,最终生成一个不可变的镜像(Image)。


2. 镜像、Layer 与容器的关系

  • Docker 镜像(Image) 由多个 只读 Layer 组成
  • 每一条 Dockerfile 指令都会生成一个 Layer
  • Layer 是不可变的增量快照
  • 构建缓存、镜像复用、镜像瘦身,全部基于 Layer 机制

镜像 = 多个只读 Layer 的叠加

容器 = 镜像 + 一层可写层(Container Layer)


3. Dockerfile 到 Layer 的真实映射

示例 Dockerfile:

FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y curl
COPY app.sh /app/app.sh

生成的镜像层如下:

层号Dockerfile 指令Layer 内容
1 FROM ubuntu Ubuntu 文件系统
2 RUN apt-get update apt 缓存
3 RUN apt-get install curl 二进制
4 COPY app.sh app.sh 文件

注意:Dockerfile 不是合并执行,而是逐层叠加。


二.Dockerfile 核心指令详解

1.FROM


1.1 指令说明

FROM 用于指定当前镜像所基于的基础镜像,是 Dockerfile 中的第一条有效指令。
一个 Dockerfile 中可以存在多个 FROM(用于多阶段构建)。

基础镜像来源:

  • Docker 会优先在本地查找基础镜像
  • 本地不存在则从 Docker Hub 或私有仓库拉取
  • 镜像不存在则构建失败

  • 1.2 语法格式

    FROM [–platform=<platform>] <image>[:<tag>] [AS <name>]

    FROM [–platform=<platform>] <image>[@<digest>] [AS <name>]


    1.3 参数说明

    参数是否必需含义示例工程建议
    FROM 必需 声明新的构建阶段并指定基础镜像 FROM ubuntu 每个 Dockerfile 至少一个
    –platform 可选 指定 OS / CPU 架构 linux/amd64、linux/arm64 跨平台 / CI 推荐
    <image> 必需 基础镜像名称 openjdk、ubuntu 使用可信镜像源
    :<tag> 推荐 镜像版本标签 :11-jre 不指定则默认最新版本,生产必须指定版本
    @<digest> 可选 镜像内容哈希(不可变) @sha256:… 强一致性与安全
    AS <name> 可选 构建阶段命名 AS builder 多阶段构建必用

    1.4 示例

    FROM williamyeh/java8:latest

    FROM williamyeh/java8@sha256:174d528516a0eae5c4df69966eeb5e51d7c0dc1a532249af61013953eab1d9f3

    FROM –platform=linux/amd64 ubuntu:20.04 AS builder


    1.5 多阶段构建(Multi-stage Build)

    多阶段构建通过 多个 FROM 将构建环境与运行环境分离,仅保留最终运行所需的产物,从而:大幅减小镜像体积、降低安全风险、提高可维护性。

    ❌ 错误示例(单阶段)

    FROM openjdk:11
    RUN apt-get update && apt-get install -y maven
    COPY . /app
    WORKDIR /app
    RUN mvn package
    ENTRYPOINT ["java", "-jar", "target/app.jar"]

    问题:

    • Maven 与源码永久存在镜像中
    • 镜像臃肿,攻击面扩大

    ✅ 正确示例(多阶段构建)

    # 构建阶段
    FROM maven:3.9-eclipse-temurin-11 AS builder
    WORKDIR /build
    COPY pom.xml .
    COPY src ./src
    RUN mvn clean package -DskipTests

    # 运行阶段
    FROM openjdk:11-jre
    WORKDIR /app
    COPY –from=builder /build/target/app.jar app.jar
    ENTRYPOINT ["java", "-jar", "app.jar"]

    最终镜像仅包含 JRE 与 app.jar


    2.WORKDIR

    2.1 指令说明

    WORKDIR指令用于在 Docker 镜像内部设置工作目录。一旦设置了 WORKDIR,后续的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 这几个指令的执行环境,都会以这个目录为当前起点。

    如果一个 Dockerfile 中从未使用过 WORKDIR,那么所有指令的**默认当前目录是根目录 /。


    2.2 语法格式

    WORKDIR /path/to/workdir


    2.3 示例

    绝对路径:

    FROM ubuntu:22.04
    WORKDIR /usr/why/app
    RUN pwd
    COPY . .

    RUN 和之后的所有命令,都是在 /usr/why/app 下执行 COPY 方法则是将宿主机当前目录下所有文件,复制到 /usr/src/app 文件夹下

    相对路径:

    FROM ubuntu:22.04
    WORKDIR /app
    RUN pwd # 输出:/app

    WORKDIR why
    RUN pwd # 输出:/app/why

    WORKDIR test
    RUN pwd # 输出:/app/why/test

    设置相对路径后,依次增加追加前置的工作目录


    3.COPY

    3.1 指令说明

    COPY 用于将构建上下文中的文件或目录复制到镜像中,这些文件或目录会被添加到镜像的文件系统里,成为镜像的一部分。是最推荐使用的文件复制指令。


    3.2 语法格式

    COPY [–from=<name>] [–chown=<user>:<group>] [–chmod=<perms>] [–link] [–parents] [–exclude=<pattern>] <src>… <dest>

    COPY [–from=<name>] [–chown=<user>:<group>] [–chmod=<perms>] [–link] [–parents] [–exclude=<pattern>] ["<src>",… "<dest>"]


    3.3 参数说明

    参数作用典型使用场景备注
    –from=<stage> 从指定构建阶段复制文件 多阶段构建中复制编译产物 多阶段构建核心参数
    –chown=<user>:<group> 设置文件属主和属组 非 root 用户运行容器 优于 RUN chown
    –chmod=<perms> 设置文件权限 shell 脚本 / 可执行文件 如 755、644
    –exclude=<pattern> 排除匹配的文件 精细控制 COPY 内容 类似 .dockerignore,但更局部
    –parents 保留源文件目录结构 批量复制并保持路径 适合复制深层文件
    –link 使用硬链接代替复制 大文件/不可变文件/构建性能优化 多个 Layer 共享同一文件数据减少 IO、加快构建

    3.4 示例

    从指定构建阶段复制文件:

    COPY –from=builder /build/target/app.jar /app/app.jar

    设置文件属主和属组:

    COPY –chown=appuser:appgroup app.jar /app/app.jar

    设置文件权限:

    COPY –chmod=755 start.sh /app/start.sh

    排除匹配的文件:

    COPY –exclude=*.md –exclude=test/ . /app/

    保留源文件目录结构:

    COPY –parents src/main/resources/application.yml /app/

    使用硬链接代替复制:

    注:需开启 DOCKER_BUILDKIT=1

    COPY –link app.jar /app/app.jar

    4.ADD

    4.1 指令说明

    ADD指令时一个比COPY 指令功能更宽泛的资源引入指令,主要功能为向镜像文件系统中引入新的数据,数据内容可以来自上下文文件或远程URL,并对于某些类型的压缩文件可自动解压。


    4.2 语法格式

    ADD [–keep-git-dir] [–checksum=<checksum>] [–chown=<user>:<group>] [–chmod=<perms>] [–link] [–exclude=<pattern>] <src>… <dest>

    ADD [–keep-git-dir] [–checksum=<checksum>] [–chown=<user>:<group>] [–chmod=<perms>] [–link] [–exclude=<pattern>] ["<src>", … "<dest>"]


    4.3 参数说明

    参数作用典型使用场景备注
    –keep-git-dir 保留 .git 目录 构建时需要 Git 元信息 当 ADD 的源是 Git 仓库 时,保留 .git 目录
    –checksum=<checksum> 校验下载内容的完整性 ADD URL 资源 校验通过 URL 下载的文件是否被篡改
    –chown=<user>:<group> 设置文件属主/属组 非 root 容器 设置 ADD 后文件的属主和属组
    –chmod=<perms> 设置文件权限 脚本 / 可执行文件 如 755、644
    –link 使用硬链接而非复制 构建性能优化 多个 Layer 共享同一文件数据减少 IO、加快构建
    –exclude=<pattern> 排除匹配文件 精细控制 ADD 内容 在 ADD 时排除指定文件

    4.4 示例

    下载远程 git 链接并保留 .git 目录:

    使用 git 需启用 BuildKit

    ADD –keep-git-dir https://github.com/example/repo.git /src

    校验下载内容的完整性:

    注:url下载的文件不会解压

    ADD –checksum=sha256:abc123 https://example.com/app.tar.gz /app/

    设置文件属主/属组:

    ADD –chown=app:app app.tar.gz /app/

    设置文件权限:

    ADD –chmod=755 start.sh /app/start.sh

    使用硬链接:

    ADD –link app.tar.gz /app/

    排除匹配文件:

    ADD –exclude=*.md –exclude=test/ . /app/


    4.5 与 COPY 的对比

    对比维度COPYADD备注
    基本功能 复制本地文件/目录 复制文件 + 扩展功能 能用 COPY 就用 COPY
    是否支持 URL ❌ 不支持 ✅ 支持 url下载的文件不会解压
    是否自动解压 ❌ 否 ✅ 是 支持的格式:.tar .tar.gz .tgz .tar.bz2 .tbz2 .tar.xz .txz
    是否支持 Git 仓库 ⚠️(BuildKit 支持) 需开启 BuildKit,docker高版本自动开启
    行为可预测性 ⭐⭐⭐⭐⭐ ⭐⭐ COPY 更安全
    构建可控性 COPY 更易维护
    构建缓存稳定性 稳定 不稳定 ADD 易失效
    是否推荐用于生产 ✅ 强烈推荐 ⚠️ 谨慎 官方态度
    可读性 高(即复制) 低(可能有隐式行为) 团队友好性
    安全风险 较高 ADD 可能引入供应链风险

    5. MAINTAINER(已废弃)

    5.1 指令说明

    MAINTAINER 指令设置 Docker 镜像的制作者的个人信息。


    5.2 语法格式

    MAINTAINER <作者信息>


    5.3 示例

    MAINTAINER xiaoyangzi

    MAINTAINER xiaoyangzi <xiaoyangzi@email.com>


    6.LABEL

    6.1 指令说明

    LABEL指令为镜像添加元数据(metadata)的指令。这些元数据以键值对(key-value) 的形式存在,用于描述镜像的作者、版本、用途、来源等信息。
    LABEL 不会影响镜像的构建流程和运行行为,其主要作用是信息标注与管理。


    6.2 语法格式

    LABEL <key>=<value> <key>=<value> <key>=<value> …


    6.3 示例

    设置制作人信息:

    LABEL maintainer="xiaoyangzi <xiaoyangzi@email.com>"

    设置多个标签:

    LABEL maintainer="xiaoyangzi <xiaoyangzi@email.com>" \\
    version="1.0" \\
    description="测试镜像"


    7.ENV

    7.1 指令说明

    ENV 指令用于在 Docker 镜像构建过程中设置环境变量。这些变量会被设置在由该 Dockerfile 构建出的镜像环境里。环境变量可以在Dockerfile的许多指令中使用,包括但不限于:WORKDIR、ENV、LABEL、RUN、CMD、ENTRYPOINT、COPY、ADD等。

    当以某个镜像运行容器时,使用ENV设置的环境变量将持续存在。可以使用docker inspect 查看这些值,并使用 docker run –env <key>=<value> 来更改它们。


    7.2 语法格式

    常用形式:

    ENV <key>=<value> [<key>=<value>…]

    一对一形式(不推荐):

    ENV <key> <value>

    在 Dockerfile 中,环境变量的引用有两种方式:$variable_name 和 ${variable_name}。

    • 基本引用:使用 \\$variable_name 时,变量名后面不能紧跟字母、数字、下划线,需以空格、换行、特殊字符等来表示变量名的结束。如果变量名后面需要紧接着其他字母数字下划线,就必须使用${variable_name}形式来明确变量名的范围。
    • 括号形式:使用 \\${variable_name} 可以明确指定变量名的边界,这样可以在字符串中直接嵌入变量而不会引起歧义。
    • 转义:如果需要使用$字符本身,而不是作为变量引用,可以用\\$来转义。

    7.3 示例

    一对一形式:

    ENV NAME "XYZ"

    常用形式:

    ENV NAME="XYZ" \\
    AGE=18 \\
    gender=male

    使用示例:

    ENV NAME XYZ
    CMD echo "Hello, $NAME"
    CMD echo "Hello, ${NAME}"


    8.ARG

    8.1 指令说明

    ARG(Argument)是 Dockerfile 中用于定义构建阶段变量的指令。该变量仅在镜像构建过程中可用,用于向构建过程传递参数,而不会在容器运行时自动保留。
    ARG 的主要作用是提高 Dockerfile 的可配置性与复用性。


    8.2 语法格式

    ARG <name>[=<default value>] [<name>[=<default value>]…]

    一个 ARG 变量从它被定义的那一行开始才生效,在这行之前使用它是无效的。

    在使用 docker build 命令构建镜像时,使用 –build-arg 标志来为 ARG 变量赋值。

    docker build –build-arg <变量名>=<> –build-arg <变量名>=<> .


    8.3 示例

    定义变量

    ARG APP_ENV=dev
    ARG APP_VERSION
    ARG BUILD_TIME

    使用变量:

    与ENV使用方法相似:

    RUN echo "Environment: $APP_ENV"
    RUN echo "Version: ${APP_VERSION}"

    同样可以使用shell方式 ${APP_VERSION:-v0.0.1},如果 APP_VERSION 未被定义则默认 v0.0.1

    RUN echo "Environment: $APP_ENV"
    RUN echo "Version: ${APP_VERSION:-v0.0.1}"

    构建时传参:

    docker build \\
    –build-arg APP_ENV=prod \\
    –build-arg APP_VERSION=1.2.3 \\
    –build-arg BUILD_TIME=2025-01-01 \\
    .


    8.4 ENV和ARG的区别

    维度ARGENV
    生命周期 构建阶段(ARG在构建阶段可传参改变) 构建 + 容器运行阶段(容器期可用)
    可否在容器运行时访问
    默认值 Dockerfile 内可定义 Dockerfile 内可定义
    多阶段构建作用域 每个阶段需重新声明,或者在 FROM 前全局声明 继承上阶段,可重新定义进行覆盖
    安全性 不安全,可能出现在镜像历史 同样不安全,存在于镜像元数据
    使用场景 动态构建参数、版本号、条件编译 容器运行期配置、路径、端口、标识等

    联合使用 ARG 和 ENV

    ARG APP_ENV=dev
    ENV APP_ENV=${APP_ENV}
    RUN echo "Build environment: $APP_ENV"

    注:ARG的只会被 ENV定义的值覆盖:

    FROM ubuntu
    ARG NAME=xyz
    ENV NAME=why
    RUN echo $NAME

    FROM ubuntu
    ENV NAME=why
    ARG NAME=xyz
    RUN echo $NAME

    两个的NAME的输出均为 why


    8.5 内置 ARG 变量

    在 Dockerfile 里,有一些内置(预定义)ARG 变量,主要是为了支持构建阶段的一些特定场景。它们不是所有变量都自动存在,而是 Docker 官方定义的、可以直接使用或覆盖的构建参数。

    变量名说明可用阶段
    BUILD_DATE 构建时间(通常用来标记镜像构建时间) 构建阶段
    VCS_REF Git 提交 hash(可选,用于标记源代码版本) 构建阶段
    TARGETPLATFORM 当前构建的平台(例如 linux/amd64) 构建阶段
    BUILDPLATFORM 执行构建的宿主平台(例如 linux/amd64) 构建阶段
    TARGETOS 构建目标操作系统(例如 linux、windows) 构建阶段
    TARGETARCH 构建目标 CPU 架构(例如 amd64、arm64) 构建阶段
    TARGETVARIANT 构建目标架构的变体(例如 v7) 构建阶段

    9. RUN

    9.1 指令说明

    RUN指令用于在镜像构建阶段执行命令,并将执行结果提交为一个新的镜像层(image layer)。

    RUN = 构建时执行命令 + 固化结果到镜像中


    9.2 语法格式

    Shell 格式:

    会启动 shell 来执行命令,通常是 /bin/sh, 实际执行时会包装为 /bin/sh -c “”

    注:支持变量替换,通配符,管道,逻辑运算符等操作,可使用 $HOME、*.txt、|、&&等功能。

    RUN [OPTIONS] <command> …

    Exec 格式:

    使用一个数组来明确指定要运行的可执行文件路径以及它的参数。

    Docker 会直接调用这个可执行文件,而不通过任何默认的 Shell。

    RUN [OPTIONS] [ "<command>", … ]

    注:环境变量不会自动展开,通配符、管道和逻辑运算符无效,如不能使用 $HOME、*.txt、|、&&等功能。

    如果既想使用 Exec 格式,又需要 Shell 的特性(比如变量替换),你必须显式地调用一个 Shell:

    RUN ["/bin/bash", "-c", "echo $HOME && rm -rf *.log"]

    两种形式对比

    格式类型Dockerfile 写法是否启动 shell变量展开逻辑运算符是否支持管道是否支持重定向是否支持 glob适合复杂逻辑
    Shell 格式 RUN echo hello ✅ 是(/bin/sh -c) ✅ 非常适合
    Exec 格式 RUN [“echo”,“hello”] ❌ 否 ❌ 不适合
    OPTIONS 参数:

    以下参数仅在 BuildKit 启用时可用:

    参数作用对象解决什么问题常见取值 / 类型是否进入最终镜像典型使用场景关键注意点
    –mount 文件系统 在构建阶段临时挂载资源 type=cache 构建缓存type=bind 绑定主机或上下文文件type=secret 构建期密钥type=ssh 构建期 SSH 访问 ❌ 不会 依赖缓存私有仓库凭证SSH 拉代码 仅当前 RUN 有效构建结束即销毁
    –network 网络 控制构建期联网行为 default 默认网络none 完全断网host 使用宿主机网络 ❌ 不会 禁止隐式下载可复现构建 none 可显著提升安全性
    –security 安全策略 放宽构建沙箱限制 sandbox(默认)insecure 放宽安全限制 ❌ 不会 私有仓库 token、npm / pip 私服凭证、SSH key CI 中慎用
    –device 硬件设备 构建期访问宿主设备 /dev/kvm/dev/nvidia0 ❌ 不会 QEMU / GPU 构建 极少数场景需要

    9.3 示例

    shell 形式:

    RUN echo "Hello Docker"

    Exec 形式:

    RUN ["echo", "Hello Docker"]

    合并 RUN:

    RUN apt-get update \\
    && apt-get install -y curl \\
    && rm -rf /var/lib/apt/lists/*

    使用变量:

    ARG APP_VERSION
    RUN echo "version=$APP_VERSION"

    构建缓存:

    RUN –mount=type=cache,target=/root/.cache \\
    pip install -r requirements.txt

    绑定主机或上下文文件:

    RUN –mount=type=bind,source=requirements.txt,target=/tmp/req.txt \\
    pip install -r /tmp/req.txt

    构建期密钥:

    RUN –mount=type=secret,id=mytoken \\
    cat /run/secrets/mytoken

    构建命令:

    docker build –secret id=mytoken,src=token.txt .

    构建期 SSH 访问:

    RUN –mount=type=ssh git clone git@github.com:private/repo.git

    构建命令:

    docker build –ssh default .

    在构建阶段禁止联网

    RUN –network=none go build

    控制构建阶段的安全策略:

    RUN –security=insecure some-command

    临时暴露设备给 RUN:

    RUN –device=/dev/kvm make test

    组合使用:

    RUN –mount=type=cache,target=/root/.cache \\
    –mount=type=secret,id=npm_token \\
    –network=default \\
    npm install


    10.ENTRYPOINT

    10.1 指令说明

    ENTRYPOINT 用于定义容器启动时的固定入口程序。无论用户在 docker run 后面传什么,ENTRYPOINT 都会被执行。
    当使用 docker run 命令启动一个基于该镜像的容器时,Docker 守护进程会执行 ENTRYPOINT 所指定的命令。这个命令会成为容器的“主进程”(PID 1)。


    10.2 语法格式

    Exec 格式:

    使用字符串数组组成命令,且必须是双引号。

    ENTRYPOINT ["executable", "param1", "param2"]

    Shell 格式:

    会启动 shell 来执行命令,通常是 /bin/sh, 实际执行时会包装为 /bin/sh -c "<command>"

    ENTRYPOINT command param1 param2

    两者区别:

    对比维度Exec 格式Shell 格式
    Dockerfile 写法 ENTRYPOINT ["nginx"] ENTRYPOINT nginx
    是否启动 shell ❌ 否 ✅ 是(/bin/sh -c)
    实际执行模型 直接 execve 程序 /bin/sh -c "cmd"
    PID 1 是谁 应用程序本身 /bin/sh
    是否直接接收 SIGTERM ✅ 是 ❌ 否(可能被吞)
    是否支持优雅停止 ✅ 是 ❌(不可靠)
    信号传递可靠性 ⭐⭐⭐⭐⭐
    容器停止行为 可预测、可控 不稳定
    是否支持 $VAR
    是否支持 && / |
    是否支持重定向 >
    是否支持管道
    是否支持通配符
    是否支持 shell 内建
    CMD 是否作为参数 ✅(强) ❌(语义混乱)
    docker run 参数追加 ⚠️ 不直观
    工程可维护性 ⭐⭐⭐⭐⭐ ⭐⭐
    生产环境推荐度 ⭐⭐⭐⭐⭐
    替换 ENTRYPOINT:

    ENTRYPOINT 一般是不可变的,但是可以在启动容器时使用 –entrypoint 参数覆盖

    docker run –entrypoint bash image

    如果我们采用 –entrypoint 覆盖了 ENTRYPOINT,则 Dockerfile 中作为 ENTRYPOINT 参数的原始 CMD 命令会被忽略


    10.3 示例

    Exec 格式:

    ENTRYPOINT ["python"]

    docker run 命令实际执行
    docker run image app.py python app.py

    Shell 格式:

    ENTRYPOINT nginx -g "daemon off;"

    与CMD组合执行:

    ENTRYPOINT ["python"]
    CMD ["app.py"]

    docker run 命令实际执行
    docker run image python app.py
    docker run image other.py python other.py

    11.CMD

    11.1 指令说明

    CMD 用于为容器提供默认启动命令或默认参数。它只在容器启动时执行(docker run),不会在构建 docker build 阶段执行。

    Dockerfile 中只能有一个 CMD,如果有多个 CMD 指令,也只有最后一个会生效,并且可以被运行时参数覆盖:

    CMD ["echo", "hello"]

    docker run image echo world

    echo hello 会被 echo world 覆盖,只会输出 world。


    11.2 语法格式

    Shell 格式:

    会启动 shell 来执行命令,通常是 /bin/sh, 实际执行时会包装为 /bin/sh -c "<command>"

    CMD command param1 param2

    Exec 格式:

    使用字符串数组组成命令,且必须是双引号。

    CMD ["executable","param1","param2"]

    为 ENTRYPOINT 提供默认参数:

    和 ENTRYPOINT 指令配合使用,CMD 的作用不再是直接运行一个命令,而是为 ENTRYPOINT 指定的命令提供一组默认的参数。

    CMD ["param1","param2"]

    两者区别:

    对比维度Exec 格式Shell 格式参数格式(配合 ENTRYPOINT)
    Dockerfile 写法 CMD ["executable","arg1","arg2"] CMD command arg1 arg2 ENTRYPOINT ["exe"]CMD ["arg1","arg2"]
    是否启动 shell ❌ 否 ✅ 是(/bin/sh -c) ❌ 否
    实际执行模型 直接 execve /bin/sh -c "cmd" execve(ENTRYPOINT + CMD)
    PID 1 是谁 可执行程序 /bin/sh ENTRYPOINT 程序
    是否接收 SIGTERM ❌(不可靠)
    是否支持优雅停止
    是否支持 $VAR 有在 ENTRYPOINT 本身是 shell 时才可以。
    是否支持 && / | 有在 ENTRYPOINT 本身是 shell 时才可以。
    是否支持重定向 > 有在 ENTRYPOINT 本身是 shell 时才可以。
    是否支持 管道 有在 ENTRYPOINT 本身是 shell 时才可以。
    是否支持通配符 有在 ENTRYPOINT 本身是 shell 时才可以。
    CMD 是否可被覆盖 ✅(整体替换) ✅(整体替换) ✅(仅替换参数
    docker run 参数行为 覆盖整个 CMD 覆盖整个 CMD 追加 / 替换参数
    与 ENTRYPOINT 协作能力 一般 ⭐⭐⭐⭐⭐
    行为可预测性 ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
    生产环境推荐度 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
    典型使用场景 固定启动命令 临时调试 官方镜像、服务型容器

    11.3 示例

    Exec 形式:

    CMD ["nginx", "-g", "daemon off;"]

    Shell 形式:

    CMD nginx -g "daemon off;"

    配合 ENTRYPOINT:

    ENTRYPOINT ["nginx"]
    CMD ["-g", "daemon off;"]

    docker run实际执行
    docker run image nginx -g daemon off;
    docker run image -t nginx -t

    RUN、ENTRYPOINT、CMD 区别

    对比维度RUNENTRYPOINTCMD
    所属阶段 构建阶段(build time) 运行阶段(run time) 运行阶段(run time)
    核心作用 构建镜像内容 定义容器的固定入口程序 定义默认启动命令或参数
    是否生成镜像层 ✅ 每条 RUN 生成一层
    是否在构建时执行
    是否在容器启动时执行
    是否必须存在
    是否只能有一条 ✅(最后一条生效) ✅(最后一条生效)
    是否支持 Shell 格式 ✅(不推荐) ✅(不推荐)
    是否支持 Exec 格式 ✅(强烈推荐) ✅(推荐)
    是否启动 shell Shell 格式会 Shell 格式会 Shell 格式会
    是否支持 $VAR && | > * ✅(Shell) ❌(Exec) / ✅(Shell) ❌(Exec) / ✅(Shell)
    是否成为 PID 1 取决于是否有 ENTRYPOINT
    是否直接接收 SIGTERM ✅(Exec) ❌ / ✅(取决于 ENTRYPOINT)
    是否支持优雅停止 ✅(Exec) 依赖 ENTRYPOINT
    是否可被 docker run 覆盖 ⚠️(需 –entrypoint)
    docker run 参数行为 无意义 参数会追加 覆盖或作为参数
    与 ENTRYPOINT 的关系 定义“是什么程序” 定义“默认参数”
    典型使用次数 多次 1 次 1 次
    生产环境重要性 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐

    12.EXPOSE

    12.1 指令说明

    EXPOSE 用于声明容器在运行时“预期会监听”的端口。可以理解为一种文档化的端口声明 + 元数据提示,而不是网络规则。

    EXPOSE 指令本身只是声明端口,不会真的打开端口,也不会创建防火墙规则、让宿主机能访问、自动映射端口。


    12.2 语法格式

    默认协议是 tcp

    EXPOSE <port> [<port>/<protocol>…]


    12.3 示例

    声明端口:

    EXPOSE 80
    EXPOSE 80/tcp
    EXPOSE 53/udp
    EXPOSE 80 443

    声明多个端口:

    EXPOSE 80 443 9000


    12.4 启动示例

    -p 映射启动:

    docker run -d -p 80:7000 -p 8080:8080/udp image

    -P 启动:

    docker run -P image

    会自动映射所有 EXPOSE 的端口到宿主机的一个高端口(通常从 32768 开始)


    13.VOLUME

    13.1 指令说明

    VOLUME 用于声明容器中的某个路径是持久化数据目录。这个目录的数据不应该随着容器销毁而消失。

    工作原理:

  • Docker 会自动在宿主机上生成一个随机名字的目录,这个目录被称为“匿名卷”。(默认在 /var/lib/docker/volumes/ 下,可以通过 docker inspect 查看容器元数据找到)。
  • 将这个主机上的随机目录,与容器内部的 VOLUME 目录绑定起来。
  • 任何写入容器内 VOLUME 目录的文件,实际上都被保存在了主机上的那个随机目录里。
  • 容器被删除后,宿主机上的随机目录及其里面的数据默认不会被删除。

  • 13.2 语法格式

    单路径模式:

    VOLUME ["/data"]

    数组模式:

    VOLUME ["/var/lib/mysql", "/var/log/mysql"]


    13.3 示例

    1. VOLUME 示例

    该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个随机名称的目录与镜像目录挂载

    VOLUME ["/data"]


    2.-v 示例
    宿主机指定 volume 目录名称:

    该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个 mydata 名称的目录与镜像目录挂载

    docker run -v mydata:/data image


    宿主机指定绝对路径:

    该形式会在宿主机指定的绝对路径目录与镜像目录挂载

    docker run -v /host/data:/data image


    3.–mount type=volume 示例

    该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个 mydata 名称的目录与镜像目录挂载

    docker run –mount type=volume,source=mydata,target=/data image


    4.–mount type=bind 示例:

    该形式会在宿主机指定的绝对路径目录与镜像目录挂载

    docker run –mount type=bind,source=/host/data,target=/data image


    13.4 VOLUME、-v、–mount 区别

    以下出现的 volume 目录为宿主机Docker目录下,默认:/var/lib/docker/volumes/

    对比维度VOLUME (Dockerfile)-v–mount type=volume–mount type=bind
    定义位置 Dockerfile docker run / Compose docker run / Compose docker run / Compose
    生效时机 容器启动时 容器启动时 容器启动时 容器启动时
    目的 声明容器内持久化目录 挂载 volume 或宿主机目录 明确挂载 volume 挂载宿主机目录
    是否创建 volume ✅ 自动匿名 volume ✅ 可创建 ✅ 可创建 ❌(只能挂已有宿主机目录)
    容器路径 ✅ 必须 ✅ 必须 ✅ 必须 ✅ 必须
    宿主机路径 / source ❌ 无法指定 ✅ 可指定 ✅ volume 名称 ✅ 宿主机目录
    数据实际存储位置 宿主机 Docker volume 内部目录 /var/lib/docker/volumes/… 宿主机 Docker volume 内部目录 /var/lib/docker/volumes/…或宿主机指定目录 宿主机 Docker volume 内部目录 /var/lib/docker/volumes/… 宿主机指定目录
    是否可控
    是否影响镜像层 ✅ 切断容器目录与镜像层
    工程实践推荐度 ⚠️ 官方镜像兜底 ⚠️ 快捷方案 ✅ 工程首选 ✅ 生产挂宿主机首选

    14.SHELL

    14.1 指令说明

    SHELL 的作用只有一个:修改后续 Shell Form 指令所使用的"默认 shell"

    它影响的是这些以 shell 方式执行的指令格式:

    RUN <string>
    CMD <string>
    ENTRYPOINT <string>

    默认情况下:

    • 在 Linux 容器中,默认是 ["/bin/sh", "-c"]。
    • 在 Windows 容器中,默认是["cmd", "/S", "/C"]。

    例如当执行 RUN echo “Hello World” 时:

    • Docker 在 Linux 底层实际上执行的是:/bin/sh -c "echo \\"Hello World\\"
    • Docker 在 Windows 底层实际上执行的是:cmd /S /C "echo \\"Hello World\\"

    每个 SHELL 指令都会覆盖所有先前的 SHELL 指令,并影响所有后续指令

    注意:SHELL 不影响 Exec 形式的指令

    14.2 语法格式

    SHELL ["executable", "parameters"]

    参数说明:

    • executable:要使用的 Shell 程序的完整路径。如 /bin/bash、powershell 等。
    • parameters:传递给该 Shell 程序的参数。如 -c、 -Command等。

    14.3 示例

    Bash 常用模式:

    SHELL ["/bin/bash", "-c"]

    Bash 严格模式:

    SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]

    参数说明:

    • -e:出错即失败。
    • -u:未定义变量报错。
    • -x:打印执行命令。
    • pipefail:管道中任意失败即失败。
    • -c:后面接需要执行的命令。
    Windows 默认(cmd):

    SHELL ["cmd", "/S", "/C"]

    参数说明:

    • /S:改变 /C 后面命令字符串的解析规则,防止复杂命令容易被错误拆分或转义失败。
    • /C:执行完后面的命令字符串后立即退出。
    Windows PowerShell:

    SHELL ["powershell", "-Command"]

    PowerShell 严格模式:

    SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop';"]

    参数说明:

    • -NoProfile:启动 PowerShell 时不加载任何用户或系统 Profile 脚本。使Docker 构建要 可重复、可预测。
    • -Command:后面的字符串就是要执行的命令。
    • $ErrorActionPreference = ‘Stop’;:任何非终止性错误,都会升级为终止性错误,报错立即停止执行。

    15.USER

    15.1 指令说明

    USER 指令用于指定后续 Dockerfile 指令以及容器运行时所使用的用户和用户组。默认情况下,容器的运行身份为 root 用户。USER指令可以修改后续的 RUN、CMD、 ENTRYPOINT 等指令以哪个用户的权限来执行。

    注:可以在一个 Dockerfile 中使用多个 USER 来切换身份


    15.2 语法格式

    必须在系统 /etc/passwd 文件中定义的用户名/组

    用户名/用户组名:

    USER <user>[:<group>]

    用户ID/组ID:

    USER UID[:GID]


    15.3 示例

    创建用户并使用:

    # 创建一个用户组,指定组id为 1001,组名为 appgroup
    # 并创建一个系统用户 appuser,指定用户id为 1001,并加入 appgroup 组
    RUN groupadd -g 1001 appgroup && useradd -r -u 1001 -g appgroup appuser

    WORKDIR /app
    # 将宿主机构建上下文中的 app 文件复制到容器内(COPY 后文件一定是 root 拥有的,这是后面要 chown 的原因。)
    COPY app.sh /app/app.sh
    # 修改 /app 目录的所有权,并赋予 app.sh 可执行权限
    RUN chown -R appuser:appgroup /app && chmod +x /app/app.sh
    # 切换用户
    USER appuser
    # 执行 app.sh 文件
    CMD ["/app/app.sh"]

    切换用户:

    FROM ubuntu:22.04
    RUN whoami

    RUN useradd -r -u 1001 newuser
    USER newuser
    RUN whoami

    USER root
    RUN whoami


    16.HEALTHCHECK

    16.1 指令说明

    HEALTHCHECK指令后定义一个命令,Docker 会周期性执行它,判断容器是否健康。

    容器健康状态有三种:

    • healthy:健康
    • unhealthy:不健康
    • starting:刚启动,命令还未判断

    16.2 语法格式

    检查容器的健康状况:

    HEALTHCHECK [OPTIONS] CMD command

    参数说明:

    • –interval=DURATION:两次健康检查命令之间的时间间隔。 (默认: 30s)
    • –timeout=DURATION:单次健康检查命令的执行超时时间,如果超时则视为失败。 (默认: 30s)
    • –start-period=DURATION:容器启动后的宽限期,在这段时间内,即使健康检查失败,也不会标记容器为 unhealthy。 (默认: 0s)
    • –start-interval=DURATION:这是 Docker 20.10+ 新增参数(比 –interval 更精细)
      用于在启动期覆盖 –interval 的间隔时间 (默认: 5s`)
    • –retries=N:连续失败多少次,才把容器标记为 unhealthy (默认: 3 次)
    禁用从基础镜像继承而来的任何健康检查功能:

    用于清理基础镜像继承的 HEALTHCHECK

    HEALTHCHECK NONE


    16.3 示例

    • 检查成功 → 返回 0 → healthy
    • 检查失败 → 执行 exit 1 → 返回非 0 → unhealthy
    16.3.1 curl 方式

    两次健康检查命令之间的时间间隔:

    HEALTHCHECK –interval=10s CMD curl -f http://localhost:8080/health || exit 1

    设置单次检查超时时间:

    HEALTHCHECK –timeout=5s CMD curl -f http://localhost:8080/health || exit 1

    容器启动后的宽限期:

    HEALTHCHECK –start-period=20s CMD curl -f http://localhost:8080/health || exit 1

    设置启动器时间间隔:

    容器启动前 30 秒,每 5 秒执行一次检查;容器启动后每 30 秒执行一次检查

    HEALTHCHECK –start-period=30s –start-interval=5s –interval=30s CMD curl -f http://localhost:8080/health || exit 1

    设置连续失败多少次,把容器标记为 unhealthy:

    HEALTHCHECK –retries=5 CMD curl -f http://localhost:8080/health || exit 1

    综合示例:

    HEALTHCHECK \\
    –interval=30s \\
    –timeout=5s \\
    –start-period=20s \\
    –start-interval=5s \\
    –retries=3 \\
    CMD curl -f http://localhost:8080/health || exit 1


    16.3.2 TCP 端口检查

    使用 Netcat 命令尝试是否能够连接,可以的话则为成功

    • 优点:快速、无数据发送,适合数据库/Redis/MQ 等服务的端口探测
    • 缺点:只能判断端口是否监听,不能判断协议/服务是否真正可用

    HEALTHCHECK CMD nc -z localhost 3306 || exit 1

    参数说明:

    • nc: Netcat 工具,万能网络工具
    • -z: 端口扫描/探测模式,不发送数据,只尝试建立 TCP 连接

    16.3.3 命令/进程检查

    扫描 /proc 目录,如 Linux 内核维护的 /proc/[pid]/cmdline,pgrep 遍历进程列表,查找匹配 myservice 的进程

    HEALTHCHECK CMD pgrep myservice || exit 1

    参数说明:

    • pgrep:Process GREP 的缩写,用于在 Linux 系统中 查找正在运行的进程。
    • myservice:进程名或部分匹配字符串。

    pgrep 常用参数:

    参数含义示例
    -x 精确匹配命令名 pgrep -x nginx
    -u <user> 只匹配特定用户 pgrep -u appuser myservice
    -q 静默模式,只返回状态码 pgrep -q myservice
    -f 匹配完整命令行 pgrep -f "python /app/app.py"

    16.3.4 文件/目录检查

    HEALTHCHECK CMD test -f /app/config.yaml || exit 1

    参数说明:

    • test:内置 shell 命令,用于检查文件/字符串/数字等条件。
    • -f:判断目标是否存在且是普通文件(不是目录、链接、设备等)。

    test 扩展用法:

    参数含义示例
    -f 判断是否普通文件 test -f /app/config.yaml
    -d 判断是否目录 test -d /app/logs
    -e 判断文件或目录是否存在 test -e /app/config.yaml
    -r 文件是否可读 test -r /app/config.yaml
    -w 文件是否可写 test -w /app/config.yaml
    -x 文件是否可执行 test -x /app/app

    16.3.5 自定义脚本(复杂逻辑)

    HEALTHCHECK CMD /app/healthcheck.sh


    17.ONBUILD

    17.1 指令说明

    ONBUILD = 构建触发器,它不会在当前镜像构建时执行,而是在基于当前镜像的子镜像构建时触发执行。

    • 当前 Dockerfile:定义基础镜像
    • ONBUILD:给“使用这个镜像作为父镜像的 Dockerfile”留的指令
    • 构建此镜像时(父镜像)不执行。
    • 基于父镜像构建子镜像时才执行。

    ONBUILD 指令会在子镜像构建时首先执行,但严格来说是“在父镜像的 ONBUILD 队列中按顺序执行,紧接着子镜像自己的第一条指令之前。


    17.2 语法格式

    ONBUILD <INSTRUCTION>

    <instruction> 可以是 Dockerfile 中的常用指令,例如:COPY、ADD、RUN、ENV 等。(不支持某些特殊指令,如 FROM、ONBUILD 自己)


    17.3 示例

    17.3.1 构建示例

    构建父镜像:

    # 基础镜像
    FROM ubuntu:22.04
    ONBUILD COPY . /app
    ONBUILD RUN echo "Build triggered in child"

    构建这个镜像时:

    • ONBUILD COPY 和 ONBUILD RUN 不会执行
    • 镜像构建完成 → 生成一个带有“触发器”的镜像

    构建子镜像:

    FROM mybaseimage:latest

    构建子镜像时:

    • Docker 会自动执行父镜像的 ONBUILD 指令
    • COPY . /app → 将子镜像上下文复制到 /app
    • RUN echo … → 执行命令
    • 然后执行子镜像自己的 Dockerfile 指令

    17.3.2 典型使用场景:

    父镜像:

    # python:3.9-slim 的 Dockerfile
    ONBUILD COPY requirements.txt /app/
    ONBUILD RUN pip install -r /app/requirements.txt

    子镜像:

    FROM python:3.9-slim
    COPY . /app


    18.STOPSIGNAL

    18.1 指令说明

    当执行 docker stop 时,Docker 发送给容器主进程(PID 1)的 Unix 信号。

    注:由于 STOPSIGNAL 是对 PID 1 的主进程有效,所以在 SHELL 格式的命令时 PID 1 是 /bin/sh,如下 myapp 是子进程,STOPSIGNAL 发给 sh,sh 不一定转发信号。从而导致 STOPSIGNAL 失效

    CMD myapp
    ENTRYPOINT myapp

    写法PID 1 是谁STOPSIGNAL 是否生效
    ENTRYPOINT Exec 应用进程
    CMD Exec 应用进程
    ENTRYPOINT Shell /bin/sh ❌(通常)
    CMD Shell /bin/sh ❌(通常)

    18.2 语法格式

    STOPSIGNAL signal

    支持两种写法:

    # 信号名形式
    STOPSIGNAL SIGTERM
    # 编号形式
    STOPSIGNAL 15

    等同于在 docker run 或 docker create 时指定–stop-signal=:

    docker run –stop-signal=SIGINT my-image

    docker create –stop-signal SIGTERM my-image

    常用 Unix 信号表

    信号名编号含义默认行为常见用途
    SIGTERM 15 请求终止 终止进程 Docker 默认 stop 信号
    SIGINT 2 中断 终止进程 Ctrl+C、CLI 程序
    SIGQUIT 3 退出并生成 core 终止 + core Nginx 优雅退出
    SIGKILL 9 强制杀死 立即终止 无法捕获,兜底
    SIGHUP 1 挂起/重载 终止或重载 重新加载配置
    SIGUSR1 10 用户自定义 忽略 应用自定义控制
    SIGUSR2 12 用户自定义 忽略 应用自定义控制
    SIGPIPE 13 管道破裂 终止 写入已关闭管道
    SIGCHLD 17 子进程退出 忽略 进程回收
    SIGALRM 14 定时器超时 终止 超时控制

    18.3 示例

    18.3.1 SIGTERM:

    请求进程正常退出(可捕获、可处理),docker stop 默认发送

    STOPSIGNAL SIGTERM
    ENTRYPOINT ["myapp"]


    18.3.2 SIGINT:

    CLI 工具、通过命令行直接运行、执行完就退出的程序、运行时占着终端、用户能实时看到输出的程序

    STOPSIGNAL SIGINT
    CMD ["ffmpeg", "-i", "a.mp4", "b.mp4"]

    STOPSIGNAL SIGINT
    CMD ["node", "server.js"]

    STOPSIGNAL SIGINT
    CMD ["python", "server.py"]


    18.3.3 SIGQUIT

    Nginx 优雅退出:

    STOPSIGNAL SIGQUIT


    18.3.4 SIGKILL

    立即杀死进程,不要在 Dockerfile 里用 STOPSIGNAL SIGKILL

    docker kill mycontainer


    18.3.5 SIGHUP

    重新加载配置 / 重启逻辑

    docker kill -s HUP nginx-container

    等价于:

    nginx -s reload


    用 Bash 模拟配置重载:

    #!/bin/sh

    reload() {
    echo "Reload config at $(date)"
    }

    trap reload HUP

    echo "App started, PID $$"

    while true; do
    sleep 5
    done

    FROM alpine
    COPY app.sh /app.sh
    RUN chmod +x /app.sh
    CMD ["/app.sh"]

    docker run -d –name hup-demo hup-image
    docker kill -s HUP hup-demo

    输出:

    Reload config at 2026-01-08 …


    三.docker build 构建命令

    1. docker build 介绍

    docker build 是 Docker 客户端用于根据 Dockerfile 构建镜像(Image)的命令。
    镜像是不可变的只读模板,容器是镜像的运行实例。docker build 只负责生成镜像,不运行任何容器。


    2.docker build 的基本语法

    2.1 语法格式

    docker build [OPTIONS] PATH | URL |

    关键组成部分

    部分含义
    OPTIONS 构建参数
    PATH PATH 指的是构建上下文路径, 可以是相对路径或绝对路径
    URL Git 仓库或者 HTTP(s) 资源
    从 stdin 读取 Dockerfile

    2.2 OPTIONS 可用参数列表

    参数简述用法 / 示例备注
    -t, –tag 给生成的镜像打标签 docker build -t myapp:1.0 . 可指定多个标签,多标签镜像共享同一镜像 ID,如果不指定标签,则会生成一个随机镜像id,而不会有名字
    -f, –file 指定 Dockerfile 路径 docker build -f Dockerfile.prod . 可以是相对路径或绝对路径(如果不指定,则会在构建上下文的根目录寻找Dockerfile)
    –build-arg 构建时传入参数 docker build –build-arg VERSION=1.2.3 . 仅在 build 阶段有效,不进入最终镜像环境变量
    –cache-from 指定缓存来源镜像 docker build –cache-from myapp:cache . 用于加速构建,常与 CI/CD 配合
    –no-cache 禁用缓存 docker build –no-cache . 强制重新执行每一条 Dockerfile 指令
    –pull 强制拉取最新基础镜像 docker build –pull . 避免使用本地旧镜像
    –quiet, -q 静默构建,仅输出镜像 ID docker build -q . CI/CD 常用,减少日志输出
    –rm 构建完成后删除中间容器 默认 true 一般不用手动设置,除非调试
    –force-rm 即使构建失败也删除中间容器 docker build –force-rm . 调试时避免残留垃圾容器
    –compress 压缩发送给 daemon 的上下文 默认开启 对大文件夹有明显效果
    –isolation 设置构建隔离方式 docker build –isolation=process . Windows 平台可用,Linux 通常忽略
    –network 构建网络模式 docker build –network=host . 默认 bridge,复杂网络需求可指定
    –output, -o 构建输出到本地目录或其他后端 docker build -o type=local,dest=./out . 用于 BuildKit,支持多种输出类型
    –progress 控制日志显示方式 docker build –progress=plain . 可选 auto/plain/tty
    –secret 构建时使用 secret docker build –secret id=mysecret,src=./secret.txt . 需 BuildKit 支持,用于安全传递密码等
    –ssh 构建时使用 SSH agent docker build –ssh default . 常用于私有 Git 拉取依赖
    –platform 指定目标平台 docker build –platform linux/amd64 . 用于跨架构构建,多架构镜像
    –iidfile 将构建完成镜像 ID 写入文件 docker build –iidfile image_id.txt . CI/CD 常用
    –label 给构建的镜像打标签信息 docker build –label version=1.0 . metadata,不影响镜像 ID
    –build-context 指定额外构建上下文 docker build –build-context docs=./docs . BuildKit 支持,可引入多个上下文
    –ulimit 设置构建时的 ulimit docker build –ulimit nofile=1024:2048 . BuildKit 支持,控制资源限制

    2.3 URL 参数说明

    如执行:

    docker build -t myapp:latest https://github.com/user/repo.git

  • Docker daemon 下载远程仓库到临时目录:如果 URL 指定了 branch/tag/commit,则下载指定版本,默认是 HEAD
  • 仓库下载完成后,这个下载的内容就是构建上下文。
  • Docker daemon 读取 Dockerfile 内容,按顺序解析每条构建指令(FROM, RUN, COPY, ADD, ENV 等)。
  • 注意:Dockerfile 默认在仓库根目录下找 Dockerfile,如果文件名不是 Dockerfile,必须加 -f 指定。


    – 参数说明:

    用法描述构建上下文Dockerfile 来源示例(单元格安全)优势限制 / 注意事项
    Here Document Shell 使用 HereDoc 把 Dockerfile 内容送入 stdin 默认空 stdin docker build -t tempimage – <<EOFFROM alpineRUN echo helloEOF 无需 Dockerfile 文件,适合临时测试、教学 无上下文,不能 COPY 本地文件
    管道 echo 用 echo 输出 Dockerfile,通过管道传给 docker build 默认空 stdin echo "FROM alpine\\nRUN echo hello" | docker build – -t tempimage 最简单、脚本友好 不适合复杂 Dockerfile
    tar 方式传上下文 将目录打包为 tar,通过 stdin 传给 Docker stdin 中的 tar 包 stdin Dockerfile + 上下文 tar -czf – . | docker build – -t myimage 可在无 Dockerfile 文件情况下构建完整项目 命令复杂,调试不直观
    动态生成 Dockerfile 脚本动态生成 Dockerfile 内容 视脚本而定 stdin generate.sh | docker build – -t ci-image CI/CD 自动化利器 默认仍无上下文,需额外处理
    stdin + BuildKit 上下文 使用 BuildKit 引入额外构建上下文 多上下文 stdin docker build –build-context src=./src – < Dockerfile 解决 stdin 无上下文问题 依赖 BuildKit,复杂度高

    2.4 dockerignore 文件

    .dockerignore 是位于构建上下文根目录的配置文件,用于在构建开始之前过滤构建上下文中不需要发送给 Docker daemon 的文件和目录。防止一些大文件或者没有的文件创建到镜像中。

    如:

    .git
    .gitignore
    node_modules
    target
    dist
    *.log


    3.示例

    3.1 镜像标签

    docker build -t repo/name:tag .

    多标签:

    docker build -t app:1.0 -t app:latest .

    3.2 指定 DOckerfile

    不指定标签

    docker build -f Dockerfile.prod .

    3.3 传入构建参数

    给 Dockerfile 中的 ARG 传参

    docker build –build-arg VERSION=1.2.3 .

    3.4 禁用缓存

    docker build –no-cache .

    3.5 平台指定

    docker build –platform linux/amd64 .

    3.6 本地文件路径

    docker build -t myapp:1.0 .
    docker build -t myapp:1.0 ./docker
    docker build -t myapp:1.0 /home/user/project

    • Dockerfile:默认在 PATH 根目录下找 Dockerfile。
    • COPY / ADD:只能访问上下文里的文件,不能访问 PATH 以外的文件。
    • 性能注意:不要把不必要的大文件夹放入上下文,否则每次 build 都要上传,耗时很长。
    • 解决方案:使用 .dockerignore 忽略不需要的文件。

    3.7 Git 仓库或者 HTTP(s) 资源

    docker build -t myapp:latest https://github.com/user/repo.git
    docker build -t myapp:latest https://github.com/user/repo.git#branch-name
    docker build -t myapp:latest https://github.com/user/repo.git#commit-hash

    3.8 从标准输入读取 Dockerfile

    动态生成 Dockerfile:

    CI/CD 脚本生成 Dockerfile 内容,然后直接构建,不用在磁盘上写文件

    echo -e "FROM alpine\\nRUN echo hello" | docker build – -t myimage

    临时构建:

    # <<EOF 表示 把后续直到 EOF 的内容当作标准输入
    docker build -t tempimage – <<EOF
    FROM busybox
    RUN echo hello
    EOF

    在这里插入图片描述

    四.docker 部署 springboot 示例

    1.docker 下拉 java 镜像

    docker pull williamyeh/java8

    该镜像不必启动

    2.编写 Dockerfile 文件

    #指定基础镜像,本地没有会从dockerHub pul1下来
    FROM williamyeh/java8
    #把可执行jar包复制到基础镜像的根目录下
    ADD api-test.jar /api-test.jar
    #镜像要暴露的端口,如要使用端口,在执行docker run命令时使用-p生效
    EXPOSE 8087
    #在镜像运行为容器后执行的命令
    ENTRYPOINT ["java","-jar","/api-test.jar"]

    3.打包 jar 为镜像

    上传 jar 包到服务器 Dockerfile 文件同目录下

    docker build -f Dokcerfile -t why/api-test:v1.0 .

    参数说明:

    • -f: 指定Dockerfile文件的路径
    • -t: 指定镜像名字和TAG
    • .: 指当前目录,这里实际上需要一个上下文路径

    4.启动 api-test 镜像

    docker run -d –name api-test -p 8087:8087 why/api-test:v1.0

    我们可以在一台机器上, 部署多个该微服务, 内部同一个端口, 宿主机多个端口, 以此用来负载均衡

    docker run -d –name api-test2 -p 8088:8087 why/api-test:v1.0

    docker run -d –name api-test3 -p 8089:8087 why/api-test:v1.0

    赞(0)
    未经允许不得转载:171主机测评 » Dockerfile 指令
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址