Docker 构建镜像初体验

125 阅读3分钟

Docker 基本概念

当在使用 Docker 时,既是在创建和使用镜像(images)、容器(containers)、网络(networks)、卷轴(volumes)、插件(plugins)和其他的对象。

镜像(Images)

镜像是只读的模板,而且带有创创建 Docker 容器的一些指令。通常,一个镜像是基于另一个镜像,添加一些自定义的编辑。例如,你可能会在 ubuntu 镜像上构建一个新的镜像,并在其中安装其他的应用。

你可以构建自己的镜像或者直接使用别人发布的镜像。构建镜像时,需要创建 Dockerfile 声明创建的步骤和如何运行它。**Dockerfile 的每一条指令都会在镜像中创建一层**,每当你修改 Dockerfile 或者重新构建镜像时,只有哪些被修改了的指令对应的镜像层会被重新构建,这也是为什么镜像那么轻量、小巧、快速的原因之一。

容器(Container)

容器是镜像的可运行实例。容器由镜像和你在创建和启动容器时提供的配置共同定义,当容器被移除时,所有非持久存储的状态都会一并消失。

默认情况下,容器与其他容器及宿主机之间相互隔离,当然你也可以控制如何隔离它们之间的网络、存储以及其他的子系统。

Dockerfile 的命令

Docker 可以通过读取 Dockerfile 的指令来构建镜像。

FROM

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

FROM 指令为接下来的指令初始化一个基础镜像(Base Image),所以有效的 Dockerfile 必须以 FROM 指令开头。

FROM 指令可以在一个文件中出现多次,每个 FROM 指令会清空之前的所有状态。为上个阶段的 FROM 设置 AS name 可以在后续的 FROMCOPY —from=<name> 指令中通过名字引用到该镜像。

RUN

RUN <command>

RUN ["executable", "param1", "param2"]

RUN 指令会在当前镜像中执行命令,并且将运行结果提交,作为后续阶段使用。SHELL 风格和 EXEC 风格的指令区别在于,EXEC 风格不需要做字符转译。

另外 EXEC 风格也不会触发 SHELL 的处理,例如:RUN ["echo", "$HOME"]$HOME 不会被替换成环境变量,因为指令并没有通过 SHELL 处理,需要切换成 RUN ["/bin/bash", "-c", "echo hello"] 才有效。

CMD

CMD command param1 param2

CMD ["executable","param1","param2"] 单个文件只能存在一个 CMD 指令,如果有多个则仅有最后一个指令生效。

CMD 的只要目的是为运行中的容器提供缺省值,它会在容器启动后执行。

💡 EXEC 风格会被解析成 JSON Array,因而必须使用双引号 `"` 。

ADD

ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

ADD 指令将新文件、目录或者远程文件的 URL 从 <src> 添加到镜像 <dest> 的文件系统中。<src> 为当前工作目录下的路径。

COPY

COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

COPY 指令将新文件、目录从<src>添加到镜像<dest>的文件系统中。

💡 `ADD` 与 `COPY` 之间的差别在于:
  1. ADD 能够添加远程文件而 COPY 不能;
  2. COPY 能够用于多阶段的构建而 ADD 不能;

Docker 镜像的制作

主要流程

  1. docker login <registry> 登录

  2. docker build <path> 通过路径下的 Dockerfile 构建镜像

  3. docker push 推送镜像

    1. docker image tag <name>:<tag> <registry>/<name>:<tag>
    2. docker image push <registry>/<name>:<tag>

调试

为某个项目构建特定镜像时,通常需要一定地调试,若每次都将镜像推送到 registry,再切换到该项目中进行构建测试,则显得过于繁琐。

此时可以考虑将项目文件挂在到镜像的容器中,并进入文件执行操作以进行调试。

  1. docker build <path> 构建镜像
  2. docker run -v <host-src>:<container-dest> 挂载本地文件目录到容器中
  3. docker attch <container-id> 进入容器并控制容器
  4. 执行任意命令进行测试
  5. 推送

Reference

Reference documentation

github.com/yeasy/docke…