8、【Docker笔记】使用Dockerfile建立镜像

在前面咱们讲解了基于已有的镜像容器建立和基于本地模板导入两种方式来建立镜像,在这里咱们就来讲说第三种建立镜像的方式。Dockerfile是一个文本格式的配置文件,咱们能够经过Dockerfile快速建立自定义的镜像。html

1、基本结构

Dockerfile是由多行命令语句组成的,而且在文件中支持以 # 开始的注释行。咱们通常将Dockerfile文件分为四部分:基础镜像信息、维护者信息、镜像操做指令和容器启动时执行指令。其中,第一行(不包含注释行)必须指定基于的基础镜像,例如:FROM ubuntu。以后能够是维护者信息,如:MAINTAINER gongziqi 14155830994@qq.com。再日后能够是镜像的操做指令,如:python

RUN echo "deb archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.listnginx

RUN apt-get update && apt-get install -y nginxdocker

RUN echo "\ndaemon off;" >> /etc/nginx/nginx.confshell

最后能够是容器启动时执行指令,如:CMD /usr/sbin/nginx。数据库

# 0. 在ubuntu镜像的基础上,安装inotify-tools/nginx/apache2/openssh-server等,建立新的Nginx镜像
 # Nginx
 # VERSION 1.0
	FROM ubuntu
	MAINTAINER gongziqi 1415583094@qq.com
	RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
 # 1. 在ubuntu镜像基础上,安装firefox/vnc。启动后,用户可经过5900端口经过vnc方式使用firefox
 # FireFox over VNC
 # VERSION 1.0
	FROM ubuntu
	RUN apt-get update && apt-get install -y x11vnc xvfb firefox
	RUN mkdir ./.vnc
	RUN x11vnc -storepasswd 123456 ~/.vnc/passwd
	RUN bash -c 'echo "firefox" >> /.bashrc'
	EXPOSE 5900
	CMD ["x11vnc","-forever","usepw","-create"]
复制代码

2、指令

一、FROM

语法为:FROM 或 FROM :。若在同一个Dockerfile中建立多个镜像,可使用多个FROM即每一个镜像一个。apache

二、MAINTAINER

语法:MAINTAINER ,用来指定维护者信息。ubuntu

三、RUN

语法:RUN 或 RUN ["executable","param1","param2"]。第一个将在shell终端中运行命令,即 /bin/bash -c;第二个则使用 exec 执行。每条RUN指令将在当前镜像基础上执行指定指令,并提交为新的镜像。若命令行太长可使用 \ 来换行书写。vim

四、CMD

支持三种方式:ruby

  • CMD ["executable", "param1", "param2"],使用 exec执行,推荐方式。

  • CMD command param1 param2,在 /bin/sh 中执行,提供给须要交互的应用。

  • CMD ["param1","param2"],提供给 ENTRYPOINT的默认参数。

    指定启动容器时执行的命令,每一个Dockerfile只能由一条 CMD命令。若指定多条,则只有最后一条有效。若在启动容器时,指定了运行的命令,则CMD命令将会被覆盖。

五、EXPOSE

语法:EXPOSE [ ...],如:EXPOSE 22 80 8443,即告诉Docker服务器容器暴露的端口,这些端口可供互联使用。此时在容器启动中,可以使用 -P 来随机指定一个端口,也可以使用 -p 来指定具体的端口映射。

六、ENV

语法:ENV 。指定一个环境变量,会被后面的RUN指令使用,并在容器运行时保持。如:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && ...
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
复制代码

七、ADD

语法:ADD 。将复制指定的src到容器中的desc。其中,src 能够是Dockerfile所在目录的一个相对路径(文件/目录);也可为一个URL;还可为一个tar文件。

八、COPY

语法:COPY 。复制本地主机的src(Dockerfile所在目录的相对路径)到容器中的desc。当目标路径不存在时,将自动建立。当使用本地目录为源目录时,推荐使用COPY,不推荐ADD。

九、ENTRYPOINT

语法:ENTRYPOINT ["executable","param1","param2"] 或 ENTRYPOINT command param1 param2(shell中执行)。配置容器启动后执行的命令,而且不可被docker run 提供的参数覆盖。每一个Dockerfile只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。

十、VOLUME

语法:VOLUME ["/data"]。建立一个能够从本地主机或其余容器挂载的挂载点,通常用来存放数据库和须要保持的数据等。

十一、USER

语法:USER daemon。指定运行容器时的用户名或UID,后续的RUN指令也会使用指定用户。当服务不须要管理员权限时,可经过该命令指定运行用户,而且能够在以前建立所须要的用户。如:RUN groupadd -r postgres && useradd -r -g postgres postgres。若此时须要临时获取管理员权限,则可以使用gosu,不推荐使用sudo。

十二、WORKDIR

语法:WORKDIR /path/to/workdir。为后续的 RUN、CMD、ENTRYPOINT指令配置工做目录。可以使用多个WORKDIR,若后面的WORKDIR指定的是相对路径,则是基于前一个WORKDIR指定的路径。如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
# 结果为:/a/b/c
复制代码

1三、ONBUILD

语法:ONBUILD [INSTRUCTION]。配置当所建立的镜像做为其余新建立镜像的基础镜像时,所执行的操做指令。如:Dockerfile使用以下的内容建立了镜像 image-A。

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
复制代码

若基于image-A建立新的镜像时,新的Dockerfile中使用 FROM image-A指定基础镜像时,会自动执行 ONBUILD 指令内容,即等价于在 FROM指令后添加了以上的两条指令。在使用ONBUILD指令的镜像,咱们推荐在标签中注明,如:ruby:1.9-onbuild。

3、建立镜像

在编写完Dockerfile以后,能够经过 Docker build 命令来建立镜像。语法为:docker build [选项] 路径,即读取指定路径下的Dockerfile,并将该路径下全部内容发送给Docker服务端,由服务端来建立镜像。所以咱们建议放置Dockerfile的目录为空目录。若为非空目录,但愿忽略路径下的某些目录或文件,可经过 .dockerignore文件来配置。

# 指定Dockerfile路径所在路径为 /tmp/docker_builder/,但愿生成镜像标签为 build_repo/first_image, # 在标签命名时须要注意,全部字母必须为小写
$ sudo docker build -t build_repo/first_image /tmp/docker_builder/
复制代码

4、一个实例

根据以上信息,咱们来本身建立一个Nginx镜像。

# 0. 建立Dockerfile所在目录
$ sudo mkdir /opt/tmp_dockerbuilder
 # 1. 建立Dockerfile文件并编写内容
$ sudo vim Dockerfile
 # Nginx
 # VERSION 1.0
	FROM ubuntu
	MAINTAINER gongziqi 1415583094@qq.com
	RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
 # 2. 查看当前本地镜像
$ sudo docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
 # 3. build Dockerfile文件,建立镜像
$ sudo docker build -t nginx/mynginx /opt/tmp_dockerbuilder/Dockerfile
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu
 ---> 4e5021d210f6
Step 2/3 : MAINTAINER gongziqi 1415583094@qq.com
 ---> Running in 8dc5269da475
Removing intermediate container 8dc5269da475
 ---> e27af3f3a447
Step 3/3 : RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
 ---> Running in 2ec0f5b9fc81
 ........
 ........
 ........
Successfully built d27de6c7896d
Successfully tagged nginx/mynginx:latest
 # 4. 再次查看本地镜像
$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
nginx/mynginx        latest              d27de6c7896d        6 minutes ago       275MB
 # 5. 以当前建立的镜像运行容器
$ sudo docker run -ti d27de6c7896d /bin/bash
root@a505965d1b84:/#
 # 6. 查看当前的容器中是否有咱们刚才须要安装的相关软件
root@a505965d1b84:/# find / -name apache2
/etc/cron.daily/apache2
/etc/init.d/apache2
/etc/logrotate.d/apache2
/etc/apache2
/etc/ufw/applications.d/apache2
find: '/proc/1/map_files': Operation not permitted
find: '/proc/12/map_files': Operation not permitted
/usr/lib/apache2
/usr/sbin/apache2
/usr/share/bug/apache2
/usr/share/doc/apache2
/usr/share/lintian/overrides/apache2
/usr/share/apache2
/var/cache/apache2
/var/lib/apache2
/var/log/apache2
 # 7. 查看ubuntu镜像运行的容器中是否有apache2
$ sudo docker run -tid ubuntu /bin/bash
$ sudo docker exec -ti 6df8ff14f57f /bin/bash
root@6df8ff14f57f:/# find / -name apache2
find: '/proc/1/map_files': Operation not permitted
find: '/proc/10/map_files': Operation not permitted
find: '/proc/19/map_files': Operation not permitted
root@6df8ff14f57f:/#
 # 说明:咱们会发现刚才的配置的 apache2 软件已被安装,而基于的 ubuntu镜像自己是没有apache2的
复制代码

image-20200412143000638
相关文章
相关标签/搜索