######################################################################################
文章中有错或者其他问题请联系小弟:[email protected]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
为什么要使用Dockerfile
Dockerfile 能搭建出一抹一样的环境来,而且操作方便,简单,环境一致
注:base images需统一, 可以从灵鹊云,数字云,阿里云中直接pull。直接在官方dockerhub中pull实在是太慢了,还经常失败
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dockerfile 语法如下,跟我们熟悉的shell一样,是顺序向下执行的。
Dockerfile 执行与注意点
docker build . docker build -t centos:7 . docker build -t centos:7 -t centos:latest . docker build -f /path/docker/file/Dockerfile .
tips:
1. 整个build过程是由Docker daemon 控制的,并非CLI 2. Dockerfile 尽量别放到node的 ‘/‘ 目录下,否则会将整个根目录全部send到docker daemon 3. Docker build 过程中每一行是独立的(有点类似Makefile),所如果前面定义RUN cd /tmp ,后面定义 RUN touch file ,这个file一定不会在/tmp下面
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Environment replacement
Dockerfile 中的变量是有ENV定义。变量比较有意思,有好多中写法,大家研究一下看:
1. $foo , ${foo} 3. \$foo ,\${foo} 4. ${fool_name} ,$fool_name, ${fool}_cont 5. ${variable:-word} , 如果$variable 没有设置,那么传递的值就是word 6. ${variable:+word} ,如果$variable 已经设置,那么传递的值就是word
并非所有的Dockerfile指令都能support ENV ,我们看看有哪些能够support:
ADD,COPY,ENV,EXPOSE,LABEL,USER,WORKDIR,VOLUME,STOPSIGNAL
目前就只有这么多了
注:在Dockerfile同一行中ENV环境变量是保持不替换的,什么意思呢?我们看个例子就很清楚了。
ENV abc=hello ENV abc=bye def=$abc ENV ghi=$abc
结果 def=hello, ghi=bye,
因为在第二个ENV中,abc变量虽然是有被重新赋值,但是因为跟def赋值是在同一行,所以了结果就是依然是上一行的值,是不是很有趣:)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#Comment
#INSTRUCTION arguments
FROM <images:tag> ex: FROM centos:6.6
如果没有对应的images,那么会直接从公共的dockerhub中pull(当然直接dockerhub的server就是另外一回事了)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MAINTANER <name>
ex: MAINTAINER GuiQiu<[email protected]>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RUN <command>
两种模式,一种是shell模式,这种模式等于说是/bin/sh -c command这样执行
ex: RUN echo "$NAME is my friend" RUN yum install -y mysql python RUN /bin/bash -c ‘source $HOME/.bashrc ; echo $HOME‘
另一种模式,exec模式 ,因为这种模式将option当作JSON array来parser的,所以一定是要使用双引号的。
RUN ["executable", "param1", "param2"] ex: RUN ["/bin/bash", "-c", "echo hello"] RUN [ "echo", "$HOME" ]
在exec模式中,如果有变量,那么在parser的时候,是不传值的,要记得。
tips:在测试阶段,Dockerfile一直频繁的修改,所以我们在build的时候,有时候不希望使用上一版或上几版的cache,可以使用下面的命令避免(个人感觉还蛮有作用的)
docker build --no-cache
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CMD ["executable","param1","param2"] (exec form, this is the preferred form) CMD ["param1","param2"] (as default parameters to ENTRYPOINT) CMD command param1 param2 (shell form)
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred) ENTRYPOINT command param1 param2 (shell form)
用此option可以避免使用Dockerfile中定义的ENTRYPOINT值:--entrypoint=flag
tips:
1. 如果CMD 是给ENTRYPOINT 提供参数的话,那么必须使用JSON格式,也就是必须要双引号(不是单引号)
2. ENTRYPOINT CMD 区别是 ENTRYPOINT的指令不会被user指定的命令overwrite,而是当作参数使用;CMD定义的指令会直接被overwrite
3. CMD RUN 的区别,RUN指令会在build过程中指令且commit,然而CMD 却只是定义到images中,不会在build的过程中执行,只是在container启动的时候执行
4. 当container别当成一个执行档来用的时候,比较难建议使用ENTRYPOINT + CMD 执行一些参数
5. Dockerfile 必须定义ENTRYPOINT CMD其中之一
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ADD/COPY ADD <src>... <dest> ADD ["<src>",... "<dest>"] COPY <src>... <dest> COPY ["<src>",... "<dest>"]
tips:
1. ADD / COPY 都是复制的作用,但是ADD 可以直接复制url而COPY则需要先download下来然后才能复制,当然如果url中有需要密码认证的话,还是必须通过其他的方式来先得到内容才能复制
2. src的路径必须包含在Dockerfile所在的路径下
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
USER daemon
以什么user来运行此container
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
WORKDIR path
container 开启之后default路径
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[[email protected] dockerfile]# cat Dockerfile FROM centos:test MAINTAINER GUIQIU<[email protected]> ENV FILENAME DOCKERFILE ENV MYNAME=zhangsan YOURNAME=lisi RUN yum install -y xclock RUN yum install -y openssh-server openssh-clients RUN ["mkdir", "-p" ,"/d/test"] RUN useradd zhangsan ADD README /root/ COPY README /d/test WORKDIR /d USER zhangsan CMD /bin/bash
[[email protected] dockerfile]# cat Dockerfile1 FROM centos:test MAINTAINER GUIQIU<[email protected]> ENV FILENAME DOCKERFILE ENV MYNAME=zhangsan YOURNAME=lisi RUN yum install -y xclock RUN yum install -y perl \ openssh-server openssh-clients RUN ["mkdir", "-p" ,"/d/test"] ADD README /root/ COPY README /d/test WORKDIR /d CMD /bin/bash
[[email protected] dockerfile]# cat Dockerfile2 FROM centos:test MAINTAINER GUIQIU<[email protected]> ENV FILENAME DOCKERFILE ENV MYNAME=zhangsan YOURNAME=lisi RUN yum install -y xclock RUN yum install -y perl \ openssh-server openssh-clients RUN ["mkdir", "-p" ,"/d/test"] ADD README /root/ COPY README /d/test WORKDIR /d ENTRYPOINT ["/bin/bash"]
[[email protected] dockerfile]# cat Dockerfile3 FROM centos:test MAINTAINER GUIQIU<[email protected]> ENV FILENAME DOCKERFILE ENV MYNAME=zhangsan YOURNAME=lisi RUN yum install -y xclock RUN yum install -y perl \ openssh-server openssh-clients RUN ["mkdir", "-p" ,"/d/test"] ADD README /root/ COPY README /d/test WORKDIR /d ENTRYPOINT ["/usr/bin/echo","ThisIsTest"]