Dockerfile

133 阅读5分钟

Dockerfile 是一个创建镜像的所有命令的文本文件夹,包含了一条条执行和说明,每条指令构建一层,通过docker build 命令 根据Dockerfile的内容构建镜像,因此每条指令的内容就是描述该层如何构建。有了Dockerfile,就就可以指定自己的docker 权限规则,只需要在Dockerfile上添加或者修改指令,就可以生成Docker镜像。

Dockerfile 是用来构建Docker镜像的文本文件,是由一条条构建镜像需要的指令和参数构成的脚本。
构建的三个步骤:编写Dockerfile 文件,docker build 命令构建镜像 docker run 依据镜像运行容器实例

Dockerfile 基础知识

  1. 每条保留字指令都必须为大写字母,且后面要跟至少一个参数
  2. 指令按照从上到下顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

Docker 执行Dockerfile 的大致流程

  1. docekr 从基础镜像运行一个容器
  2. 执行一条指令并对容器做出修改
  3. 执行类似docker commit 的提交操作提交一个新的镜像层
  4. docker 在基于刚提交的镜像运行一个新容器
  5. 执行 dockerfile 中的下一条指令直到所有的指令都执行完成

Dockerfile基本指令

FROM

基础镜像,当前镜像是基于那个镜像的,指定一个已经存在的镜像作为模版,第一条必须是FROM 例子:
FROM centos:7.9.2009 有版本号的一定要指定清楚版本号。

MAINTAINER

镜像维护者的名称和邮箱地址。例子:MAINTAINER wyn<40xxxxxx@qq.com>

RUN

构建镜像需要运行的命令 两种格式(shell格式和,exec格式) RUN 是在docker build 时运行的 例子:
RUN yum -y install vim

EXPOSE

当前容器对外暴露的端口 例子 EXPOSE 80

ENV

用来在构建镜像的过程中设置环境变量 例子:ENV MYPATH /usr/local

ENV MY_PATH /usr/mytest
# 这个定义的环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
#也可以在其他指令中直接使用这些环境变量
# 比如 WORKDIR $MY_PATH
WORKDIR

指定在容器创建之后,终端默认登录进来的工作目录,一个落脚点,例子WORKDIR $MY_PATH 这里使用的上面ENV 定义的环境变量(指定的是容器内的路径)通过WORKDIR 设置工作目录后,Dockerfile中其后的命令 RUN、CMD、ENTRPOINT、ADD、COPY 等目录都会在该目录下执行,在使用docker run 运行容器时,可以通过 -w 参数覆盖构建是所设置的工作目录。 如果我们通过WORKDIR 设置的路径在容器中不存在的话,会自动创建

USER

指定该镜像以什么样的用户去执行,如果都不指定默认是root

ADD

将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包,例子:

ADD jdk-8u191-linux-x64.tar.gz /usr/local/java/COPY

第二个参数是容器内部的目录位置。

VLOUME

容器数据卷,用于数据保存和持久化工作

CMD

指定容器启动后要干的事

CMD 容器启动命令
CMD 指令的格式和RUN 相似,也是两种格式:
#shell 格式:CMD<命令>
#exec 格式:CMD["可执行文件","参数1","参数2"...]
#参数列表格式 CMD ["参数1","参数2"...] ,在制定了ENTRYPOINT 指令后,用 CMD 指定具体参数

注意: Dockerfile 中可以有多个CMD指令,但是只有最后一个生效,CMD命令被 docker run 之后的参数替换掉

默认tomact 的 Dockerfile文件的最后面两条指令是:
EXPOSE 8080
CMD ["catalina.sh","run"]
这时候如果我们运行指令 docker run -it -p 8080:8080 镜像id
访问8080端口的时候可以看到页面
但是如果我们使用命令 docker run -it -p 8080:8080 镜像id /bin/bash
在访问8080的时候就会发现看不到页面了
原因:
后面加了 /bin/bash
就相当于将tomcat Dockerfile最后的代码修改为
EXPOSE 8080
CMD ["catalina.sh","run"]
CMD ["/bin/bash","run"]
就会覆盖我们原来的 CMD 命令的内容

和RUN 命令的区别:

  1. CMD 是在docker run 时运行的
  2. RUN 是在docker build 时运行的。
ENTRYPOINT

也是用来指定一个容器启动时要运行的命令 类属于CMD命令,但是ENTRYPOINT 不会被docker run 后面的命令覆盖,而且这些命令运行参数会被当做参数送给ENTRYPOINT 指定的程序
命令格式和案例说明

命令格式: ENTRYPOINT ["<executeable>","<paraml>","<param2>"...]
ENTRYPOINT 可以和CMD一起使用,一般是变参才会使用CMD ,这里的CMD等于是在给ENTRYPOINT传递参数。
当指定了ENTRYPOINT后,CMD的含义就会发生变化,不在是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指定,他两个组合会变成<ENTRYPOINT>"<CMD>"
案例如下:
假设已经通过DOckerfile构建了nginx:test镜像
FROM nginx

ENTRYPOINT ['nginx',"-c"]  # 定参
CDM ["/etc/nginx/nginx.conf"]  # 变参

构建镜像

docker build -t 新镜像的名字:TAG . 注意TAG 后面有个点

docker build -t centosjava8:1.5 .

注意命令不要写错,最新版本的centos 会报错,我们最好自己下载一个7 版本的然后在Dockerfile 文件中指定一下。

虚悬镜像

image-20240514074201668.png

查看虚悬镜像 docker iamges ls -f dangling=true
删除所有虚悬镜像:docker images prune