一、Dockerfile 概述
1. 什么是 Dockerfile
Dockerfile 是一个用于构建 Docker 镜像的文本文件,其中包含一系列 。 Docker 引擎会根据这些指令,,最终生成一个。
Dockerfile 是构建 Docker 镜像的文本文件,包含一系列自上而下执行的指令。本文详解了 FROM、WORKDIR、COPY、ADD、ENV、ARG、RUN、ENTRYPOINT、CMD、EXPOSE、VOLUME 等核心指令的语法、参数及最佳实践,重点介绍了多阶段构建以减小镜像体积。同时涵盖了 docker build 命令的使用、构建上下文管理以及 .dockerignore 配置。最后提供了基于 Spring Boot 的 Docker 部署完整示例,帮助开发者掌握容器化应用的标准流程。

Dockerfile 是一个用于构建 Docker 镜像的文本文件,其中包含一系列 。 Docker 引擎会根据这些指令,,最终生成一个。
镜像 = 多个只读 Layer 的叠加
容器 = 镜像 + 一层可写层(Container 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 不是合并执行,而是逐层叠加。
FROM 用于指定当前镜像所基于的基础镜像,是 Dockerfile 中的第一条有效指令。
一个 Dockerfile 中可以存在多个 FROM(用于多阶段构建)。
基础镜像来源:
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>@<digest> [AS <name>]
| 参数 | 是否必需 | 含义 | 示例 | 工程建议 |
|---|---|---|---|---|
| FROM | 必需 | 声明新的构建阶段并指定基础镜像 | FROM ubuntu | 每个 Dockerfile 至少一个 |
| --platform | 可选 | 指定 OS / CPU 架构 | linux/amd64, linux/arm64 | 跨平台 / CI 推荐 |
<image> | 必需 | 基础镜像名称 | openjdk, ubuntu | 使用可信镜像源 |
:<tag> | 推荐 | 镜像版本标签 | :11-jre | 不指定则默认最新版本,生产必须指定版本 |
@<digest> | 可选 | 镜像内容哈希(不可变) | @sha256:... | 强一致性与安全 |
AS <name> | 可选 | 构建阶段命名 | AS builder | 多阶段构建必用 |
FROM williamyeh/java8:latest
FROM williamyeh/java8@sha256:174d528516a0eae5c4df69966eeb5e51d7c0dc1a532249af61013953eab1d9f3
FROM --platform=linux/amd64 ubuntu:20.04 AS builder
多阶段构建通过 多个 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"]
问题:
# 构建阶段
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
WORKDIR 指令用于在 Docker 镜像内部设置工作目录。一旦设置了 WORKDIR,后续的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 这几个指令的执行环境,都会以这个目录为当前起点。
如果一个 Dockerfile 中从未使用过 WORKDIR,那么所有指令的**默认当前目录是根目录 /。
WORKDIR /path/to/workdir
绝对路径:
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
设置相对路径后,依次增加追加前置的工作目录
COPY 用于将构建上下文中的文件或目录复制到镜像中,这些文件或目录会被添加到镜像的文件系统里,成为镜像的一部分。是最推荐使用的文件复制指令。
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>"]
| 参数 | 作用 | 典型使用场景 | 备注 |
|---|---|---|---|
--from=<stage> | 从指定构建阶段复制文件 | 多阶段构建中复制编译产物 | 多阶段构建核心参数 |
--chown=<user>:<group> | 设置文件属主和属组 | 非 root 用户运行容器 | 优于 RUN chown |
--chmod=<perms> | 设置文件权限 | shell 脚本 / 可执行文件 | 如 755、644 |
--exclude=<pattern> | 排除匹配的文件 | 精细控制 COPY 内容 | 类似 .dockerignore,但更局部 |
--parents | 保留源文件目录结构 | 批量复制并保持路径 | 适合复制深层文件 |
--link | 使用硬链接代替复制 | 大文件/不可变文件/构建性能优化 | 多个 Layer 共享同一文件数据减少 IO、加快构建 |
从指定构建阶段复制文件:
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
ADD 指令是一个比 COPY 指令功能更宽泛的资源引入指令,主要功能为向镜像文件系统中引入新的数据,数据内容可以来自上下文文件或远程 URL,并对于某些类型的压缩文件可自动解压。
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>"]
| 参数 | 作用 | 典型使用场景 | 备注 |
|---|---|---|---|
--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 时排除指定文件 |
下载远程 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/
| 对比维度 | COPY | ADD | 备注 |
|---|---|---|---|
| 基本功能 | 复制本地文件/目录 | 复制文件 + 扩展功能 | 能用 COPY 就用 COPY |
| 是否支持 URL | ❌ 不支持 | ✅ 支持 | url 下载的文件不会解压 |
| 是否自动解压 | ❌ 否 | ✅ 是 | 支持的格式:.tar .tar.gz .tgz .tar.bz2 .tbz2 .tar.xz .txz |
| 是否支持 Git 仓库 | ❌ | ⚠️(BuildKit 支持) | 需开启 BuildKit,docker 高版本自动开启 |
| 行为可预测性 | ⭐⭐⭐⭐⭐ | ⭐⭐ | COPY 更安全 |
| 构建可控性 | 高 | 低 | COPY 更易维护 |
| 构建缓存稳定性 | 稳定 | 不稳定 | ADD 易失效 |
| 是否推荐用于生产 | ✅ 强烈推荐 | ⚠️ 谨慎 | 官方态度 |
| 可读性 | 高(即复制) | 低(可能有隐式行为) | 团队友好性 |
| 安全风险 | 低 | 较高 | ADD 可能引入供应链风险 |
MAINTAINER 指令设置 Docker 镜像的制作者的个人信息。
MAINTAINER <作者信息>
MAINTAINER xiaoyangzi
MAINTAINER xiaoyangzi <[email protected]>
LABEL 指令为镜像添加元数据(metadata) 的指令。这些元数据以键值对(key-value) 的形式存在,用于描述镜像的作者、版本、用途、来源等信息。
LABEL 不会影响镜像的构建流程和运行行为,其主要作用是信息标注与管理。
LABEL <key>=<value> <key>=<value> <key>=<value> ...
设置制作人信息:
LABEL maintainer="xiaoyangzi <[email protected]>"
设置多个标签:
LABEL maintainer="xiaoyangzi <[email protected]>" \
version="1.0" \
description="测试镜像"
ENV 指令用于在 Docker 镜像构建过程中设置环境变量。这些变量会被设置在由该 Dockerfile 构建出的镜像环境里。环境变量可以在 Dockerfile 的许多指令中使用,包括但不限于:WORKDIR、ENV、LABEL、RUN、CMD、ENTRYPOINT、COPY、ADD等。
当以某个镜像运行容器时,使用 ENV 设置的环境变量将持续存在。可以使用 docker inspect 查看这些值,并使用 docker run --env <key>=<value> 来更改它们。
常用形式:
ENV <key>=<value> [<key>=<value>...]
一对一形式(不推荐):
ENV <key> <value>
在 Dockerfile 中,环境变量的引用有两种方式:$variable_name 和 ${variable_name}。
使用 $variable_name 时,变量名后面不能紧跟字母、数字、下划线,需以空格、换行、特殊字符等来表示变量名的结束。如果 变量名后面需要紧接着其他字母数字下划线,就必须使用 ${variable_name} 形式来明确变量名的范围。使用 ${variable_name} 可以明确指定变量名的边界,这样可以在字符串中直接嵌入变量而不会引起歧义。\$ 来转义。一对一形式:
ENV NAME "XYZ"
常用形式:
ENV NAME="XYZ" \
AGE=18 \
gender=male
使用示例:
ENV NAME XYZ
CMD echo "Hello, $NAME"
CMD echo "Hello, ${NAME}"
ARG(Argument)是 Dockerfile 中用于定义构建阶段变量的指令。该变量仅在镜像构建过程中可用,用于向构建过程传递参数,而不会在容器运行时自动保留。
ARG 的主要作用是提高 Dockerfile 的可配置性与复用性。
ARG <name>[=<default value>] [<name>[=<default value>]...]
一个 ARG 变量从它被定义的那一行开始才生效,在这行之前使用它是无效的。
在使用 docker build 命令构建镜像时,使用 --build-arg 标志来为 ARG 变量赋值。
docker build --build-arg <变量名>=<值> --build-arg <变量名>=<值>.
定义变量
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 \
.
| 维度 | ARG | ENV |
|---|---|---|
| 生命周期 | 构建阶段(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
在 Dockerfile 里,有一些 内置(预定义)ARG 变量,主要是为了支持构建阶段的一些特定场景。它们不是所有变量都自动存在,而是 Docker 官方定义的、可以直接使用或覆盖的构建参数。
| 变量名 | 说明 | 可用阶段 |
|---|---|---|
BUILD_DATE | 构建时间(通常用来标记镜像构建时间) | 构建阶段 |
VCS_REF | Git 提交 hash(可选,用于标记源代码版本) | 构建阶段 |
TARGETPLATFORM | 当前构建的平台(例如 linux/amd64) | 构建阶段 |
BUILDPLATFORM | 执行构建的宿主平台(例如 linux/amd64) | 构建阶段 |
TARGETOS | 构建目标操作系统(例如 linux、windows) | 构建阶段 |
TARGETARCH | 构建目标 CPU 架构(例如 amd64、arm64) | 构建阶段 |
TARGETVARIANT | 构建目标架构的变体(例如 v7) | 构建阶段 |
RUN 指令用于在镜像构建阶段执行命令,并将执行结果提交为一个新的镜像层(image layer)。
RUN = 构建时执行命令 + 固化结果到镜像中
会启动 shell 来执行命令,通常是 /bin/sh,实际执行时会包装为 /bin/sh -c ""
注:支持变量替换,通配符,管道,逻辑运算符等操作,可使用 $HOME、*.txt、|、&&等功能。
RUN [OPTIONS] <command> ...
使用一个数组来明确指定要运行的可执行文件路径以及它的参数。
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"] | ❌ 否 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ 不适合 |
以下参数仅在 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 构建 | 极少数场景需要 |
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 [email protected]: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
ENTRYPOINT 用于定义容器启动时的固定入口程序。无论用户在 docker run 后面传什么,ENTRYPOINT 都会被执行。
当使用 docker run 命令启动一个基于该镜像的容器时,Docker 守护进程会执行 ENTRYPOINT 所指定的命令。这个命令会成为容器的'主进程'(PID 1)。
使用字符串数组组成命令,且必须是双引号。
ENTRYPOINT ["executable", "param1", "param2"]
会启动 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 参数覆盖
docker run --entrypoint bash image
如果我们采用 --entrypoint 覆盖了 ENTRYPOINT,则 Dockerfile 中作为 ENTRYPOINT 参数的原始 CMD 命令会被忽略
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 |
CMD 用于为容器提供默认启动命令或默认参数。它只在容器启动时执行(docker run),不会在构建 docker build 阶段执行。
Dockerfile 中只能有一个 CMD,如果有多个 CMD 指令,也只有最后一个会生效,并且可以被运行时参数覆盖:
CMD ["echo", "hello"]
docker run image echo world
echo hello 会被 echo world 覆盖,只会输出 world。
会启动 shell 来执行命令,通常是 /bin/sh,实际执行时会包装为 /bin/sh -c "<command>"
CMD command param1 param2
使用字符串数组组成命令,且必须是双引号。
CMD ["executable","param1","param2"]
和 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 时才可以。 |
| CMD 是否可被覆盖 | ✅(整体替换) | ✅(整体替换) | ✅(仅替换参数 |
| docker run 参数行为 | 覆盖整个 CMD | 覆盖整个 CMD | 追加 / 替换参数 |
| 与 ENTRYPOINT 协作能力 | 一般 | 差 | ⭐⭐⭐⭐⭐ |
| 行为可预测性 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| 生产环境推荐度 | ⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐⭐⭐ |
| 典型使用场景 | 固定启动命令 | 临时调试 | 官方镜像、服务型容器 |
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 | |
|---|---|---|---|---|
| 所属阶段 | 构建阶段(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 次 | |
| 生产环境重要性 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
EXPOSE 用于声明容器在运行时'预期会监听'的端口。可以理解为一种文档化的端口声明 + 元数据提示,而不是网络规则。
EXPOSE 指令本身只是声明端口,不会真的打开端口,也不会创建防火墙规则、让宿主机能访问、自动映射端口。
默认协议是 tcp
EXPOSE <port> [<port>/<protocol>...]
声明端口:
EXPOSE 80
EXPOSE 80/tcp
EXPOSE 53/udp
EXPOSE 80 443
声明多个端口:
EXPOSE 80 443 9000
-p 映射启动:
docker run -d -p 80:7000 -p 8080:8080/udp image
-P 启动:
docker run -P image
会自动映射所有 EXPOSE 的端口到宿主机的一个高端口(通常从 32768 开始)
VOLUME 用于声明容器中的某个路径是持久化数据目录。这个目录的数据不应该随着容器销毁而消失。
工作原理:
随机名字的目录,这个目录被称为'匿名卷'。(默认在 /var/lib/docker/volumes/ 下,可以通过 docker inspect 查看容器元数据找到)。将这个主机上的随机目录,与容器内部的 VOLUME 目录绑定起来。保存在了主机上的那个随机目录里。数据默认不会被删除。VOLUME ["/data"]
VOLUME ["/var/lib/mysql", "/var/log/mysql"]
该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个随机名称的目录与镜像目录挂载
VOLUME ["/data"]
该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个 mydata 名称的目录与镜像目录挂载
docker run -v mydata:/data image
该形式会在宿主机指定的绝对路径目录与镜像目录挂载
docker run -v /host/data:/data image
该形式会在宿主机 Docker volume 内部目录 /var/lib/docker/volumes/ 下创建一个 mydata 名称的目录与镜像目录挂载
docker run --mount type=volume,source=mydata,target=/data image
该形式会在宿主机指定的绝对路径目录与镜像目录挂载
docker run --mount type=bind,source=/host/data,target=/data image
以下出现的 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/... | 宿主机指定目录 |
| 是否可控 | 低 | 中 | 高 | 高 |
| 是否影响镜像层 | ✅ 切断容器目录与镜像层 | ❌ | ❌ | ❌ |
| 工程实践推荐度 | ⚠️ 官方镜像兜底 | ⚠️ 快捷方案 | ✅ 工程首选 | ✅ 生产挂宿主机首选 |
SHELL 的作用只有一个:修改后续 Shell Form 指令所使用的"默认 shell"
它影响的是这些以 shell 方式执行的指令格式:
RUN <string>
CMD <string>
ENTRYPOINT <string>
默认情况下:
[/bin/sh, -c]。[cmd, /S, /C]。例如当执行 RUN echo 'Hello World' 时:
/bin/sh -c "echo \"Hello World\"cmd /S /C "echo \"Hello World\"每个 SHELL 指令都会覆盖所有先前的 SHELL 指令,并影响所有后续指令
注意:SHELL 不影响 Exec 形式的指令
SHELL ["executable", "parameters"]
参数说明:
/bin/bash、powershell 等。-c、 -Command等。SHELL ["/bin/bash", "-c"]
SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]
参数说明:
SHELL ["cmd", "/S", "/C"]
参数说明:
改变 /C 后面命令字符串的解析规则,防止复杂命令容易被错误拆分或转义失败。SHELL ["powershell", "-Command"]
SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop';"]
参数说明:
启动 PowerShell 时不加载任何用户或系统 Profile 脚本。使 Docker 构建要 可重复、可预测。任何非终止性错误,都会升级为终止性错误,报错立即停止执行。USER 指令用于指定后续 Dockerfile 指令以及容器运行时所使用的用户和用户组。默认情况下,容器的运行身份为 root 用户。USER 指令可以修改后续的 RUN、CMD、ENTRYPOINT 等指令以哪个用户的权限来执行。
注:可以在一个 Dockerfile 中使用多个 USER 来切换身份
必须在系统 /etc/passwd 文件中定义的用户名/组
USER <user>[:<group>]
USER UID[:GID]
创建用户并使用:
# 创建一个用户组,指定组 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
HEALTHCHECK 指令后定义一个命令,Docker 会周期性执行它,判断容器是否健康。
容器健康状态有三种:
HEALTHCHECK [OPTIONS] CMD command
参数说明:
两次健康检查命令之间的时间间隔。 (默认:30s)单次健康检查命令的执行超时时间,如果超时则视为失败。 (默认:30s)容器启动后的宽限期,在这段时间内,即使健康检查失败,也不会标记容器为 unhealthy。 (默认:0s)比 --interval 更精细)用于在启动期覆盖 --interval 的间隔时间 (默认:5s`)连续失败多少次,才把容器标记为 unhealthy (默认:3 次)用于清理基础镜像继承的 HEALTHCHECK
HEALTHCHECK NONE
两次健康检查命令之间的时间间隔:
HEALTHCHECK --interval=10s CMD curl -f http://localhost:8080/health || exit 1
设置单次检查超时时间:
HEALTHCHECK --timeout=5s CMD curl -f http://localhost:080/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
使用 Netcat 命令尝试是否能够连接,可以的话则为成功
数据库/Redis/MQ 等服务的端口探测只能判断端口是否监听,不能判断协议/服务是否真正可用HEALTHCHECK CMD nc -z localhost 3306 || exit 1
参数说明:
扫描 /proc 目录,如 Linux 内核维护的 /proc/[pid]/cmdline,pgrep 遍历进程列表,查找匹配 myservice 的进程
HEALTHCHECK CMD pgrep myservice || exit 1
参数说明:
pgrep 常用参数:
| 参数 | 含义 | 示例 |
|---|---|---|
-x | 精确匹配命令名 | pgrep -x nginx |
-u <user> | 只匹配特定用户 | pgrep -u appuser myservice |
-q | 静默模式,只返回状态码 | pgrep -q myservice |
-f | 匹配完整命令行 | pgrep -f "python /app/app.py" |
HEALTHCHECK CMD test -f /app/config.yaml || exit 1
参数说明:
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 |
HEALTHCHECK CMD /app/healthcheck.sh
ONBUILD = 构建触发器,它不会在当前镜像构建时执行,而是在基于当前镜像的子镜像构建时触发执行。
ONBUILD 指令会在子镜像构建时首先执行,但严格来说是'在父镜像的 ONBUILD 队列中按顺序执行,紧接着子镜像自己的第一条指令之前。
ONBUILD <INSTRUCTION>
<instruction> 可以是 Dockerfile 中的常用指令,例如:COPY、ADD、RUN、ENV 等。(不支持某些特殊指令,如 FROM、ONBUILD 自己)
构建父镜像:
# 基础镜像
FROM ubuntu:22.04
ONBUILD COPY . /app
ONBUILD RUN echo "Build triggered in child"
构建这个镜像时:
ONBUILD COPY 和 ONBUILD RUN 不会执行镜像构建完成 → 生成一个带有'触发器'的镜像构建子镜像:
FROM mybaseimage:latest
构建子镜像时:
父镜像:
# 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
当执行 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 | ❌(通常) |
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 | 定时器超时 | 终止 | 超时控制 |
请求进程正常退出(可捕获、可处理),docker stop 默认发送
STOPSIGNAL SIGTERM
ENTRYPOINT ["myapp"]
CLI 工具、通过命令行直接运行、执行完就退出的程序、运行时占着终端、用户能实时看到输出的程序
STOPSIGNAL SIGINT
CMD ["ffmpeg", "-i", "a.mp4", "b.mp4"]
STOPSIGNAL SIGINT
CMD ["node", "server.js"]
STOPSIGNAL SIGINT
CMD ["python", "server.py"]
Nginx 优雅退出:
STOPSIGNAL SIGQUIT
立即杀死进程,不要在 Dockerfile 里用 STOPSIGNAL SIGKILL
dockerkill mycontainer
重新加载配置 / 重启逻辑
dockerkill -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
dockerkill -s HUP hup-demo
输出:
Reload config at 2026-01-08 ...
docker build 是 Docker 客户端用于根据 Dockerfile 构建镜像(Image)的命令。
镜像是不可变的只读模板,容器是镜像的运行实例。docker build 只负责生成镜像,不运行任何容器。
docker build [OPTIONS] PATH| URL | -
关键组成部分
| 部分 | 含义 |
|---|---|
| OPTIONS | 构建参数 |
| PATH | PATH 指的是构建上下文路径,可以是相对路径或绝对路径 |
| URL | Git 仓库或者 HTTP(s) 资源 |
| - | 从 stdin 读取 Dockerfile |
| 参数 | 简述 | 用法 / 示例 | 备注 |
|---|---|---|---|
-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 支持,控制资源限制 |
如执行:
docker build -t myapp:latest https://github.com/user/repo.git
如果 URL 指定了 branch/tag/commit,则下载指定版本,默认是 HEAD构建上下文。顺序解析每条构建指令(FROM, RUN, COPY, ADD, ENV 等)。注意:Dockerfile 默认在仓库根目录下找 Dockerfile,如果文件名不是 Dockerfile,必须加 -f 指定。
- 参数说明:
| 用法 | 描述 | 构建上下文 | Dockerfile 来源 | 示例(单元格安全) | 优势 | 限制 / 注意事项 |
|---|---|---|---|---|---|---|
| Here Document | Shell 使用 HereDoc 把 Dockerfile 内容送入 stdin | 默认空 | stdin | docker build -t tempimage - <<EOF FROM alpine RUN echo hello EOF | 无需 Dockerfile 文件,适合临时测试、教学 | 无上下文,不能 COPY 本地文件 |
| 管道 echo | 用 echo 输出 Dockerfile,通过管道传给 docker build | 默认空 | stdin | `echo "FROM alpine\nRUN echo hello" | docker build - -t tempimage` | 最简单、脚本友好 |
| 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,复杂度高 |
.dockerignore 是位于构建上下文根目录的配置文件,用于在构建开始之前过滤构建上下文中不需要发送给 Docker daemon 的文件和目录。防止一些大文件或者没有的文件创建到镜像中。
如:
.git
.gitignore
node_modules
target
dist
*.log
docker build -t repo/name:tag .
多标签:
docker build -t app:1.0 -t app:latest .
不指定标签
docker build -f Dockerfile.prod .
给 Dockerfile 中的 ARG 传参
docker build --build-arg VERSION=1.2.3 .
docker build --no-cache .
docker build --platform linux/amd64 .
docker build -t myapp:1.0 .
docker build -t myapp:1.0 ./docker
docker build -t myapp:1.0 /home/user/project
只能访问上下文里的文件,不能访问 PATH 以外的文件。不要把不必要的大文件夹放入上下文,否则每次 build 都要上传,耗时很长。使用 .dockerignore 忽略不需要的文件。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
动态生成 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 pull williamyeh/java8
该镜像不必启动
#指定基础镜像,本地没有会从 dockerHub pull 下来
FROM williamyeh/java8
#把可执行 jar 包复制到基础镜像的根目录下
ADD api-test.jar /api-test.jar
#镜像要暴露的端口,如要使用端口,在执行 docker run 命令时使用-p 生效
EXPOSE 8087
#在镜像运行为容器后执行的命令
ENTRYPOINT ["java","-jar","/api-test.jar"]
上传 jar 包到服务器 Dockerfile 文件同目录下
docker build -f Dockerfile -t why/api-test:v1.0 .
参数说明:
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

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online