Loading... # Docker File 解析: ## 构建简史 编写一个 dockerfile 的文件,符合 dockerfile 的规范 docker build 执行,获得一个自定义的镜像 docker 运行 Docker 执行 docker file 文件的大致流程 > docker 从基础镜像运行一个容器 执行一条指令并对容器作出修改 执行类似 docker commit 的操作提交一个新的镜像层 docker 在基于刚提交的镜像运行一个新容器 执行 docker 中的下一条指令知道所有指令都执行完成 ## Docker File 基础知识: ![](http://type.zimopy.com/usr/uploads/2023/11/3574276738.png) 每条**保留字**指令必须为大写字母且后面要跟随至少一个参数 指令从上到下、从左至右执行 ‘#’ :表示注释 每条指令都会创建一个新的镜像层,并对镜像进行提交 ## Docker File 体系结构: ### 保留字指令: FROM:基础镜像,当前这个新的镜像是基于哪个镜像(scratch) MAINTAINER:镜像作者 + 邮箱 RUN:容器构建时所需要运行的命令 EXPOSE:当前容器对外暴露的端口号 WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 ENV:用于构建镜像过程中设置环境变量 ADD: 拷贝加解压缩:将宿主机目录下的文件拷贝进镜像且 add 命令会自动处理 rul 和解压 tar 压缩包 COPY: 将从构建上下文目录中 <源路径> 的文件 / 目录复制到新的一层的镜像内的 < 目标路径 > 位置 * COPY src dest * COPY [“src”,”dest”] VOLUME: 容器数据卷,用于数据保存和持久化工作 CMD: * 指定一个容器启动时要运行的命令 * DockerFile 中可以有多个 CMD 指令, **但只有最后一个生效** ,CMD 会被 docker run 之后的参数替换!!! ENTRYPOINT: * 指定一个容器启动时要运行的命令 * 目的与 CMD 一样,都是在指定容器启动程序及参数 * 不会被替换,被追加 ONBUILD:触发器 当构建一个被继承 Docker File 时运行的命令,父镜像在被子继承后父镜像的 onbuild 被触发 ![](http://type.zimopy.com/usr/uploads/2023/11/4098853817.png) ![](http://type.zimopy.com/usr/uploads/2023/11/3729216525.png) # 关键字详解 ## Dockerfile 分为四部分: > 基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。 ## 基础镜像信息 ### FROM ```python # 格式 FROM <image> or FROM <image>:<tag> ``` > 如果在同一个 Dockerfile 中创建多个镜像时,可以使用多个 `FROM` 指令(每个镜像一次) 注意: Dockerfile 每个保留字都会在 docker 容器中新建一层镜像层,合理的减少镜像层以达节省资源的目的 ```bash # base FROM python:3.7 RUN pip3 install requests RUN pip3 install bs4 RUN pip3 install scrapy RUN ... # other FROM python:3.7 RUN pip3 install requests bs64 scrapy # Python通过空格分隔,达到安装多个包的效果 # batter # 外部建立所安装包 pip3 freeze >> requirements.txt # 在Dockerfile 中 FROM python:3.7 RUN pip3 install -r requirements.txt ``` > 分析:达到的效果虽相同,但所用资源却不同,base 所使用的资源约为 other,batter 的 3/5 > > * base 三层 > * other 一层 > * batter 一层 > > 1. 若所需要使用到的第三方库较少,建议使用 other > 2. 在实际工程中用到的第三方库大多情况下都大于三个,方法二虽好。但所需导入的包一多,很可能出现单词拼写错误,格式不符 ## 维护者信息 (非必须) ### MAINTAINER ```bash # 格式 MAINTAINR <name> ``` ## 镜像操作指令 (按需择选) ### COPY > 作用: 复制文件指令,从上下文 目录中复制或目录, 到容器中的指定路径 同等需求下建议使用 COPY ```bash # 格式 COPY <src> <dest> COPY [--chown=<user>:<group>] <源路径1>... <目标路径> COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"] # [--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。 # 复制本地主机的 `<src>`(为 Dockerfile 所在目录的相对路径)到容器中的 `<dest>` ``` **<源路径>** :源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。 ```bash COPY hom* dir/ COPY hom?.txt dir/ ``` **<目标路径>** :容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。 ### ADD > 作用: 复制文件指令,从上下文 目录中复制或目录, 到容器中的指定路径 同等需求下建议使用 COPY ```bash # 格式 ADD <src> <dest>` # 该命令将复制指定的 `<src>` 到容器中的 `<dest>`。 # 其中 `<src>` 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。 ``` * ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 < 目标路径 >。 * ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定 小结: * ADD 与 COPY 功能无明显差异, 但针对性不同 * 当使用本地文件为源目录时,建议使用 Copy * 当需使用压缩包中文件时构建时,建议使用 Copy ### RUN > 作用:用于在容器内执行命令 ```bash # 格式 RUN <command> [option] # 相当于shell格式 RUN ["command", "option1", 'option2'] # 相当于 exec 格式 ``` ### WORKDIR > 作用:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作 (主) 目录,必须是提前创建好)。 docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。 ```bash # 格式 WORKDIR <dir> ``` ### USE > 作用:用于指定将使用命令的用户和用户组 此处只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 由于 docker 无设置,默认需在 root 权限下运行 正所谓权限越大能力越大,若被入侵则造成损失较于其他权限为最大 安全与灵活性 二者相对斟酌 ```bash # 格式 USER <username>[:<usergroup>] ``` ### EXPOSE > 作用:仅声明端口 > > * 方便配置映射 > * 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。 ```bash # 格式 EXPORT <port1> [<prot2> <prot3> ...] ``` ## 执行指令 ### CMD > 作用:类似于 RUN 命令,但运行处不同 > > * RUN 在 Docker build 前运行 > * CMD 在 docker run 后运行 > > 注意: > > * 当 Dockerfile 中存在多个 CMD 指令,**仅最后一个生效。** > * CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。 > > 当使用自定制镜像时,大致流程为 > > * 编写业务代码 > * 构建定制镜像 (docker build) > * docker 中运行业务 (Docker run) ```bash # 格式 CMD <ShellCommand1 [option]> [&&ShellCommand2[option] ] CMD ["<可执行命令或文件>", "<option1>", "<option2>", ... ] # 此写法为保留字 ENTRYPOINT 指令指定的程序提供默认参数 CMD ["<command1>", "<command2>", "<command3>", ...] ``` ### ENTRYPOINT > 作用:功能与 CMD 相似,但不会被 docker run 后的指定参数所覆盖,命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。 但是当 docker run 使用了 —entrypoint 选项此选项的参数,可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。 ENTRYPOINT CMD 对比 同:多个 指令,**仅最后一个生效。** 异: ENTRYPOINT 选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。 ```bash # 格式 ENTRYPOINT ["<可执行命令或文件>","option1", "option2"] ``` ### ENV > 作用:配置容器内的环境变量,且保存,可以被后续 指令使用 ```bash # 格式 ENV <Key> <Values> ENV <Key1>=<Values1>, <Key2>=<Values2> ... ``` ### ARG > 作用:配置容器内的环境变量,且保存,可以被后续 指令使用(与 ENV 功能相似) 不同:作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效 也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。 ```bash 构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。 ``` ```bash # 格式 ARG <key>[=默认值], <Value> # 若不写Value 则Build时为自己写的默认值 ``` ### VOLUME > 作用:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。 > > * 避免重要的数据,因容器重启而丢失 > * 避免容器不断变大 ```bash # 格式: VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径> ``` ``` 在启动容器 docker run 的时候,我们可以通过 -v 参 ``` ### HEALTHCHECK > 作用:用于指定某个程序或者指令来监控 docker 容器服务的运行状态。 格式: ```bash HEALTHCHECK [option] CMD <command> #设置检查容器健康状况的命令 HEALTHCHECK NONE # 如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 HEALTHCHECK [option] CMD <command> # CMD 后面跟随的命令使用 ``` ### ONBUILD > 作用:用于延迟构建命令的执行。 先构建一个父类镜像 (ONBUILD 在父类中,但不立即执行), 后子类继承此父类镜像 (执行父类的 ONBUILD 命令) 本次并不执行,当镜像调用它时,将执行父类中 ONBUILD 命令 ```bash # 格式 ONBUILD <其它指令> ``` 最后修改:2023 年 11 月 28 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏