目录
- 一、什么是dockerfile
- 二、基本语法和结构
- 三、参数指令说明
- 3.1. FROM (小写 from)
- 3.2. MAINTAINER (小写 maintainer)
- 3.3. RUN (小写 run)
- 3.4. CMD (小写 cmd)
- 3.5. LABEL (小写 label)
- 3.6. EXPOSE (小写 expose)
- 3.7. ENV (小写 env)
- 3.8. ADD (小写 add)
- 3.9. COPY (小写 copy)
- 3.10. ENTRYPOINT (小写 entrypoint)
- 3.11. VOLUME (小写volume)
- 3.12. USER (小写 user)
- 3.13. WORKDIR (小写 workdir)
- 3.14. ARG (小写 arg)
- 3.15. ONBUILD (小写 onbuild)
- 3.16. STOPSIGNAL (小写 stopsignal)
- 3.17. HEALTHCHECK (小写 healthcheck)
- 3.18. SHELL (小写 shell)
- 四、创建镜像
- 五、Dockerfile实战文件
一、什么是dockerfile
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile自定义快速创建属于自己的镜像,Dockerfile是通过很多的参数指令编写的文件,通过docker build 命令来创建镜像
二、基本语法和结构
Dockerfile由一行行的命令语句组成,并且支持以#号注释
一般情况,Dockerfile分为四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动执行的指令
其中,一开始必须指定所基于的镜像信息名称,接下来一般是说明的维护者信息,后面则是镜像的操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令,每运行一条RUN指令,镜像就会添加新的一层,并提交,最后是CMD指令,用来指定运行容器时操作的指令
三、参数指令说明
指令 | 说明 |
FROM | 指定创建镜像的基础镜像 |
MAINTAINER | 指定维护者信息 |
RUN | 运行命令 |
CMD | 指定启动容器时默认执行的命令 |
LABEL | 指定生成镜像的元数据标签信息 |
EXPOSE | 声明镜像内服务所监听的端口 |
ENV | 指定环境变量 |
ADD | 复制指定的<src>路径下的内容到容器中的<dest>下,<src>可以为URL,如果是tar文件,会自动解压到<dest>路径下 |
COPY | 复制本地主机的<src>路径下的内容到镜像中的<dest>路径下,一般情况下这个常用 |
ENTRYPOINT | 指定镜像的默认入口 |
VOLUME | 创建数据卷挂载点 |
USER | 指定运行容器的用户名或者UID |
WORKDIR | 配置工作目录 |
ARG | 指定镜像内使用的参数(例如版本号等信息) |
ONBUILD | 配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作命令 |
STOPSIGNAL | 容器退出的信号值 |
HEALTHCHECK | 如何进行健康检查 |
SHELL | 指定使用shell时默认shell类型 |
3.1. FROM (小写 from)
1
2
3
4
5
6
7
8
9
10
|
指定所创建的镜像的基础镜像,如果不存在,会去DockerHub去下载 格式: FROM<image> 或者 FROM<image>:<tag> 或者 FROM<image>@<digest> 任何Dockerfile中的第一条指令必须为FROM指令,并且如果在同一个Dockerfile中创建多个镜像,可以使用多个FROM指令(每个镜像各一条) |
3.2. MAINTAINER (小写 maintainer)
1
2
3
4
5
6
|
指定维护者信息 格式: MAINTAINER<name> 该信息会写入到生成镜像的Author属性域中 |
例如:
1
|
MAINTAINER zhujingzhi@126.com |
3.3. RUN (小写 run)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
运行指令命令 格式: RUN< command > 或者 RUN [ "executable" , "paraml" , "param2" ] 注意后一个指令会被解析为JSON的数组,因此必须要用双引号 前者默认将在shell终端中运行命令,即 /bin/sh -c 后者则是用 exec 执行,不会启动shell环境 指定使用其他的终端类型可以用第二种方式,例如 RUN [ "/bin/sh" , "-c" , "echo aaaa" ] 每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像,命令长的时候可以使用 来换行 |
例如:
1
2
3
|
RUN yum update && yum -y install net-tools openssh openssl && rm -rf /var/log/a .log |
3.4. CMD (小写 cmd)
1
2
3
4
5
6
7
8
|
CMD 指令用来指定启动容器时默认执行的命令,有三种格式: 1、CMD [ "executable" , "param1" , "param2" ] 使用 exec 执行,推荐使用 2、CMD command param1 parma2 在 /bin/sh 中执行,提供给要交互的应用 3、CMD [ "parma1" , "parma2" ] 提供给ENTRYPOINT 的默认参数 每个Dockerfile只有一条CMD命令,如果指定了多条命令,只有最后一条会执行,如果启动容器时手动指定了运行的命令(作为run的参数),会把CMD命令给覆盖 |
3.5. LABEL (小写 label)
1
2
3
4
|
LABEL 指令是用来指定生成镜像的元数据标签 格式: LABEL <key>=<value> <key>=<value> <key>=<value> ....... |
例如:
1
2
|
LABEL version= "1.0" LABEL description= "Zhu Jingzhi's mirror image" |
3.6. EXPOSE (小写 expose)
1
2
3
4
5
6
7
|
EXPOSE 声明镜像内服务监听的端口 格式: EXPOSE <port> [<port>......] 注意,该指定是声明的作用,不会自动的完成端口的映射 在启动容器的时候需要使用-P 或 -p 来自动分配一个临时端口或者指定具体的端口来做映射 |
例如:
1
|
EXPOSE 22 443 80 |
3.7. ENV (小写 env)
1
2
3
4
5
6
7
8
9
10
|
ENV 指定环境变量,在镜像生成的过程中会被后续的RUN 使用,在镜像启动的容器中也会存在 格式: ENV<key><value> 或者 ENV<key>=<value>....... 注意在 指令指定的环境变量在运行时可以被覆盖掉 如: docker run -- env <key>=<value> centos |
例如:
1
2
3
|
ENV PY_VERSION 3.6.1 RUN curl -sSL http: //python .org /ftp/python/3 .6.1 /Python- $PY_VERSION. tar .xz | tar -xJC /usr/src/python ENV PATH /usr/src/python =$PY_VERSION /bin :$PATH |
3.8. ADD (小写 add)
1
2
3
4
5
6
7
8
9
10
11
12
|
该命令将复制指定的<src>路径下的内容到容器中的<dest>路径下 格式: ADD <src> <dest> 其中<src>可以是Dockerfile所在目录的一个相对路径(文件或者目录),也可以是URL,还可以是个 tar 文件(如果是 tar 文件,会自动解压到<dest>路径下),<dest>可以是镜像内的绝对路径,或者相对于工作目录的相对路径 路径支持正则格式 例如: ADD *. tar /code/ tar 压缩包用这个还是很方便的 |
3.9. COPY (小写 copy)
1
2
3
4
5
6
7
|
COPY 复制本地主机的<src>(为Dockerfile所在目录的相对路径、文件或者目录)下的内容到镜像中的<dest>目录下,目录不存在会自动创建 格式: COPY <src> <dest> 路径同样支持正则 当使用本地目录为源目录的时候,非常推荐使用户CMD |
例如:
1
|
COPY /opt/data/ /opt/ |
3.10. ENTRYPOINT (小写 entrypoint)
1
2
3
4
5
6
7
8
9
10
11
|
ENTRYPOINT 指定镜像的默认入口,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数 格式: ENTRYPOINT [ "executable" , "param1" , "param2" ] 或者 ENTRYPOINT command param1 param2 此时,CMD指令指定的值将作为根命令的参数 每个Dockerfile 中只能有一个ENTRYPOINT 当指定多个的时候,只有最后一个生效 在运行时,可以被--entrypoint参数覆盖 |
3.11. VOLUME (小写volume)
1
2
3
4
5
6
|
VOLUME 创建一个挂载点 格式: VOLUME [ "/data" ] 可以从本地主机或者其他容器挂载数据卷,一般用来存放数据库和需要保存的数据 |
3.12. USER (小写 user)
1
2
3
4
5
6
7
8
|
USER 指定运行容器时的用户名或UID ,后续的RUN指令也是使用指定的用户 格式: USER daemon 当服务不需要管理员权限的时候,可以使用该命令指定运行用户,并且可以在之前创建所需要的用户 要临时获取管理员权限可以是用 sudo |
例如:
1
|
RUN groupadd -r nginx && useradd -r -g nginx nginx |
3.13. WORKDIR (小写 workdir)
1
2
3
4
5
6
|
WORKDIR 为后续的RUN CMD ENTRYPOINT 指令配置工作目录 格式: WORKDIR /path/to/workdir 可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前的命令指定路径 |
例如:
1
2
3
4
5
|
WORKDIR /a WORKDIR b WORKDIR c 最终的路径是 /a/b/c |
3.14. ARG (小写 arg)
1
2
3
4
5
6
|
ARG 指定一些镜像内使用的参数(例如版本信息) 格式: ARG<name>=[=<default value>] 也可以用docker build --build-arg<name>=<value>来进行指定参数值 |
3.15. ONBUILD (小写 onbuild)
1
2
3
4
|
ONBUILD 配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令 格式: ONBUILD [INSTRYCTION] |
例如创建一个镜像A:
1
2
3
4
|
[......] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build -- dir /app/src [......] |
如果基于镜像A创建新的镜像,新的Dockerfile中使用FROM 镜像A指定基础镜像,会自动执行镜像A中的ONBUILD指令的内容,等价在后面添加了两条指令
1
2
3
4
5
|
FROM 镜像A # 等价于: ADD . /app/src RUN /usr/local/bin/python-build -- dir /app/src |
3.16. STOPSIGNAL (小写 stopsignal)
1
2
3
4
|
STOPSIGNAL 指定所创建的镜像启动的容器接收的退出的信号值 例如: STOPSIGNAL signal |
3.17. HEALTHCHECK (小写 healthcheck)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
HEALTHCHECK 配置所启动容器如何进行健康检查,Docker1.12 才开始支持 两种格式: 1、HEALTHCHECK [OPTIONS] CMD command # 根据所执行命令的返回值是否为0来判断 OPTIONS支持的参数: --interval=DURATION(默认30s) :过多久检查一次 --timeout=DURATION(默认30s) : 每次检查的超时时间 --retries=N(默认为:3) : 如果失败了重试的次数 2、HEALTHCHECK NONE # 禁止基础镜像的中的健康检查 |
3.18. SHELL (小写 shell)
1
2
3
4
5
6
|
SHELL 指定其他命令使用shell时默认shell类型 格式: SHELL [ "executable" , "parameters" ] 默认值为[ "/bin/sh" , "-c" ] |
四、创建镜像
创建完dockerfile文件后 可以使用docker build 命令来创建镜像
基本的格式:
docker build [选项] Dockerfile路径
该命令会读取指定路径下(包括子目录)的Dockerfile,并将该路径下的所有的内容发给docker服务端,由服务端来创建镜像,因此建议除非生成镜像需要,否则一般吧Dockerfile放到一个空的目录中
两点经验:
- 如果使用非内容路径下的Dockerfile,可以通过 -f 参数来指定路径
- 要指定生成镜像的标签信息,可以使用 -t 参数
例如:
1
2
3
4
5
6
7
|
指定Dockerfile所在的路径为 /opt/docker_builder ,并且希望生成镜像的标签为build_repo /image [root@nfs133 ~] # docker build -t zhujingzhi/nginx1.8.1 /root/docker_builder/ 如果是在Dockerfile的目录下执行就是 [root@nfs133 ~] # docker build -t zhujingzhi/nginx1.8.1 . # 一定要加.呦 |
五、Dockerfile实战文件
说了一堆的每个参数的语法格式,下面来做个实战的dockerfile文件,来生成一个镜像,并使用这个镜像创建个容器,并运行起来,我们来使用nginx服务来做实战
5.1. 下载基础镜像
1
2
3
4
5
6
7
|
[root@rsync131 ~] # docker pull centos Using default tag: latest Trying to pull repository docker.io /library/centos ... latest: Pulling from docker.io /library/centos 256b176beaff: Pull complete Digest: sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf Status: Downloaded newer image for docker.io /centos :latest |
5.2. 编写Dockerfile文件
1
2
3
4
5
6
|
# 创建存储Dockerfile文件的目录 [root@rsync131 ~] # mkdir docker_builder [root@rsync131 ~] # cd /root/docker_builder/ # 下载需要的包 [root@rsync131 docker_builder] # wget http://nginx.org/download/nginx-1.8.1.tar.gz [root@rsync131 docker_builder] # wget http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm |
编写Dockerfile文件
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
35
36
37
|
[root@rsync131 ~] # cd /root/docker_builder/ [root@rsync131 docker_builder] # vim Dockerfile # This my first nginx Dockerfile # Version 1.0 # Base images 基础镜像 FROM centos #MAINTAINER 维护者信息 MAINTAINER zhujingzhi #ENV 设置环境变量 ENV PATH /usr/local/nginx/sbin :$PATH #ADD 文件放在当前目录下,拷过去会自动解压 ADD nginx-1.8.1. tar .gz /usr/local/ ADD epel-release-7-11.noarch.rpm /usr/local/ #RUN 执行以下命令 RUN rpm -ivh /usr/local/epel-release-7-11 .noarch.rpm RUN yum install -y wget lftp gcc gcc -c++ make openssl-devel pcre-devel pcre && yum clean all RUN useradd -s /sbin/nologin -M nginx #WORKDIR 相当于cd WORKDIR /usr/local/nginx-1 .8.1 RUN . /configure --prefix= /usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-pcre && make && make install RUN ln -s /usr/local/nginx/sbin/ * /usr/local/sbin/ #EXPOSE 映射端口 EXPOSE 80 #CMD 运行以下命令 CMD [ "nginx" , "-g" , "daemon off;" ] |
5.3. 构建镜像并启动容器
构建镜像
1
2
3
4
|
[root@rsync131 docker_builder] # cd /root/docker_builder/ [root@rsync131 docker_builder] # docker build -t zhujingzhi/nginx1.8.1 . 过程就不粘贴了 因为太多了 大家执行自己看一下吧,会有Dockerfile的每一步的执行详细信息 |
查看
1
2
3
4
5
6
7
8
|
[root@rsync131 docker_builder] # docker images REPOSITORY TAG IMAGE ID CREATED SIZE zhujingzhi /nginx1 .8.1 latest 236535a1cdd2 About a minute ago 350 MB docker.io /registry latest 2e2f252f3c88 12 days ago 33.3 MB docker.io /centos latest 5182e96772bf 6 weeks ago 200 MB 已经构建好了镜像 |
启动容器
1
2
3
4
5
|
[root@rsync131 docker_builder] # docker run -itd --name nginx1 -p 80:80 236535a1cdd2 8e23f4f849a33515c27e0bad92ff29442b7b2822be30dc235f30bf200d663f64 [root@rsync131 docker_builder] # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e23f4f849a3 236535a1cdd2 "nginx -g 'daemon ..." 2 seconds ago Up 2 seconds 0.0.0.0:80->80 /tcp nginx1 |
5.4. 访问测试
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
|
[root@rsync131 docker_builder] # curl 127.0.0.1 <!DOCTYPE html> <html> < head > <title>Welcome to nginx!< /title > <style> body { 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } < /style > < /head > <body> <h1>Welcome to nginx!< /h1 > <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.< /p > <p>For online documentation and support please refer to <a href= "http://nginx.org/" >nginx.org< /a >.<br/> Commercial support is available at <a href= "http://nginx.com/" >nginx.com< /a >.< /p > <p><em>Thank you for using nginx.< /em >< /p > < /body > < /html > |