Docker-Dockerfile

目录

一、引入

1. 什么是Dockerfile

Dockerfile 是一个用来 构建镜像的文本文件,包含了一条条构建镜像所需的指令和说明。

  • Dockerfile 是一个文本文件
  • 包含了一条条的指令
  • 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
  • 对于开发人员:可以为开发团队提供一个完全一致的开发环境
  • 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件 构建一个新的镜像开始工作了
  • 对于运维人员:在部署时,可以实现应用的无缝移植

常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。
dockerFile是用来构建docker镜像的文件!命令参数脚本!

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。

我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。

而要自定义镜像,就必须先了解镜像的结构才行。

2. 镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。

我们以MySQL为例,来看看镜像的组成结构:

Docker-Dockerfile

简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。

我们要构建镜像,其实就是实现上述打包的过程。

; 3. 约定

  • Dockerfile中所用的所有文件一定要和Dockerfile文件在 同一级父目录下,可以为Dockerfile父目录的子目录
  • Dockerfile中相对路径默认都是Dockerfile所在的目录
  • Dockerfile中一定要惜字如金,能写到一行的指令,一定要写到一行,原因是分层构建,联合挂载这个特性。Dockerfile中每一条指令被视为一层

二、Dockerfile常用指令

Dockerfile就是一个文本文件,其中包含一个个的 指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

网上找到一张很有意思的图,我将它放在这。

Docker-Dockerfile

; 1. FROM

基础镜像,定制的镜像都是基于 FROM 的镜像。并且 必须是第一条指令

如果不以任何镜像为基础,那么写法为: FROM scratch

  • *格式
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
  • *例子
FROM mysql:5.7

FROM scratch

2. MAINTAINER

镜像是谁写的, 姓名+邮箱。可以只写一个。

新版Docker中将弃用,并使用 LABEL 指明

  • *格式
MAINTAINER <name>
  • *例子

MAINTAINER tyt

MAINTAINER 273@qq.com

MAINTAINER tyt<273@qq.com>

3. LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式。通俗点说就是为镜像指定标签。

  • *格式
LABEL <key>=<value> <key>=<value> <key>=<value> ...

  • *例子
LABEL org.opencontainers.image.authors="tyt" version="1.0" label1="l1"

4. RUN

镜像构建的时候需要运行的命令。有以下2种格式:

  • *shell 格式
RUN <命令行命令>

  • *exec格式
RUN ["可执行文件或命令", "参数1", "参数2", ...]

  • *例子
RUN yum -y install vim
RUN yum -y install net-tools
RUN ["/etc/execfile", "arg1", "arg1"]

RUN yum -y install vim \
    && RUN yum -y install net-tools \
    && RUN ["/etc/execfile", "arg1", "arg1"]

注意
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定 --no-cache参数,如: docker build --no-cache

5. CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMDdocker run 时运行。
  • RUNdocker build时运行。

作用

  • 为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。
  • CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意

  • 如果 Dockerfile 中如果存在多个 CMD 指令,仅 最后一个生效

  • *格式


CMD ["","","",...]

CMD <shell命令>

CMD ["","",...]

推荐使用第一种格式,执行过程比较明确。
第二种格式实际上在运行的过程中也会自动转换成第一种格式运行,
并且默认可执行文件是 sh, 即 /bin/bash

例如
CMD ls -a
会转换为
CMD ["ls", "-a"]
  • *例子

CMD ["/usr/bin/wc","--help"]

CMD echo "This is a test." | wc -l

ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]

默认执行时,运行以下命令
nginx -c /etc/nginx/nginx.conf

6. ENTRYPOINT

类似于 CMD 指令, 运行时机相同,都是在 docker run 执行,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数追加到 ENTRYPOINT 指令指定的程序。(具体谁被覆盖、谁被追加可看下方 镜像构建实战中的 验证CMD 和ENTRYPOINT区别)。

CMD与ENTRYPOINT不同点

  • ENTRYPOINT不会被运行的command覆盖,而 CMD则会被覆盖。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

ENTRYPOINT优点

  • 在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意

  • 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
  • 如果我们在Dockerfile种同时写了 ENTRYPOINTCMD,并且 CMD指令 不是一个完整的可执行命令,那么 CMD指定的内容将会作为 ENTRYPOINT的参数
  • 如果我们在Dockerfile种同时写了 ENTRYPOINTCMD,并且 CMD 是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效

  • *格式


ENTRYPOINT ["","","",...]

ENTRYPOINT <shell命令>
  • *例子

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]


传参运行
docker run  nginx:test -c /etc/nginx/my.conf

容器内会默认运行以下命令,启动主进程(/etc/nginx/my.conf:假设容器内已有此文件)
nginx -c /etc/nginx/my.conf
  • *对于上述提到的ENTRYPOINT和CMD同时存在时举例

`bash

ENTRYPOINT [“nginx”, “-c”]
CMD [“/etc/nginx/nginx.conf”]

nginx -c /etc/nginx/nginx.conf

第一种格式 TYT
第一种格式变量不存在
第二种格式 TYT
第二种格式变量不存在
第三种格式变量存在 TYT
第三种格式变量不存在 HSYSJ
第四种格式变量存在 HSYSJ
第四种格式变量不存在

Original: https://blog.csdn.net/qq_51938362/article/details/127811154
Author: 划水yi术家
Title: Docker-Dockerfile

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/654306/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球