docker学习之常用Dockerfile指令

来源:互联网 发布:模拟退火算法伪代码 编辑:程序博客网 时间:2024/05/29 15:32

今天我们学习几个常用的Dockerfile指令,在 http://docs.docker.com/reference/builder/可以查看Dockerfile中能使用的全部指令的清单。
一、CMD指令
CMD指令用于指定一个容器启动时要运行的命令,这与RUN指令有点类似,但RUN指令是指定镜像被构建时要运行的命令,而CMD指令是指定容器被启动时要运行的命令,这与docker run命令运行容器时指定容器运行程序类似。

CMD ["/bin/bash"]$ docker run -it ubuntu /bin/bash

上述两条指令是等效的,实际上docker run命令是启动容器时才指定运行的指令,而CMD指定的命令在构建镜像时就已经确定,运行基于镜像的容器,CMD指令指定的命令就会运行。
在CMD指令中也可以为要运行的命令指定参数:

CMD ["/bin/bash","-l"] 

docker run命令会覆盖CMD命令,如果我们在Dockerfile里指定了CMD指令,在创建容器的docker run命令中也指定了要运行的命令,这样容器启动后会运行docker run指定的命令,这样看起来CMD指令就被docker run命令覆盖了,另外一个值得注意的地方是:在Dockerfile中只能指定一条CMD命令,如果存在多条,只有最后一条CMD指令会起作用,如果想在容器启动时运行多个程序,可以使用类似Supervisor这样的服务管理工具。
二、ENTRYPOINT指令
ENTRYPOINT指令与CMD指令作用基本相同,二者的区别为:CMD指令会被docker run中指定的命令覆盖,而ENTRYPOINT 指令指定的命令则不会被轻易覆盖,实际上docker run命令中指定的的所有参数都会被当作参数再次传递给ENTRYPOINT指令。

 ENTRYPOINT ["/bin/bash"] ENTRYPOINT ["/bin/bash","-l"]

如果有需要,也可以覆盖ENTRYPOINT指令,可以在docker run命令中指定 –entrypoint标志覆盖ENTRYPOINT指令。
三、WORKDIR指令
WORKDIR指令可以在创建容器时在容器内部指定一个工作目录,ENTRYPOINT和CMD指令指定的程序会在这个目录下执行。

 WORKDIR /opt/webapp/db RUN bundle install WORKDIR /opt/webapp/ ENTRYPOINT ["rackup"]

先将工作目录切换为 /opt/webapp/db执行bundle install命令,然后将工作目录切换为/opt/webapp/,最后用ENTRYPOINT指令设定了启动容器时运行的命令rackup。我们可以通过 -w选项在运行时覆盖工作目录:

 $ docker run -it -w /home/webappp/ ubuntu ls 

将/home/webappp/ 设为工作目录。
四、ENV指令
ENV指令在构建镜像中设置环境变量。
ENV RVM_PATH /home/rvm/
这个环境变量可以在后续RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样:
RUN gem install apache 这个RUN指令会以下面的广式执行:

RVM_PATH=/home/rvm/ gem install apache

我们也可以在其它指令中直接使用环境变量,与shell脚本中使用变量的方法相同:’$变量名’。

 ENV TARGET_DIR /opt/app WORKDIR $TARGET_DIR

ENV指令设置的环境变量也会被注入从镜像中创建的所有容器中。我们也可以在docker run命令中 使用-e选项向容器注入环境变量。
五、USER
USER指令用来指定镜像以哪个用户去运行

USER jix

指定镜像启动的容器以用户jix的身份运行,我们可以在USER指令中指定UID或GID,或二者的组合。

 USER user USER user:group USER uid USER uid:gid USER user:gid USER uid:group

也可以在docker run 命令中通过-u选项指定用户,注意docker run命令指定的用户会覆盖USER指令中设定的用户。如果不指定用户,则默认用户为root。
六、VOLUME
VOLUME指令的作用是向基于镜像创建的容器中添加卷,卷是存在一个或多个容器内的特定的目录,可以提供以下功能:
.卷可以在容器间共享和重用。
.一个容器可以单独拥有一个卷
.对卷的修改是立时生效的
.对卷的修改不会对更新镜像产生影响
.卷会一直存在直到没有任何容器再使用它
通过卷,我们可以将数据、数据库、或者其它内容添加到镜像,而不必将这些内容提交到镜像,而且通过卷我们可以很方便地在多个容器间共享这些内容。下面来看一下VOLUME指令的使用:

 VOLUME ["/opt/project"]

这条指令将会为基于此镜像创建的容器创建一个名为/opt/project的挂载点,我们也可以指定多个挂载点:

 VOLUME ["/opt/project","/data"]

七、ADD指令
ADD指令将构建环境下的文件和目录复制到镜像中。

ADD index.html /opt/application/index.html

上面的指令会将构建目录下的index.html复制到镜像中的/opt/application/index.html,源文件的位置参数可以是一个URL,或者构建上下文或构建环境中的文件或或目录,不能对构建环境目录以外的文件进行操作。 在ADD指令中,docker通过目的地址参数末尾的字符来判断源文件是目录还是文件。如果目的地址以’/’结尾,那么docker就认为源文件为目录,如果目的地址不以’/’结尾,docker就认为源文件是文件。源文件也可以使用网络上的资源:

 ADD http://wordpress.org/latest.zip /root/wordpress.zip

关于ADD指令最后一点要注意是:如果源文件是gzip、bzip2、xz类型的归档文件,docker会自动将其提取、解压。

ADD apache.tar.gz /home/apache/

上面这条命令会将归档文件apache.tar.gz解压到镜像/home/apache/目录下。如果目的地址不存在的话,docker会
自动创建这个路径,并且新创建的文件和目录的权限为755,UID和GID都为0。
八、COPY指令
COPY指令与ADD指令类似,二者的区别是:COPY指令只是复制,不会提取和解压gzip、bzip2、xz类型的归档文件。
总结:
学习了dockerfile中常用的几个命令,dockerfile中可以使用的命令远远不只这些,这些命令最好在实际应用中
学习、体会。

0 0