1 Dockerfile(总结)

首先来看下什么是dockerfile:Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。

- 先来看下dockerfile怎么创建镜像?先来介绍它的语法吧。

- FROM  //指定基于哪个基础镜像

> FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM为第一个指令。至于image则可以是任何合理存在的image镜像。  

FROM 一定是首个非注释指令 Dockerfile.  

FROM 可以在一个 Dockerfile中出现多次,以便于创建混合的images。    

如果没有指定 tag,latest将会被指定为要使用的基础镜像版本。

1. 格式 FROM <image> 或者 FROM <image>:<tag> 比如  

FROM centos  

FROM centos:latest

- MAINTAINER //指定镜像制作者的信息

格式 MAINTAIN <name>,比如

MAINTAINER chy chy@chylinux.com

-  RUN  //镜像操作指令

> RUN命令将在当前image中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行Dockerfile中的下一个指令。

层级 RUN 指令和生成提交是符合Docker核心理念的做法。它允许像版本控制那样,在任意一个点,对image 镜像进行定制化构建。

RUN 指令缓存不会在下个命令执行时自动失效。比如 RUN apt-get dist-upgrade -y 的缓存就可能被用于下一个指令. --no-cache 标志可以被用于强制取消缓存使用。     

1. 格式为 RUN <command> 或者 RUN [“executable”, “param1”, “param2”],比如  

RUN yum install httpd  

RUN ["/bin/bash", "-c", "echo hello"]

- CMD  //有三种格式

> Dockerfile.中只能有一个CMD指令。 如果你指定了多个,那么最后个CMD指令是生效的。  

CMD指令的主要作用是提供默认的执行容器。这些默认值可以包括可执行文件,也可以省略可执行文件  

当你使用shell或exec格式时,CMD会自动执行这个命令。

1. CMD ["executable", "param1", "param2"]

2. CMD command param1 param2

3. CMD ["param1", "param2"]

4. RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。比如  

CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c","/usr/local/nginx/conf/nginx.conf"]

- EXPOSE //指令指定在docker允许时指定的端口进行转发。

格式为 EXPOSE <port> [<port>...] , 比如  

EXPOSE 22 80 8443  

> 这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴漏出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。  

- ENV 

> ENV 指令可以用于为docker容器设置环境变量  

ENV设置的环境变量,可以使用 docker  inspect命令来查看。同时还可以使用docker run --env <key>=<value>来修改环境变量

1. 格式 ENV <key> <value>, 比如   

ENV PATH /usr/local/mysql/bin:$PATH    

它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量如下:   

ENV MYSQL_version 5.6  

- ADD //ADD 将文件从路径 <src> 复制添加到容器内部路径 <dest>。

><src> 必须是相对于源文件夹的一个文件或目录,也可以是一个远程的url。<dest> 是目标容器中的绝对路径。

所有的新文件和文件夹都会创建UID 和 GID。事实上如果 <src> 是一个远程文件URL,那么目标文件的权限将会是600。

1. 格式 add <src> <dest>  将本地的一个文件或目录拷贝到容器的某个目录里。 其中src为Dockerfile所在目录的相对路径,它也可以是一个url。比如    

ADD <conf/vhosts> </usr/local/nginx/conf>

- COPY //COPY 将文件从路径 <src> 复制添加到容器内部路径 <dest>

1. 格式同add (使用方法和add一样,不同的是,它不支持url

- ENTRYPOINT //是指定 Docker image 运行成 instance (也就是 Docker container) 时,要执行的命令或者文件。  

注意:

1. 容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条有效。和CMD不同是:

2. CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。比如,容器名字为aming

我们在Dockerfile中指定如下CMD:

CMD ["/bin/echo","test"]  

启动容器的命令是 docker run aming 这样会输出 test 

假如启动容器的命令是 docker run -it chy /bin/bash 什么都不会输出  

ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行ENTRYPOINT ["echo", "test"]

docker run -it aming 123

则会输出 test 123 ,这相当于要执行命令 echo test 123

- VOLUME //创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。  

格式  VOLUME ["/data"] ( 创建一个可以从本地主机或其他容器挂载的挂载点)

- USER //USER 用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险。  

格式 USER daemon    

指定运行容器的用户

- WORKDIR 

> WORKDIR 用来切换工作目录的。Docker 默认的工作目录是/,只有 RUN 能执行 cd 命令切换目录,而且还只作用在当下下的 RUN,也就是说每一个 RUN 都是独立进行的。如果想让其他指令在指定的目录下执行,就得靠 WORKDIR。WORKDIR 动作的目录改变是持久的,不用每个指令前都使用一次 WORKDIR

1. 格式 WORKDIR /path/to/workdir   

为后续的RUN、CMD或者ENTRYPOINT指定工作目录


2 Dockerfile示例(安装nginx总结)

如上我们介绍了dockerfile的语法与格式,接下来我们就试试实际的操作是怎样的吧以nginx为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@chy ~]# vim Dockerfile 
 //创建一个Dockerfile
## Set the base image to CentOS
FROM centos //基于centos的镜像
# File Author / Maintainer
MAINTAINER chy chy@chylinux.com //作者的信息
# Install necessary tools
RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel //用run安装一下依赖的包
# Install Nginx
ADD http://nginx.org/download/nginx-1.8.0.tar.gz . //安装nginx的源码包
RUN tar zxvf nginx-1.8.0.tar.gz
RUN mkdir -p /usr/local/nginx //创建一个目录
RUN cd nginx-1.8.0 && ./configure --prefix=/usr/local/nginx && make && make install 
RUN rm -fv  /usr/local/nginx/conf/nginx.conf
ADD http://www.apelearn.com/study_v2/.nginx_conf  /usr/local/nginx/conf/nginx.conf //将配置文件下载到/usr/local/nginx/conf/nginx.conf下去
# Expose ports
EXPOSE 80
# Set the default command to execute when creating a new container
ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd //这里需要注意下如果不加tail -f /etc/passwd 这个当执行完第一个命令之后就会容器就会停止,当加了后面的tail -f后就执行不完这个容器一直执行着
[root@chy ~]# docker build -t centos7_1 . //创建镜像 -t用来指定新的容器的名称
[root@chy ~]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
centos7_1                     latest              89cc1360adab        28 seconds ago      347MB
<none>                        <none>              8c39f4925009        About an hour ago   569MB
发现有新创建的镜像
[root@chy ~]# docker run -itd -p 81:80 centos7_1 bash //运行新的容器
1101ab2618a483fffb8902952f82331361c8ca82db8132c6ef362642bf27a204
[root@chy ~]# docker exec -it 1101ab261  bash
[root@1101ab2618a4 /]# ps aux |grep nginx
root          1  0.1  0.0  11640  1336 pts/0    Ss+  23:35   0:00 /bin/sh -c /usr/local/nginx/sbin/nginx && tail -f /etc/passwd bash
root          6  0.0  0.0  24840   792 ?        Ss   23:35   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody        8  0.0  0.2  27284  3376 ?        S    23:35   0:00 nginx: worker process
nobody        9  0.0  0.2  27284  3376 ?        S    23:35   0:00 nginx: worker process
root         23  0.0  0.0   9048   660 pts/1    S+   23:36   0:00 grep --color=auto nginx

希望看过的童鞋多多指教,谢谢!j_0063.gifj_0063.gif