您的位置:首页 > 运维架构 > Docker

初识DOCKERFILE

2017-11-15 13:38 381 查看

初识DOCKERFILE



 



 



 

示例

[root@dockerdevops ~]# mkdir newdir

[root@dockerdevops ~]# cd newdir

[root@dockerdevops newdir]# touch Dockerfile

[root@dockerdevops newdir]# echo "FROM ubuntu:latest"> Dockerfile

[root@dockerdevops newdir]# echo "RUN mkdir /dir1">>Dockerfile

[root@dockerdevops newdir]# docker build -t testimage .

Sending build context to Docker daemon 2.048kB

Step 1/2 : FROM ubuntu:latest

---> 747cb2d60bbe

Step 2/2 : RUN mkdir /dir1

---> Running in 1a2f1bb5a3e7

---> 6344d592f811

Removing intermediate container 1a2f1bb5a3e7

Successfully built 6344d592f811

Successfully tagged testimage:latest

[root@dockerdevops newdir]#

 

解释

Docker指令是从上到下一层一层执行的,所以在使用这个Dockerfile构建镜像时,首先执行FROM ubuntu:latest这条指令。

FROM ubuntu:latest指定ubuntu:latest作为基础镜像,也就是将ubuntu:latest镜像的所有镜像层放置在testimage镜像的最下面。

然后执行RUN mkdir dir1指令,前面我们说过,执行RUN指令时,会在之前指令创建出的镜像的基础上创建一个临时容器,在这里的容器Id为c5117d908931,并在容器中运行命令。在命令结束运行后提交新容器为新镜像,并删除临时创建的容器c5117d908931。

在Dockerfile的所有指令执行完后,新镜像就构建完成了!

注意事项,谨慎使用RUN

修改前的Dokcerfile文件

既然RUN就像 Shell 脚本一样可以执行命令,那么是否就可以像Shell 脚本一样把每个命令对应一个RUN呢?比如这样

FROM debian:jessie

RUN apt-get update

RUN apt-get install -y gcc libc6-dev make

RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"

RUN mkdir -p /usr/src/redis

RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1

RUN make -C /usr/src/redis

RUN make -C /usr/src/redis install
上面这个Dockerfile是为了编译、安装 redis可执行文件。虽然它能够完成了所需的功能,但是正如之前说过,Dockerfile中每一个指令都会建立一层,RUN 也不例外。每一个RUN的行为,都会创建一个新的镜像层。

而上面的这种写法,创建了 8 层镜像(1层基础镜像+7层由RUN执行创建的镜像)。这是完全没有意义的,而且很多运行时不需要的东西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。

修改后的Dockerfile文件

因为之前所有的命令只有一个目的,就是编译、安装 redis 可执行文件。因此没有必要建立很多层,这只是一层的事情。因此,修改之后的Dockerfile文件并没有使用很多个RUN指令,而仅仅使用一个RUN 指令,并使用 &&将各个命令串联起来。除此以外,把redis的编译环境、更新的软件包也通通清除掉了,减少镜像占用的存储空间。如下所示,修改之后的Dockerfile构建完成后是就只会有2层镜像了(1层基础镜像+1层由RUN执行创建的镜像)

FROM debian:jessie

RUN buildDeps='gcc libc6-dev make' \

&& apt-get update \

&& apt-get install -y $buildDeps \

&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \

&& mkdir -p /usr/src/redis \

&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-component

s=1 \

&& make -C /usr/src/redis \

&& make -C /usr/src/redis install \

&& rm -rf /var/lib/apt/lists/* \

&& rm redis.tar.gz \

&& rm -r /usr/src/redis \

&& apt-get purge -y --auto-remove $buildDeps
在Dockerfile的编写过程中一定要牢记一点:镜像的每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: