文章目录
- 本篇摘要
- 一.镜像制作的原因
- 二.Docker镜像制作的两种方式
- [三.基于快照模式制作C++ `hello world` 镜像](#三.基于快照模式制作C++
hello world镜像) - 四.dockerfile镜像制作
-
- dockerfile概念
- [为什么需要 Dockerfile](#为什么需要 Dockerfile)
- dockerfile常见的指令
- dockerfile之build介绍
- 五.`dockerfile`制作优秀实践
- 六.测试需要代码汇总
- 七.本篇小结:

本篇摘要
本文系统解析 Dockerfile 全指令集与实战技巧,涵盖镜像构建原理、多阶段优化、缓存机制及安全实践。通过快照与 Dockerfile 对比,详解如何高效封装应用、缩减镜像体积,并提供企业级镜像优化方案,助力构建生产就绪的容器化应用。
一.镜像制作的原因
-
代码封装发布:为了将自主编写的应用程序代码直接打包到镜像中,实现与镜像一体化的发布和部署。
-
安全合规要求:为避免第三方镜像可能存在的安全漏洞或未知风险,确保运行环境的安全与可控。
-
功能定制扩展 :
官方镜像无法满足特定需求(如为数据库添加审计等额外功能),需要通过自定义镜像来实现。 -
内部规范统一:遵守公司内部规定,需使用自有的操作系统或基础环境作为基准来构建镜像,以符合统一的标准和管理流程。
二.Docker镜像制作的两种方式
- 制作快照(适用于偶尔制作的镜像)

- 方法:先启动一个基础容器(如 Ubuntu),进入容器内部手动安装和配置所有所需软件,最后将该容器的整个状态打包成一个新镜像。
- 类比:类似于给当前系统拍一张"快照"或"备份"。
- Dockerfile构建(适用于经常更新的镜像)

- 方法 :将所有安装和配置步骤编写到一个名为
Dockerfile的文本文件中,然后使用docker build命令自动构建镜像。 - 优势:过程透明、可重复,易于版本管理和自动化,是推荐的标准做法。
三.基于快照模式制作C++ hello world 镜像
制作流程
基于centos:7原镜像进行把对应的容器启动然后在容器中进行对应操作,接着把它commit成镜像,下次启动就直接一次性启动执行对应命令,这样一个简单的镜像就制作好了。
首先对应宿主机进行文件编写:

启动对应centos:7容器并以bash交互进去:

把宿主机对应的test文件拷贝过去:

下面在对应的容器中进行centos 镜像源安装:

下面安装完gcc开始运行:

接着把它commit成对应的镜像;

下面进行一次性执行容器命令:


- 执行完后也是立刻退出了。

- 可以看到对应的commit的过程保留文件系统+底层元数据,而之前的export就不会。
基于快照模式的提交镜像总结

-
可以发现当进行commit进行制作的时候,当使用方完全看不到对应的制作过程;而且如果想要修改的话,又要重头再制作(不知道这个镜像到了哪一步);而上面操作,其实运行容器的时候没有用到gcc;倒不如直接把对应的exe拷贝进容器中,因此看起来是比较臃肿的。
-
而后面要介绍的Dockerfile就完美的解决了这一点。
四.dockerfile镜像制作
dockerfile概念

-
Dockerfile 是一个文本脚本文件,用于自动化和定义 Docker 镜像的构建过程。
-
镜像的定制就是定制每一层的配置和文件。Dockerfile 中的每一条指令 都会对应构建出镜像的一个层级。
-
通过在其中写入一系列的命令(例如复制文件、安装软件、配置环境等),来描述每一层应当如何被构建。
-
通过执行这个脚本(使用
docker build命令),可以自动地构建出一个符合用户定制需求的、新的 Docker 镜像。 -
Dockerfile 中最后一个 FROM指令决定了最终镜像的根基,之前的阶段只是为它服务的临时环境。
如图:

总而言之,Dockerfile 是将手动构建镜像的步骤记录到一个自动化脚本中,从而实现镜像构建的流程化、可重复和可管理。
为什么需要 Dockerfile
-
官方镜像通常无法直接满足应用需求,需要将自己开发的代码打包进去,制作成符合要求的自定义应用镜像(基于commit的快照模式改造)。
-
相比手动执行命令并提交(
docker commit)的不可追溯和易遗漏,Dockerfile 能将构建过程自动化,确保每次构建的结果一致。 -
使用
docker commit制作的是"黑箱镜像",构建步骤不透明。而 Dockerfile 是明文脚本,所有操作清晰可见,易于理解和二次开发。 -
docker commit容易将运行时产生的临时文件和未清理的依赖打包进镜像,导致镜像臃肿。Dockerfile 可以通过多阶段构建等功能,分离编译和运行环境,产出更标准、体积更小的镜像。
制作好对应的镜像然后放到对应仓库,后面就可以直接同步push下对应镜像然后实例化出对应的容器,在不同的环境进行部署测试等:

dockerfile常见的指令
1.FROM指令
-
功能 :
FROM指令用于指定构建镜像所依赖的基础镜像,后续所有指令均在此基础镜像提供的环境中执行。 -
位置要求 :必须是 Dockerfile 中首个非注释指令,或紧跟在
ARG指令之后。 -
镜像拉取:若本地不存在指定镜像,Docker 会尝试从公共仓库自动拉取;若镜像不存在则报错。
-
多阶段构建 :可通过多次使用
FROM指令创建多个镜像,或将某一构建阶段作为另一阶段的依赖(需配合AS <name>命名)。 -
标签默认值 :若未指定镜像标签(
<tag>),默认使用latest标签。 -
语法参数
--platform:指定目标平台架构(如linux/amd64)。<image>:基础镜像名称(如果是scratch的话就是从空镜像开始制作;做出来就是基础镜像)。<tag>/<digest>:使用标签或哈希值精确指定镜像版本。AS <name>:为构建阶段命名,便于多阶段构建中引用。
演示下:
在对应目录创建dockerfile文件:

基于基本镜像centos:7来构建新镜像:


- 进行构建然后这里提示说,建议在build的时候进行--platform指定(. 是当前目录作为dockefile上下文)。

- 创建成功(说白了就是搞了个centos:7的副本)。

- 启动这个镜像来实例化容器执行一次性命令。
2.MAINTAINER指令
- 已废弃的 Docker 指令
- 原用途:标注镜像作者信息
- 现建议:改用
LABEL maintainer="作者名" - 语法示例:
MAINTAINER 姓名<邮箱>
(注:现使用仅触发警告,不影响构建)
演示下:


- 这里提示已经废弃掉了。



- 成功启动,可以运行,看到对应的author内容发生改变。
3.LABEL指令
- 功能:用于为 Docker 镜像添加元数据(描述信息)。
- 格式:元数据以键值对(key=value)形式存储。
- 语法 :
LABEL <键>=<值> <键>=<值> ...(可同时定义多个标签)。 - 用途:记录作者、版本、描述等镜像信息,方便管理。
演示下:



- 可以看到成功运行。


- 查看镜像详情,可以看到对应的labels被添加了。
4.COPY指令
- 功能:将主机上的文件或目录复制到镜像内部。
- 语法 :
COPY [参数] <源路径> <目标路径>。 - 参数:
--chown:可设置复制后文件的所属用户和组。--from:可从多阶段构建的前一阶段复制文件。
- 规则:
- 源路径必须在构建上下文内。
- 复制目录时会递归复制其内容(不包括目录本身)。
- 复制多个文件或使用通配符时,目标路径必须是目录(以
/结尾)。 - 目标路径不存在时会自动创建。
演示下:
首先编写对应dockerfile:
查看对应的组别有哪些(随便启动一个对应的NGINX容器):

- 这里可以根据第一个作为不同的组进行chown操作。
下面编写对应指令:


- 在宿主机制作对应文件。

- 对应镜像制作成功,然后去对应的容器的bash下查看。

- 对应的
拥有者与从属组更改完成,对应的文件内容也发生拷贝覆盖。
5.ENV指令
- 作用 :在镜像里设置环境变量(就像设置全局配置)。
- 使用 :设置后,后面的指令(如
RUN,COPY)都能用$变量名来使用这个值。 - 写法 :
ENV 变量名=值(例如:ENV APP_HOME=/app)。
演示下:
编写dockerfile:


- 成功打成镜像。
下面进入对应容器看下:

- 也是成功显示。
6.WORKDIR指令
-
核心功能 :用来设置工作目录 ,相当于
cd命令。之后的所有指令(如RUN,CMD,COPY,ADD)都会在这个目录下执行(指定目录不存在就会创建)。 -
基本语法 :
WORKDIR /路径/到/目录。路径可以是绝对路径(如/app),也可以是相对路径。 -
默认目录 :如果不设置,默认的工作目录是容器文件系统的根目录(
/)。 -
相对路径 :如果使用相对路径(如
subdir),它会基于前一条WORKDIR指令设置的路径。 -
支持变量 :路径里可以使用之前通过
ENV指令定义的环境变量(如WORKDIR $APP_HOME)。
演示下:



- 镜像成功构建成功(为啥有悬空镜像? 重复构建同名镜像时,Docker会将旧镜像的标签转移给新镜像,导致旧镜像变成无标签的状态。)。

- 发现对应的工作目录确实变了,也就是进入对应的bash就回来到对应工作目录(也就是没有指定对应目录默认都会在这个目录操作)。
7.ADD指令
-
核心功能 :用于复制文件,比
COPY功能更强,支持自动解压压缩包(如.tar)和从 URL 下载文件(但是url下载后不会自动解压)。 -
基本语法 :
ADD [--chown=<用户>:<组>] <源路径>... <目标路径>路径包含空格时,可以用引号格式。
-
关键参数
--chown:在复制时可同时修改文件的所有者和所属组 (如--chown=user:group)。 -
路径说明:
<源路径>:支持使用通配符。<目标路径>:必须是容器内的路径,建议使用绝对路径 ,否则会相对于WORKDIR指令设置的目录。
演示下:
对应的nginx下载的官网:

下面测试下直接url抓过来以及直接tar包拿进来效果:

首先把对应tar.gz对应的压缩包到当前目录方便cp;对于wget直接从网站爬就行:

下面进行镜像构建:


- 发现了对应的url的话只cp对应压缩包进来不进行解压;而对应的压缩包cp的话自动解压;还发现对于当前目录操作,默认当成了对应的工作目录来进行。
8.RUN指令
-
核心功能 :在
docker build构建镜像的过程中执行命令(例如安装软件、编译代码等)。 -
两种语法形式:
- Shell 形式 :
RUN <command>
默认在 /bin/sh -c 下执行命令;支持 Shell 特性,如变量替换、通配符(*)等。
- Exec 形式 :
RUN ["executable", "param1", "param2"]
直接执行程序,不通过 Shell;避免 Shell 解析的歧义,格式更清晰;不支持 Shell 特性,如需使用必须显式调用 Shell(如 RUN ["/bin/bash", "-c", "your command"])。
- 使用场景:通常用于安装依赖包、下载编译代码、执行构建脚本等任何需要在构建阶段准备镜像环境的操作。
演示下:
先演示下简单使用:

- 把对应的从网站wget下来的压缩包解压到对应目录(这里用的包含shell的语法)。

- 发现成功解压。
下面测试基于ubuntu 解压安转nginx:



- 对应exec显示显示shell调用成功,对应的nginx安装完成。


- 对应html首页也被覆盖。
9.CMD指令
- 核心功能 :在容器启动时执行命令,为容器提供默认的运行程序。
- 与 RUN 的区别 :
RUN在镜像构建时 执行,用于安装配置;CMD在容器运行时 执行,用于启动应用(相当于main函数)。 - 语法形式 :
- 推荐格式 :
CMD ["executable", "param1", "param2"] - 为 ENTRYPOINT 提供参数 :
CMD ["param1", "param2"] - Shell 格式 :
CMD command param1 param2
- 推荐格式 :
- 重要特性 :
- 一个 Dockerfile 中可以有多个
CMD,但只有最后一个会生效。 - 在启动容器时,
docker run后面跟的命令可以覆盖 Dockerfile 中的CMD指令。 - 与entrypoint都出现的时候,结合起效果。
- 一个 Dockerfile 中可以有多个
- 注意事项 :使用 JSON 数组格式(Exec form)时,必须使用双引号。
演示下:

- 基于之前的ubuntu镜像进行让实例化的容器的主进程就去执行启动nginx的前台任务。



- 这里发现对应的cmd变了;也就是容器一启动里面的主进程就去执行这个指令了;而访问对应8090端口就被映射到容器的80端口(nginx就默认部署在80端口上),因此看到对应效果。

- 如果没有更改镜像的cmd默认就是bash;自然一启动没收到一次性命令就退出来了。
10.EXPOSE指令
- 作用 :只声明容器会用的端口,不自动打开端口。
- 本质 :是给用户的说明文档,告诉别人这个镜像里的服务用了哪些端口。
- 用法 :
EXPOSE <端口号>或EXPOSE <端口号>/<协议>(如EXPOSE 80/tcp)。 - 关键 :运行容器时必须加
-p(如-p 80:80)才能从外部访问。
演示下:

- 只是声明说是有这个端口,并没有完成映射。

- curl一下发现curl宿主机80端口没有被转发到对应容器80端口,故只是声明。
11.ENTRYPOINT指令
-
核心功能 :指定容器启动时的主入口命令,让容器像独立应用程序一样运行。
-
两种语法形式:
- Exec 形式(推荐) :
ENTRYPOINT ["可执行命令", "参数1", "参数2"] - Shell 形式 :
ENTRYPOINT 命令 参数1 参数2
- Exec 形式(推荐) :
-
关键注意事项 :使用 Exec 形式(JSON数组)时,必须使用双引号,使用单引号会导致错误。
-
与 CMD 的区别 :
ENTRYPOINT定义的命令通常不会被docker run的命令覆盖,而CMD提供的默认参数可以被覆盖。两者常结合使用。
演示下:
基于之前的ubuntu的dockerfile对于cmd配合entrypoint结合使用:


- build后启动,发现直接就是前台运行不是bash(直接退出);说明两者结合使用变成主进程的命令了。

- 查看容器详情可以发现。

- 可以发现这里如果是entrypoint或者两者结合使用的话,后面的命令就不能覆盖掉之前的命令给主进程(这里是把后面的当成参数传给entrypoint了,然后不认识这些参数故报错)。
如果是cmd模式呢?



- 这里可以看到成功打印出来了,此时就是把对应的参数给cmd了,也就是覆盖cmd原先dockerfile中设置的了,直接主进程就执行新的命令了。

- 这里如果使用的是entrypoint;那么
--entrypoint :命令 -c:参数才能发生指令覆盖;而cmd本身就会发生覆盖。
总结下:
entrypoint可以结合cmd(做entrypoint参数使用);然后如果是单entrypoint或者结合使用的,那么此时run后面命令就是给entrypoint做参数(可能无法识别);但是如果是cmd状态,run的时候添加参数就是覆盖cmd让主进程执行。
12.ARG 指令
- 作用 :定义构建时可修改 的变量,类似
ENV但仅在docker build阶段有效。 - 语法 :
ARG <变量名>[=默认值](默认值可选)。 - 传参 :通过
docker build --build-arg <变量名>=<值>覆盖默认值。 - 作用域:从定义处开始生效,定义前无法使用(即使传参也无效)。
- 优先级 :若
ENV和ARG同名,ENV的值会覆盖ARG的值;也就是只存在于对应dockerfile中不进镜像。 - 用途:灵活控制软件版本、路径等构建参数,提升Dockerfile可复用性。
演示下:

- 相当于别名(只在对应的dockerfile文件有效)。

- 就是对应版本ubuntu。
但是如果不想改dockerfile但是想换个版本;此时就可以在build的时候借助--build-arg 来修改对应的VERSION:


- 这里查看对应镜像版本就是更新后的22.10.
总结下:
如果只希望在dockerfile中起效,因此可以使用arg指令;比如对应的还有需要动态构建(如镜像版本升级等);此时arg就能发挥作用。
13.VOLUME指令
用法:
- VOLUME <挂载点路径>(直接指定)
- VOLUME "\<挂载点路径\>"(JSON数组格式)
- 作用 :在容器里自动创建备份盘(匿名数据卷),防止数据丢失。
- 特点 :
- 备份盘位置由 Docker 自动分配(用户不能指定主机目录)。
- 即使启动命令忘了用
-v,数据也会存下来。 - 容器删除后,备份盘里的数据还在。
- 优先级 :如果用户启动时用了
-v指定目录,则以-v为准,这个"自动备份盘"就不生效了。 - 典型用途:像 MySQL 这类有重要数据的容器,必须用它确保数据安全。
下面来演示下:

- 这路不输入-v也就是默认匿名卷存储在对应的
/var/lib/docker/volumes下。


- 确实符合预期,并且挂载也是volume。
如果加上-v也就是覆盖默认的volume,以-v为主:


- 把对应宿主机当前目录的文件同步过去了。

- 此时挂载方式也改变了。
14.SHELL指令
-
核心功能 :用于覆盖 Docker 容器中执行命令时使用的默认 Shell 程序。
-
默认 Shell:
- Linux 系统 :默认是
["/bin/sh", "-c"] - Windows 系统 :默认是
["cmd", "/S", "/C"]
- Linux 系统 :默认是
-
基本语法 :必须以 JSON 数组格式编写。
SHELL ["可执行文件", "参数"]- 例如:
SHELL ["/bin/bash", "-c"]
- 例如:
-
重要特性:
- 可以在 Dockerfile 中多次使用。
- 每条
SHELL指令都会覆盖 之前的所有SHELL指令,并影响其后的所有指令。
-
主要用途 :此指令在 Windows 容器 中特别有用,因为 Windows 上有两种常用的 Shell:
CMD和PowerShell,可以通过该指令进行切换和指定。
演示下:

- 这里从ubuntu默认的sh切换成bash;来详细展示过程。

- 这里可以通过打印出执行过程看出不一样证明构建过程中shell变化了sh-->bash。
15.USER指令
- 功能 :用于设置容器运行时或执行后续指令(如
RUN,CMD)的默认用户身份,不再默认使用 root 用户,以提升安全性。 - 语法 :支持两种格式
- 用户名/组名:
USER <user>[:<group>] - 用户ID/组ID:
USER <UID>[:<GID>]
- 用户名/组名:
- 参数 :
user/UID:指定用户名或用户 IDgroup/GID:(可选)指定用户组名或组 ID
- 注意事项 :指定的
UID必须是容器内/etc/passwd文件中存在的有效用户 ID,否则运行会失败。
演示下:

- 这里默认是root用户及用户组,然后把它设置成nginx进行文件操作;然后改回root继续创建mysql再进行文件操作。
下面build后进行查看对应容器目录:

- 发现用户及用户组确实变了。
16.healthcheck指令
-
核心功能 :用于检查容器内应用服务的健康状态,能检测进程虽在运行但服务已不可用(如死循环、服务僵死)的情况。
-
两种语法形式:
HEALTHCHECK [OPTIONS] CMD command:在容器内运行指定命令来检查健康状况。HEALTHCHECK NONE:禁用从基础镜像继承的任何健康检查。
-
关键参数(OPTIONS):
--interval=DURATION:检查间隔时间(默认 30秒)。--timeout=DURATION:等待命令响应的超时时间(默认 30秒)。--retries=N:连续失败多少次才判定为不健康(默认 3次)。--start-period=DURATION:容器启动后,等待多久开始第一次检查(默认 0秒)。
-
返回值含义(可以通过对应日志详细观看):
- 0:成功,容器健康。
- 1:失败,容器不健康。
- 2:保留值,不使用。
-
主要目的 :让 Docker 引擎能更智能地监控容器内应用的实际状态,而不仅仅是进程是否存在(
注意健康(自定义)和运行不是一个状态)。
演示下:
下面启动对应容器进行curl自己演示下health:

- 正常执行完命令就说明健康。



- docker ps可以看到从开始检测到健康状态。
下面检测下让它出现不健康:

- 这使用bash覆盖掉nginx默认的启动命令(启动web);故此时只是一个shell啥也不干。

- ps查看到到时间就失败。
17.ONBUILD指令
也就是延迟触发器!
- 作用:现在不执行,等别人拿我这个镜像当基础去构建时,再自动执行我定义的指令。
- 写法 :
ONBUILD <Dockerfile指令>,例如:ONBUILD ADD . /app/src。 - 用途 :专门用来做可复用的基础镜像,自动帮后续的"子镜像"完成一些通用操作。
演示下:


- 第一次发现对应下面没有对应文件。
然后复用下上面的镜像:


- 发现延迟成功。
18.STOPSIGNAL指令
-
核心功能 :用于设置容器停止时,Docker 引擎发送给容器内主进程的系统信号 ,以控制容器的停止方式(
根据dockerfile里设置的来覆盖掉本身stop(优雅退出)时候的信号)。 -
基本语法 :
STOPSIGNAL <信号>。- 信号可以是数字代号(如
9)。 - 也可以是信号名称(如
SIGKILL)。
- 信号可以是数字代号(如
-
常见信号:
- SIGTERM (15) :默认信号。礼貌地请求进程终止,允许其完成清理工作。
- SIGKILL (9):强制立即终止进程,不给进程任何清理的机会。
- SIGHUP (1):通常用于通知进程重新加载配置。
- SIGINT (2) :模拟键盘
Ctrl+C的中断操作。 - SIGSTOP (19):暂停进程的执行。
-
主要用途:通过发送不同的信号,可以更优雅、更可控地停止容器中的应用,例如让应用有时间保存状态、完成正在处理的请求后再退出。
演示下:


- nginx前台占用宿主机shell启动。


- stop时候发送对应信号这里显示不是优雅退出,收到的是9好信号。
下面启动个没被覆盖stop信号的普通nginx镜像:



- 这里可以看到优雅的退出。
指令总览:
常见指令清单:
| 指令 | 功能描述 | 备注 |
|---|---|---|
| FROM | 构建镜像基于哪个镜像(基础镜像) | 必须掌握 |
| MAINTAINER | 镜像维护者姓名或邮箱地址 | 已废弃,被 LABEL 替代 |
| LABEL | 为镜像添加元数据(如版本、描述等信息) | 必须掌握 |
| COPY | 拷贝文件或目录到镜像中,不支持自动下载或解压 | 必须掌握 |
| ADD | 拷贝文件或目录到镜像中,支持 URL 自动下载和压缩包自动解压 | 必须掌握 |
| WORKDIR | 设置镜像内的工作目录(后续命令均在此目录下执行) | 必须掌握 |
| RUN | 在构建过程中执行命令(如安装软件、配置环境等) | 必须掌握 |
| VOLUME | 声明容器中的挂载点(数据卷) | 必须掌握 |
| EXPOSE | 声明容器运行时监听的端口(仅声明,实际映射需在运行时指定) | 必须掌握 |
| ENV | 设置环境变量(供后续指令或容器运行时使用) | 必须掌握 |
| CMD | 指定容器启动时默认执行的命令(可被运行时覆盖) | 必须掌握 |
| ENTRYPOINT | 指定容器启动时的程序入口(与 CMD 协同或独立使用) | 必须掌握 |
| ARG | 定义构建时可传递的参数(仅在构建阶段有效) | 使用较少 |
| SHELL | 指定 RUN、CMD、ENTRYPOINT 使用的默认 shell | 使用较少 |
| USER | 指定运行容器时的用户名或 UID | 必须掌握 |
| HEALTHCHECK | 定义容器健康检查方式(如检测服务是否就绪) | 必须掌握 |
| ONBUILD | 定义延迟执行的指令(仅在以当前镜像为基础镜像构建下一级镜像时触发) | 使用较少 |
| STOPSIGNAL | 覆盖容器停止时发送的系统信号 | 使用较少 |
dockerfile之build介绍
-
功能 :用于根据
Dockerfile文件和构建上下文(代码、资源等)创建出一个新的 Docker 镜像。 -
语法 :
docker build [OPTIONS] PATH | URL | - -
常用关键参数:
-t/--tag:为生成的镜像命名和打标签 (格式:name:tag),这是最常用的参数。-f:指定使用的Dockerfile的路径(如果文件名不是默认的Dockerfile或不在上下文根目录时使用)。--no-cache:禁用缓存,从头开始构建,确保获取最新依赖。--build-arg:设置构建时的变量,可传入 Dockerfile 中的ARG指令。-q/--quiet:安静模式,成功构建后只输出最终的镜像 ID,不显示冗长的构建过程。--network:设置构建过程中RUN指令的网络模式。--label=[]:设置镜像使用的元数据。
-
构建上下文 :命令最后的
<路径>非常重要,它指定了构建时发送给 Docker 守护进程(也就是docker客户端给对应服务端发送进行的镜像制作)的文件目录(通常包含 Dockerfile 和需要复制到镜像中的代码文件)。
演示URL:
首先要知道安装了nginx在宿主机上所以访问对应ip自动默认访问80端口也就是nginx主页:

也就是访问对应ip作为网址,自动跑到这个html目录中:index.html默认就是80,下面配合url方式curl一下:


- 成功curl到。

- 网站也是可以的(这也就是为啥nginx可以被使用搭建网站原因,如这个html里)

- 基于url进行dockerfile构建。

- 成功构建。
演示-f与--no-cache

- 说是以当前目录为上下文,但是找不到对应的dockerfile。
下面指明对应dockerfile文件:

- 成功构建。
对于 --no-cache 使用的话可以看出如果复杂的镜像构建且无前基础,就会变得很慢。
演示-q与--label
之前在arg指令演示过---build-arg了。

- 成功构建只返回对应对应的id(这里写成两个--label来设置多标签)。

- 查看镜像对应标签也是成功的。
演示--network


- 这里指定了构建过程使用宿主机的网络,所以才能https访问到对应的tar包。
五.dockerfile制作优秀实践
首先要知道Dockerfile 镜像构建完全由本机的Docker 守护进程(daemon)负责执行。

- 使用
.dockerignore:创建此文件来排除构建时不需要的文件,避免发送无用数据,加速构建过程。

- 多阶段构建 :将编译和运行环境分离,最终镜像只包含运行所需的最小内容,大幅减小镜像体积(
但是最后生成的镜像是以最后一个from为主)。

- 利用构建缓存 :把内容变动少的指令(如安装依赖)放在 Dockerfile 前面,充分利用缓存提升构建速度(
此时当频繁修改源代码,再次build的时候就直接不用一直安装gcc耗时间了)。

- 精选基础镜像:优先选择官方的轻量级基础镜像(如 Alpine、slim 版本),避免使用臃肿的全功能系统镜像。

- 合并镜像层 :尽量将多条
RUN、COPY、ADD指令合并成一条,减少镜像层数。

- 保持镜像单一功能:一个镜像专注于一个用途,避免制作大而全的复杂镜像(避免镜像融合)。

- 固定外部依赖 :从外部引入数据或依赖时,使用明确的版本号和持久化地址,确保构建可重复且稳定(
如果本机不能上网,http去远端就出问题了下载)。

- 仅安装必要软件包:只安装应用运行必需的软件包,避免安装任何可有可无的包,以最小化镜像体积。
六.测试需要代码汇总
七.本篇小结:
本篇通过对比快照与 Dockerfile 两种镜像构建方式,深入剖析了 Dockerfile 核心指令的功能、语法及实战应用场景。从基础镜像选择、多层合并到多阶段构建,全面阐述了镜像优化策略。同时结合安全规范与生产实践,为开发者提供了从开发到部署的完整容器化解决方案,显著提升应用交付效率与运维可靠性。