######################################################################################

文章中有错或者其他问题请联系小弟:guiqiu_2010@163.com

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

为什么要使用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<guiqiu_2010@162.com>

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


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路径

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[root@guiqiu-virtualbox dockerfile]# cat Dockerfile
FROM  centos:test

MAINTAINER GUIQIU<guiqiu_2010@163.com>

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
[root@guiqiu-virtualbox dockerfile]# cat Dockerfile1
FROM  centos:test

MAINTAINER GUIQIU<guiqiu_2010@163.com>

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
[root@guiqiu-virtualbox dockerfile]# cat Dockerfile2
FROM  centos:test

MAINTAINER GUIQIU<guiqiu_2010@163.com>

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"]
[root@guiqiu-virtualbox dockerfile]# cat Dockerfile3
FROM  centos:test

MAINTAINER GUIQIU<guiqiu_2010@163.com>

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"]