使用Dockerfile来构建镜像

  1. Dockerfile原理
  2. 创建Dockerfile
  3. Dockerfile实例
  4. Dockerfile指令
    1. 注释
    2. FROM
    3. MAINTAINER
    4. RUN
    5. ADD
    6. WORKDIR
    7. ENV
    8. USER
    9. COPY
    10. CMD
    11. EXPOSE
  5. 构建docker镜像
  6. 测试
  7. 指定宿主机和容器端口映射

Dockerfile原理

  关于Docker中使用Dockerfile来构建镜像,可以简单的理解为:将所有的操作都写在一个脚本中,这个脚本的名称就叫Dockerfile,执行构建镜像的命令时,就会去执行这个命令。

  上面只是通俗的说法,其实,你写完Dockerfile之后,执行构建镜像的时候,并不是直接执行Dockerfile中命令,而是将这个文件所在目录的所有文件,都交给docker的守护进程,让docker守护进程来解析之后,再执行。

  上面说的是将Dockerfile所在目录的所有文件,都交给守护进程,至于为什么要这样做,待会再解释。

  但是,如果是初学Dockerfile,建议建立一个空的目录,在空目录中创建一个Dockerfile文件。

 

创建Dockerfile

-> ~ # mkdir TestDockerfile
-> ~ # cd TestDockerfile
-> TestDockerfile # touch Dockerfile
-> TestDockerfile # echo "hello world" > index.html   #创建一个测试文件

  

Dockerfile实例

  下面的Dockerfile会构建出一个安装有nginx和vim的docker镜像

#VERSION 0.0.1

FROM ubuntu:16.04

MAINTAINER ganlixin ubuntu "1355036599@qq.com"

RUN apt-get update && apt-get install -y nginx

RUN apt-get install -y vim

RUN rm -rf /var/www/html/index.html

ADD ./index.html /var/www/html/index.html

WORKDIR /var/www/html

RUN echo "hello docker" > demo.html

WORKDIR /root

RUN echo "hello root" > hey.txt

ENV SELF_DEFINE_ENVIROMENT_VAR "123456789"

RUN echo $SELF_DEFINE_ENVIROMENT_VAR > env_var.html

USER root:root

COPY index.html /tmp/test

CMD /bin/bash

EXPOSE 80

  下面会针对这个Dockerfile中每一项,进行详细的说明。

   

Dockerfile指令

注释

  在Dockerfile中,每一行“#”之后的内容,都会被当成注释。

  一般用来写一些提示信息,比如版本信息,镜像说明

 

FROM

  FROM ubuntu:16.04

  表示使用当前Dockerfile在构建镜像时,是基于哪一个镜像。一般来说,不会从零开始构建镜像,一般都会选择一个已有的镜像作为基础,在上面安装各种软件,然后构建出一个加工过的镜像。

  示例中,使用ubuntu:16.04作为基础

 

MAINTAINER

  MAINTAINER  beyond ubuntu ”1355036599@qq.com"

  用来提示用户,这个Dockerfile的作者、以及作者的联系方式

 

RUN

  RUN apt-get update && apt-get install -y nginx

  RUN用来执行一条Linux命令,执行的时机:在构建镜像的时候。

  不是在使用该镜像创建容器后,运行容器的时候。

  一个Dockerfile文件中可以有多个RUN命令,也就是说,在构建镜像时,可以执行多个指定的命令

 

ADD

  ADD  ./index.html   /var/www/html/index.html

  还记得在创建Dockerfile的时候,创建了一个测试文件吗?他的内容是hello world,文件名是index.html

  这个命令的作用就是将Dockerfile文件所在目录中的某个文件,添加到要构建的镜像中。

  如果将Dockerfile所在的环境叫做外部环境,而构建出的镜像成为内部环境的话,ADD命令的作用就是将外部环境中的文件 添加到 内部环境中。

  注意,目标路径,如果不是以 / 结尾,表示的文件;如果以 / 结尾,表示目录

 

WORKDIR

  设置一个工作目录,后面的RUN命令、CMD命令都会在这个工作目录中执行。

  相当于cd path

WORKDIR /var/www/html
RUN echo "hello docker" > demo.html
WORKDIR /root
RUN echo "hello root" > hey.txt

  上面的代码表示,在/var/www/html目录下的demo.html中输入内容“hello world”;

  然后切换工作目录,在/root目录中,在hey.txt中输入内容,“hello root”

  

ENV

  定义环境变量,相当于全局变量

  ENV SELF_DEFINE_ENVIROMENT_VAR "123456789"

  在镜像中设置一个环境变量,SELF_DEFINE_ENVIROMENT_VAR ,值为123456789

  之后可以使用$SELF_DEFINE_ENVIROMENT_VAR来使用这个变量

 

USER

  指定启动容器后,是以什么身份来运行,可以同时设置组和用户

  USER root:root

  表示启动容器后,是以root组的root身份运行

 

COPY

  COPY命令和ADD命令功能类似,

  COPY index.html /tmp/test

  将外部环境的index.html拷贝到内部环境/tmp目录下,重命名为test。如果是要将index.html拷贝到/tmp/test目录下,即,将test看作是目录,那么,就要在test后面加 / ,即 /tmp/test/

  注意,目标路径,如果不是以 / 结尾,表示的文件;如果以 / 结尾,表示目录

 

CMD

  CMD /bin/bash

  表示在使用镜像,启动容器的时候,会运行的命令。

  和RUN的区别:

  1、RUN是在构建镜像的时候运行,而CMD是在容器启动的时候运行。可以理解为,RUN命令只是在构建时执行一次,而CMD命令在每次启动容器时,都会执行一次。

  2、一个Dockerfile中可以有多个RUN命令,多个RUN命令都会执行;而CMD命令虽然可以出现多次,但是只有最后一个会被执行。

  3、RUN命令只运行一次,所以说不存在命令覆盖的情况,而CMD会出现命令覆盖的情况(即第2点区别),在启动容器时,如果指定了要执行的命令,那么Dockerfile中的CMD命令同样会被覆盖。

 

EXPOSE

  EXPOSE 80,表示将容器的80端口,映射到外部环境(宿主机)的某个端口上。

  可以通过启动容器的时候指定映射到宿主机的哪个端口

 

构建Docker镜像

  使用命令docker build命令即可触发构建操作,但是需要注意,构建时,要指定构建出的镜像名称(使用-t选项)以及tag,以及Dockerfile所在的路径。

  一般构建的时候,都是进入到Dockerfile所在的目录

  假设现在使用前面的Dockerfile构建一个镜像,镜像名为beyond/test,标签为v1,则执行如下命令

-> ~ # cd TestDockerfile
-> TestDockerfile # docker build -t="beyond/test:v1" .
			.......等待
			........
			.......构建完成
-> TestDockerfile # docker run -i -t --name first_test beyond/test
root@38ff683ba587:~#    #进入到容器中

  注意,此时,在运行容器的时候,并没有在后面加上/bin/bash,这是因为Dockerfile中CMD命令已经指定了在启动容器时执行的命令。

  

测试

  现在我们逐个检查Dockerfile中的操作是否成功,即,看对应操作的结果是否保留下来

  1、看/var/www/html/index.html这个文件的内容是不是hello world

  2、看/var/www/html下面是不是有一个demo.html,内容为hello docker

  3、看/root目录下hey.txt的内容是不是hello root

  4、使用env命令,看是不是有SELF_DEFINE_ENVIROMENT_VAR这个环境变量

  5、看/root目录下env_var.html的内容是不是环境变量SELF_DEFINE_ENVIROMENT_VAR的值123456789

  6、看一下/tmp/test文件内容是不是hello world

 

指定宿主机和容器的端口映射

-> TestDockerfile # docker run  -d --name second_test -p 8080:80 beyond/test:v1 nginx -g "daemon off;"
7d74273277cc925ae5656591367c5b3cc6e4b9ed90d251123eeaed42b463367c

  外部访问你的ip:8080,然后就可以看到结果了。

  

  

posted @ 2018-09-21 16:45  寻觅beyond  阅读(2691)  评论(0编辑  收藏  举报
返回顶部