2019-11-06 14:53:09 +08:00
# 使 用 Dockerfile 定 制 镜 像
2016-11-26 02:02:43 +08:00
从 刚 才 的 ` docker commit ` 的 学 习 中 , 我 们 可 以 了 解 到 , 镜 像 的 定 制 实 际 上 就 是 定 制 每 一 层 所 添 加 的 配 置 、 文 件 。 如 果 我 们 可 以 把 每 一 层 修 改 、 安 装 、 构 建 、 操 作 的 命 令 都 写 入 一 个 脚 本 , 用 这 个 脚 本 来 构 建 、 定 制 镜 像 , 那 么 之 前 提 及 的 无 法 重 复 的 问 题 、 镜 像 构 建 透 明 性 的 问 题 、 体 积 的 问 题 就 都 会 解 决 。 这 个 脚 本 就 是 Dockerfile 。
2019-03-08 12:21:07 +08:00
Dockerfile 是 一 个 文 本 文 件 , 其 内 包 含 了 一 条 条 的 * * 指 令 ( Instruction ) * * , 每 一 条 指 令 构 建 一 层 , 因 此 每 一 条 指 令 的 内 容 , 就 是 描 述 该 层 应 当 如 何 构 建 。
2016-11-26 02:02:43 +08:00
还 以 之 前 定 制 ` nginx ` 镜 像 为 例 , 这 次 我 们 使 用 Dockerfile 来 定 制 。
在 一 个 空 白 目 录 中 , 建 立 一 个 文 本 文 件 , 并 命 名 为 ` Dockerfile ` :
` ` ` bash
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile
` ` `
其 内 容 为 :
2019-10-29 14:31:45 +08:00
` ` ` docker
2016-11-26 02:02:43 +08:00
FROM nginx
RUN echo ' < h1 > Hello , Docker ! < / h1 > ' > / usr / share / nginx / html / index . html
` ` `
这 个 Dockerfile 很 简 单 , 一 共 就 两 行 。 涉 及 到 了 两 条 指 令 , ` FROM ` 和 ` RUN ` 。
2019-11-06 14:53:09 +08:00
# # FROM 指 定 基 础 镜 像
2016-11-26 02:02:43 +08:00
2019-03-08 12:21:07 +08:00
所 谓 定 制 镜 像 , 那 一 定 是 以 一 个 镜 像 为 基 础 , 在 其 上 进 行 定 制 。 就 像 我 们 之 前 运 行 了 一 个 ` nginx ` 镜 像 的 容 器 , 再 进 行 修 改 一 样 , 基 础 镜 像 是 必 须 指 定 的 。 而 ` FROM ` 就 是 指 定 * * 基 础 镜 像 * * , 因 此 一 个 ` Dockerfile ` 中 ` FROM ` 是 必 备 的 指 令 , 并 且 必 须 是 第 一 条 指 令 。
2016-11-26 02:02:43 +08:00
2018-12-14 19:08:14 +08:00
在 [ Docker Hub ] ( https : //hub.docker.com/search?q=&type=image&image_filter=official) 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 [`nginx`](https://hub.docker.com/_/nginx/)、[`redis`](https://hub.docker.com/_/redis/)、[`mongo`](https://hub.docker.com/_/mongo/)、[`mysql`](https://hub.docker.com/_/mysql/)、[`httpd`](https://hub.docker.com/_/httpd/)、[`php`](https://hub.docker.com/_/php/)、[`tomcat`](https://hub.docker.com/_/tomcat/) 等;也有一些方便开发、构建、运行各种语言应用的镜像,如 [`node`](https://hub.docker.com/_/node)、[`openjdk`](https://hub.docker.com/_/openjdk/)、[`python`](https://hub.docker.com/_/python/)、[`ruby`](https://hub.docker.com/_/ruby/)、[`golang`](https://hub.docker.com/_/golang/) 等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
2017-11-22 20:28:10 +08:00
2018-12-14 19:08:14 +08:00
如 果 没 有 找 到 对 应 服 务 的 镜 像 , 官 方 镜 像 中 还 提 供 了 一 些 更 为 基 础 的 操 作 系 统 镜 像 , 如 [ ` ubuntu ` ] ( https : //hub.docker.com/_/ubuntu/)、[`debian`](https://hub.docker.com/_/debian/)、[`centos`](https://hub.docker.com/_/centos/)、[`fedora`](https://hub.docker.com/_/fedora/)、[`alpine`](https://hub.docker.com/_/alpine/) 等,这些操作系统的软件库为我们提供了更广阔的扩展空间。
2016-11-26 02:02:43 +08:00
除 了 选 择 现 有 镜 像 为 基 础 镜 像 外 , Docker 还 存 在 一 个 特 殊 的 镜 像 , 名 为 ` scratch ` 。 这 个 镜 像 是 虚 拟 的 概 念 , 并 不 实 际 存 在 , 它 表 示 一 个 空 白 的 镜 像 。
2019-10-29 14:31:45 +08:00
` ` ` docker
2016-11-26 02:02:43 +08:00
FROM scratch
...
` ` `
如 果 你 以 ` scratch ` 为 基 础 镜 像 的 话 , 意 味 着 你 不 以 任 何 镜 像 为 基 础 , 接 下 来 所 写 的 指 令 将 作 为 镜 像 第 一 层 开 始 存 在 。
2021-03-11 23:09:37 +08:00
不 以 任 何 系 统 为 基 础 , 直 接 将 可 执 行 文 件 复 制 进 镜 像 的 做 法 并 不 罕 见 , 对 于 Linux 下 静 态 编 译 的 程 序 来 说 , 并 不 需 要 有 操 作 系 统 提 供 运 行 时 支 持 , 所 需 的 一 切 库 都 已 经 在 可 执 行 文 件 里 了 , 因 此 直 接 ` FROM scratch ` 会 让 镜 像 体 积 更 加 小 巧 。 使 用 [ Go 语 言 ] ( https : //golang.google.cn/) 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。
2016-11-26 02:02:43 +08:00
2019-11-06 14:53:09 +08:00
# # RUN 执 行 命 令
2016-11-26 02:02:43 +08:00
` RUN ` 指 令 是 用 来 执 行 命 令 行 命 令 的 。 由 于 命 令 行 的 强 大 能 力 , ` RUN ` 指 令 在 定 制 镜 像 时 是 最 常 用 的 指 令 之 一 。 其 格 式 有 两 种 :
2017-10-20 17:09:52 +08:00
* * shell * 格 式 : ` RUN <命令> ` , 就 像 直 接 在 命 令 行 中 输 入 的 命 令 一 样 。 刚 才 写 的 Dockerfile 中 的 ` RUN ` 指 令 就 是 这 种 格 式 。
2016-11-26 02:02:43 +08:00
2019-10-29 14:31:45 +08:00
` ` ` docker
2016-11-26 02:02:43 +08:00
RUN echo ' < h1 > Hello , Docker ! < / h1 > ' > / usr / share / nginx / html / index . html
` ` `
* * exec * 格 式 : ` RUN ["可执行文件", "参数1", "参数2"] ` , 这 更 像 是 函 数 调 用 中 的 格 式 。
既 然 ` RUN ` 就 像 Shell 脚 本 一 样 可 以 执 行 命 令 , 那 么 我 们 是 否 就 可 以 像 Shell 脚 本 一 样 把 每 个 命 令 对 应 一 个 RUN 呢 ? 比 如 这 样 :
2019-10-29 14:31:45 +08:00
` ` ` docker
2018-12-19 17:07:40 +08:00
FROM debian : stretch
2016-11-26 02:02:43 +08:00
RUN apt - get update
2018-12-19 17:07:40 +08:00
RUN apt - get install - y gcc libc6 - dev make wget
RUN wget - O redis . tar . gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
2016-11-26 02:02:43 +08:00
RUN mkdir - p / usr / src / redis
RUN tar - xzf redis . tar . gz - C / usr / src / redis -- strip - components = 1
RUN make - C / usr / src / redis
RUN make - C / usr / src / redis install
` ` `
之 前 说 过 , Dockerfile 中 每 一 个 指 令 都 会 建 立 一 层 , ` RUN ` 也 不 例 外 。 每 一 个 ` RUN ` 的 行 为 , 就 和 刚 才 我 们 手 工 建 立 镜 像 的 过 程 一 样 : 新 建 立 一 层 , 在 其 上 执 行 这 些 命 令 , 执 行 结 束 后 , ` commit ` 这 一 层 的 修 改 , 构 成 新 的 镜 像 。
而 上 面 的 这 种 写 法 , 创 建 了 7 层 镜 像 。 这 是 完 全 没 有 意 义 的 , 而 且 很 多 运 行 时 不 需 要 的 东 西 , 都 被 装 进 了 镜 像 里 , 比 如 编 译 环 境 、 更 新 的 软 件 包 等 等 。 结 果 就 是 产 生 非 常 臃 肿 、 非 常 多 层 的 镜 像 , 不 仅 仅 增 加 了 构 建 部 署 的 时 间 , 也 很 容 易 出 错 。
这 是 很 多 初 学 Docker 的 人 常 犯 的 一 个 错 误 。
* Union FS 是 有 最 大 层 数 限 制 的 , 比 如 AUFS , 曾 经 是 最 大 不 得 超 过 42 层 , 现 在 是 不 得 超 过 127 层 。 *
上 面 的 ` Dockerfile ` 正 确 的 写 法 应 该 是 这 样 :
2019-10-29 14:31:45 +08:00
` ` ` docker
2018-12-19 17:07:40 +08:00
FROM debian : stretch
2016-11-26 02:02:43 +08:00
2020-08-25 18:01:53 +08:00
RUN set - x ; buildDeps = ' gcc libc6 - dev make wget ' \
2016-11-26 02:02:43 +08:00
&& apt - get update \
&& apt - get install - y $ buildDeps \
2018-12-19 17:07:40 +08:00
&& wget - O redis . tar . gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
2016-11-26 02:02:43 +08:00
&& mkdir - p / usr / src / redis \
&& tar - xzf redis . tar . gz - C / usr / src / redis -- strip - components = 1 \
&& make - C / usr / src / redis \
&& make - C / usr / src / redis install \
&& rm - rf / var / lib / apt / lists / * \
&& rm redis . tar . gz \
&& rm - r / usr / src / redis \
&& apt - get purge - y -- auto - remove $ buildDeps
` ` `
2020-05-08 19:20:23 +08:00
首 先 , 之 前 所 有 的 命 令 只 有 一 个 目 的 , 就 是 编 译 、 安 装 redis 可 执 行 文 件 。 因 此 没 有 必 要 建 立 很 多 层 , 这 只 是 一 层 的 事 情 。 因 此 , 这 里 没 有 使 用 很 多 个 ` RUN ` 一 一 对 应 不 同 的 命 令 , 而 是 仅 仅 使 用 一 个 ` RUN ` 指 令 , 并 使 用 ` && ` 将 各 个 所 需 命 令 串 联 起 来 。 将 之 前 的 7 层 , 简 化 为 了 1 层 。 在 撰 写 Dockerfile 的 时 候 , 要 经 常 提 醒 自 己 , 这 并 不 是 在 写 Shell 脚 本 , 而 是 在 定 义 每 一 层 该 如 何 构 建 。
2016-11-26 02:02:43 +08:00
并 且 , 这 里 为 了 格 式 化 还 进 行 了 换 行 。 Dockerfile 支 持 Shell 类 的 行 尾 添 加 ` \ ` 的 命 令 换 行 方 式 , 以 及 行 首 ` # ` 进 行 注 释 的 格 式 。 良 好 的 格 式 , 比 如 换 行 、 缩 进 、 注 释 等 , 会 让 维 护 、 排 障 更 为 容 易 , 这 是 一 个 比 较 好 的 习 惯 。
此 外 , 还 可 以 看 到 这 一 组 命 令 的 最 后 添 加 了 清 理 工 作 的 命 令 , 删 除 了 为 了 编 译 构 建 所 需 要 的 软 件 , 清 理 了 所 有 下 载 、 展 开 的 文 件 , 并 且 还 清 理 了 ` apt ` 缓 存 文 件 。 这 是 很 重 要 的 一 步 , 我 们 之 前 说 过 , 镜 像 是 多 层 存 储 , 每 一 层 的 东 西 并 不 会 在 下 一 层 被 删 除 , 会 一 直 跟 随 着 镜 像 。 因 此 镜 像 构 建 时 , 一 定 要 确 保 每 一 层 只 添 加 真 正 需 要 添 加 的 东 西 , 任 何 无 关 的 东 西 都 应 该 清 理 掉 。
很 多 人 初 学 Docker 制 作 出 了 很 臃 肿 的 镜 像 的 原 因 之 一 , 就 是 忘 记 了 每 一 层 构 建 的 最 后 一 定 要 清 理 掉 无 关 文 件 。
2019-11-06 14:53:09 +08:00
# # 构 建 镜 像
2016-11-26 02:02:43 +08:00
好 了 , 让 我 们 再 回 到 之 前 定 制 的 nginx 镜 像 的 Dockerfile 来 。 现 在 我 们 明 白 了 这 个 Dockerfile 的 内 容 , 那 么 让 我 们 来 构 建 这 个 镜 像 吧 。
在 ` Dockerfile ` 文 件 所 在 目 录 执 行 :
` ` ` bash
$ docker build - t nginx : v3 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM nginx
-- - > e43d811ce2f4
Step 2 : RUN echo ' < h1 > Hello , Docker ! < / h1 > ' > / usr / share / nginx / html / index . html
-- - > Running in 9 cdc27646c7b
-- - > 44 aa4490ce2c
Removing intermediate container 9 cdc27646c7b
Successfully built 44 aa4490ce2c
` ` `
从 命 令 的 输 出 结 果 中 , 我 们 可 以 清 晰 的 看 到 镜 像 的 构 建 过 程 。 在 ` Step 2 ` 中 , 如 同 我 们 之 前 所 说 的 那 样 , ` RUN ` 指 令 启 动 了 一 个 容 器 ` 9cdc27646c7b ` , 执 行 了 所 要 求 的 命 令 , 并 最 后 提 交 了 这 一 层 ` 44aa4490ce2c ` , 随 后 删 除 了 所 用 到 的 这 个 容 器 ` 9cdc27646c7b ` 。
这 里 我 们 使 用 了 ` docker build ` 命 令 进 行 镜 像 构 建 。 其 格 式 为 :
` ` ` bash
docker build [ 选 项 ] < 上 下 文 路 径 / URL / - >
` ` `
在 这 里 我 们 指 定 了 最 终 镜 像 的 名 称 ` -t nginx:v3 ` , 构 建 成 功 后 , 我 们 可 以 像 之 前 运 行 ` nginx:v2 ` 那 样 来 运 行 这 个 镜 像 , 其 结 果 会 和 ` nginx:v2 ` 一 样 。
2019-11-06 14:53:09 +08:00
# # 镜 像 构 建 上 下 文 ( Context )
2016-11-26 02:02:43 +08:00
2019-03-08 12:21:07 +08:00
如 果 注 意 , 会 看 到 ` docker build ` 命 令 最 后 有 一 个 ` . ` 。 ` . ` 表 示 当 前 目 录 , 而 ` Dockerfile ` 就 在 当 前 目 录 , 因 此 不 少 初 学 者 以 为 这 个 路 径 是 在 指 定 ` Dockerfile ` 所 在 路 径 , 这 么 理 解 其 实 是 不 准 确 的 。 如 果 对 应 上 面 的 命 令 格 式 , 你 可 能 会 发 现 , 这 是 在 指 定 * * 上 下 文 路 径 * * 。 那 么 什 么 是 上 下 文 呢 ?
2016-11-26 02:02:43 +08:00
2019-01-06 09:50:03 +08:00
首 先 我 们 要 理 解 ` docker build ` 的 工 作 原 理 。 Docker 在 运 行 时 分 为 Docker 引 擎 ( 也 就 是 服 务 端 守 护 进 程 ) 和 客 户 端 工 具 。 Docker 的 引 擎 提 供 了 一 组 REST API , 被 称 为 [ Docker Remote API ] ( https : //docs.docker.com/develop/sdk/),而如 `docker` 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 `docker` 功能, 但实际上, 一切都是使用的远程调用形式在服务端( Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举。
2016-11-26 02:02:43 +08:00
当 我 们 进 行 镜 像 构 建 的 时 候 , 并 非 所 有 定 制 都 会 通 过 ` RUN ` 指 令 完 成 , 经 常 会 需 要 将 一 些 本 地 文 件 复 制 进 镜 像 , 比 如 通 过 ` COPY ` 指 令 、 ` ADD ` 指 令 等 。 而 ` docker build ` 命 令 构 建 镜 像 , 其 实 并 非 在 本 地 构 建 , 而 是 在 服 务 端 , 也 就 是 Docker 引 擎 中 构 建 的 。 那 么 在 这 种 客 户 端 / 服 务 端 的 架 构 中 , 如 何 才 能 让 服 务 端 获 得 本 地 文 件 呢 ?
这 就 引 入 了 上 下 文 的 概 念 。 当 构 建 的 时 候 , 用 户 会 指 定 构 建 镜 像 上 下 文 的 路 径 , ` docker build ` 命 令 得 知 这 个 路 径 后 , 会 将 路 径 下 的 所 有 内 容 打 包 , 然 后 上 传 给 Docker 引 擎 。 这 样 Docker 引 擎 收 到 这 个 上 下 文 包 后 , 展 开 就 会 获 得 构 建 镜 像 所 需 的 一 切 文 件 。
如 果 在 ` Dockerfile ` 中 这 么 写 :
2019-10-29 14:31:45 +08:00
` ` ` docker
2016-11-26 02:02:43 +08:00
COPY . / package . json / app /
` ` `
这 并 不 是 要 复 制 执 行 ` docker build ` 命 令 所 在 的 目 录 下 的 ` package.json ` , 也 不 是 复 制 ` Dockerfile ` 所 在 目 录 下 的 ` package.json ` , 而 是 复 制 * * 上 下 文 ( context ) * * 目 录 下 的 ` package.json ` 。
因 此 , ` COPY ` 这 类 指 令 中 的 源 文 件 的 路 径 都 是 * 相 对 路 径 * 。 这 也 是 初 学 者 经 常 会 问 的 为 什 么 ` COPY ../package.json /app ` 或 者 ` COPY /opt/xxxx /app ` 无 法 工 作 的 原 因 , 因 为 这 些 路 径 已 经 超 出 了 上 下 文 的 范 围 , Docker 引 擎 无 法 获 得 这 些 位 置 的 文 件 。 如 果 真 的 需 要 那 些 文 件 , 应 该 将 它 们 复 制 到 上 下 文 目 录 中 去 。
现 在 就 可 以 理 解 刚 才 的 命 令 ` docker build -t nginx:v3 . ` 中 的 这 个 ` . ` , 实 际 上 是 在 指 定 上 下 文 的 目 录 , ` docker build ` 命 令 会 将 该 目 录 下 的 内 容 打 包 交 给 Docker 引 擎 以 帮 助 构 建 镜 像 。
如 果 观 察 ` docker build ` 输 出 , 我 们 其 实 已 经 看 到 了 这 个 发 送 上 下 文 的 过 程 :
` ` ` bash
$ docker build - t nginx : v3 .
Sending build context to Docker daemon 2.048 kB
...
` ` `
理 解 构 建 上 下 文 对 于 镜 像 构 建 是 很 重 要 的 , 避 免 犯 一 些 不 应 该 的 错 误 。 比 如 有 些 初 学 者 在 发 现 ` COPY /opt/xxxx /app ` 不 工 作 后 , 于 是 干 脆 将 ` Dockerfile ` 放 到 了 硬 盘 根 目 录 去 构 建 , 结 果 发 现 ` docker build ` 执 行 后 , 在 发 送 一 个 几 十 GB 的 东 西 , 极 为 缓 慢 而 且 很 容 易 构 建 失 败 。 那 是 因 为 这 种 做 法 是 在 让 ` docker build ` 打 包 整 个 硬 盘 , 这 显 然 是 使 用 错 误 。
2017-02-18 14:35:44 +08:00
一 般 来 说 , 应 该 会 将 ` Dockerfile ` 置 于 一 个 空 目 录 下 , 或 者 项 目 根 目 录 下 。 如 果 该 目 录 下 没 有 所 需 文 件 , 那 么 应 该 把 所 需 文 件 复 制 一 份 过 来 。 如 果 目 录 下 有 些 东 西 确 实 不 希 望 构 建 时 传 给 Docker 引 擎 , 那 么 可 以 用 ` .gitignore ` 一 样 的 语 法 写 一 个 ` .dockerignore ` , 该 文 件 是 用 于 剔 除 不 需 要 作 为 上 下 文 传 递 给 Docker 引 擎 的 。
2016-11-26 02:02:43 +08:00
那 么 为 什 么 会 有 人 误 以 为 ` . ` 是 指 定 ` Dockerfile ` 所 在 目 录 呢 ? 这 是 因 为 在 默 认 情 况 下 , 如 果 不 额 外 指 定 ` Dockerfile ` 的 话 , 会 将 上 下 文 目 录 下 的 名 为 ` Dockerfile ` 的 文 件 作 为 Dockerfile 。
这 只 是 默 认 行 为 , 实 际 上 ` Dockerfile ` 的 文 件 名 并 不 要 求 必 须 为 ` Dockerfile ` , 而 且 并 不 要 求 必 须 位 于 上 下 文 目 录 中 , 比 如 可 以 用 ` -f ../Dockerfile.php ` 参 数 指 定 某 个 文 件 作 为 ` Dockerfile ` 。
当 然 , 一 般 大 家 习 惯 性 的 会 使 用 默 认 的 文 件 名 ` Dockerfile ` , 以 及 会 将 其 置 于 镜 像 构 建 上 下 文 目 录 中 。
2019-11-06 14:53:09 +08:00
# # 其 它 ` docker build ` 的 用 法
2016-11-26 02:02:43 +08:00
2019-11-06 14:53:09 +08:00
# # # 直 接 用 Git repo 进 行 构 建
2016-11-26 02:02:43 +08:00
或 许 你 已 经 注 意 到 了 , ` docker build ` 还 支 持 从 URL 构 建 , 比 如 可 以 直 接 从 Git repo 中 构 建 :
` ` ` bash
2020-08-25 18:01:53 +08:00
# $ env : DOCKER_BUILDKIT = 0
# export DOCKER_BUILDKIT = 0
$ docker build - t hello - world https : //github.com/docker-library/hello-world.git#master:amd64/hello-world
Step 1 / 3 : FROM scratch
-- - >
Step 2 / 3 : COPY hello /
-- - > ac779757d46e
Step 3 / 3 : CMD [ "/hello" ]
-- - > Running in d2a513a760ed
Removing intermediate container d2a513a760ed
-- - > 03 8 ad4142d2b
Successfully built 03 8 ad4142d2b
2016-11-26 02:02:43 +08:00
` ` `
2020-08-25 18:01:53 +08:00
这 行 命 令 指 定 了 构 建 所 需 的 Git repo , 并 且 指 定 分 支 为 ` master ` , 构 建 目 录 为 ` /amd64/hello-world/ ` , 然 后 Docker 就 会 自 己 去 ` git clone ` 这 个 项 目 、 切 换 到 指 定 分 支 、 并 进 入 到 指 定 目 录 后 开 始 构 建 。
2016-11-26 02:02:43 +08:00
2019-11-06 14:53:09 +08:00
# # # 用 给 定 的 tar 压 缩 包 构 建
2016-11-26 02:02:43 +08:00
` ` ` bash
$ docker build http : //server/context.tar.gz
` ` `
如 果 所 给 出 的 URL 不 是 个 Git repo , 而 是 个 ` tar ` 压 缩 包 , 那 么 Docker 引 擎 会 下 载 这 个 包 , 并 自 动 解 压 缩 , 以 其 作 为 上 下 文 , 开 始 构 建 。
2019-11-06 14:53:09 +08:00
# # # 从 标 准 输 入 中 读 取 Dockerfile 进 行 构 建
2016-11-26 02:02:43 +08:00
` ` ` bash
docker build - < Dockerfile
` ` `
或
` ` ` bash
cat Dockerfile | docker build -
` ` `
如 果 标 准 输 入 传 入 的 是 文 本 文 件 , 则 将 其 视 为 ` Dockerfile ` , 并 开 始 构 建 。 这 种 形 式 由 于 直 接 从 标 准 输 入 中 读 取 Dockerfile 的 内 容 , 它 没 有 上 下 文 , 因 此 不 可 以 像 其 他 方 法 那 样 可 以 将 本 地 文 件 ` COPY ` 进 镜 像 之 类 的 事 情 。
2019-11-06 14:53:09 +08:00
# # # 从 标 准 输 入 中 读 取 上 下 文 压 缩 包 进 行 构 建
2016-11-26 02:02:43 +08:00
` ` ` bash
$ docker build - < context . tar . gz
` ` `
如 果 发 现 标 准 输 入 的 文 件 格 式 是 ` gzip ` 、 ` bzip2 ` 以 及 ` xz ` 的 话 , 将 会 使 其 为 上 下 文 压 缩 包 , 直 接 将 其 展 开 , 将 里 面 视 为 上 下 文 , 并 开 始 构 建 。