Docker系列学习(七)——DockerFile介绍以及使用

  前面的章节学习之后(系列学习传送门:Docker 系列学习 - Circle_Wang - 博客园),其实我们基本可以正常使用他人已经编写好的docker镜像来进行容器步署操作或者更改了镜像了。这一章节我们将来学习如何通过DockerFile自行构建一个docker镜像(换句话说就是如何自己构建出一个容器模板)。当我们写好了一个DockerFile之后,可以使用以下命令来创建出按照DockerFile生成的一个镜像。

docker build -f Dockerfile的文件路径 -t 镜像名:TAG(TAG可以省略) .

  通过这个命令,docker就会根据指定的dockerfile开始生成一个指定镜像名:TAG的镜像(如果TAG被省略会默认生成latest),这里一定要注意最后有一个".",这个"."表示当前目录下

1、DockerFile文件命令

  首先我们需要来熟悉一下编写一个基本的DockerFile文件需要遵守的规则,全部命令参见参考网页1

   下面,我们将采用FROM,MAINTAINER,CMD,WORKDIR,RUN这几个命令来简单熟悉下怎么创建一个镜像。我的dockerfile文件如下:

# 从哪个基础镜像启动 
FROM ubuntu
# 设置该镜像编写者信息  
MAINTAINER CircleWang
# 设定从该镜像启动容器时默认进入的路径
WORKDIR /home
# 在构建镜像时执行两个命令
RUN apt-get update
RUN apt-get install vim -y
# 在启动容器时容器执行的命令
CMD echo '---我被执行了---'

  文件中已经有了基本的注释了,总结一下这整个dockerfile文件干了一个什么事情呢?第一行首先获取了一个基础镜像叫ubuntu,并且备注了一下编写这个镜像的作者(第二行命令),第三行命令是指当生成容器的时候(进入容器的时候)默认是在/home目录下的(大家可以回忆一下之前我们进入官方的ubuntu镜像制造的容器时都是在根目录下的吧)。接下来的两行命令(RUN),就是指在生成镜像时会执行apt-get update以及apt-get install vim -y两个命令,这两个命令其实就是在安装下载VIM(回忆咱们的这篇文章中:Docker系列学习(二)——查看,启动,退出,保存镜像的方法的第8点,官方的ubuntu镜像是没有安装vim的),以后只要是从我这个镜像(dockerfile文件创建的镜像)生成的容器,那么就是自带有vim的了。最后一行命令(CMD)其实是指当从镜像生成容器的时候,容器中会执行这个命令(这个命令的意思是打印一句话”---我被执行了---“)。

  这里要注意RUN和CMD这两个命令虽然都是执行,但是意义不同。RUN是指在构建镜像的时候(可以认为是定义类)会在这个类中执行(这里就是安装vim),但是在构建类的时候是不执行CMD的,换句话说当你在docker build的时候是不会打印”---我被执行了---“这句话的,只要当你从这个镜像中生成容器时,在容器内部会执行CMD命令。

  下面我们来看看你生成镜像,以及从这个镜像生成类的情况。

docker build -f my_dockerfile01 -t my_ubuntu .

   可以看到我已经生成了一个名叫my_ubuntu的镜像TAG为latset。下面我们再根据这个镜像(my_ubuntu)启动一个容器看看。

docker run -it my_ubuntu

   已经打印除了我们CMD的信息了。这里有个问题出现了,为什么我是用的时-it(交互运行容器)为什么没有进入到容器内呢?我们使用docker ps -a却是可以看到一个停止的容器的,为什么容器会直接停止呢。回忆一下我们之前启动官方的ubuntu系统时,启动完成了就会直接进入到容器内部的啊。并且还有一个非常奇怪的现象是我是用docker ps -a可以看到这个容器的id但是无法使用docker start 容器id的方式启动这个容器(其实查看细节应该是启动了又马上关闭了)。这个问题我查看了很多地方都没有说得很清楚的解释以后再补充吧,直接说解决方法。

方法一:直接在从镜像中启动容器时采用docker run -it my_ubuntu /bin/bash命令,最后添加的/bin/bsah指启动一个命令窗口,并以交互的形式,这样就可以直接进入容器了,并且关闭容器之后还能再次启动容器。

方法二:在dockerfile文件中最后一个命令CMD,更改为

CMD echo '---我被执行了---' && /bin/bash

这个意思就是不仅要打印”---我被执行了---“,还要进入/bin/bash,此时在使用docker run -it my_ubuntu命令进入就没有问题了。(注意更改了Dockerfile文件要重新build镜像哟)

2、CMD和ENTRYPOINT的区别

  前一节我们已经讲过了CMD的用法,也就是在从镜像生成容器时,在容器内部会执行的命令。但是这里要注意到CMD在dockerfile中只有最后一个会被执行,如果你的dockerfile中有多个CMD命令,只有最后一个CMD命令会被执行(这也就是前一节我是使用&&符号来链接命令而不使用两个CMD命令)。并且如果在使用docker run -it my_ubuntu 命令来启动容器的时候,此时后面如果加了/bin/bush(这种类似的命令行命令)此时就会忽略掉镜像中的CMD命令。(换句话说,如果采用docker run -it my_ubuntu /bin/bash启动容器,那么将不会打印出”---我被执行了---“这句话的)

  ENTRYPOINT的使用跟CMD一样,虽然依然是只有最后一个ENTRYPOINT才会被容器内命令行执行,但是却可以在末尾增加命令,也会在启动容器的时候执行的。

 

 

参考网页

Dockerfile命令详解(超全版本) - 大周说测试 - 博客园 (cnblogs.com)

posted @ 2022-04-13 16:34  Circle_Wang  阅读(705)  评论(0编辑  收藏  举报