构建镜像
docker提供了两种方式构建镜像:
- docker commit 通过容器构建
- docker build 通过dockerfile文件构建
1. 通过docker commit 构建
通过Ubuntu镜像构建一个容器,命名为commit_test:
更新并安装nginx,
退出容器并查看,然后提交,使用docker images命令即可看到新创建好的镜像。
以新创建好的镜像运行一个容器,并查看进程:
访问映射的宿主机端口,返回如下内容:
至此,采用commit命令创建镜像成功。
2. 使用Dockerfile构建镜像
- 创建Dockerfile文件
- 使用docker build命令
用例:
** 首先创建一个dockerfile的目录:
** 进入到该目录
** 使用vim命令编辑dockerfile,如果vim命令没有安装,需要先安装vim命令
进入编辑模式后,输入如下内容:
** 保存退出后,通过docker build命令编译:
docker build -t=‘yixian/df_test’ .
点表示在当前目录编译,-t表示给当前镜像取名字。
总共有五行命令,分五个步骤,每次运行完生成一个中间层镜像。最后结果:
根据该镜像生成一个容器,最后访问得到了正确的结果。
Dockerfile的指令格式
包括了注释和指令
# Comment
INSTRUCTION argument
指令名称一般大写,参数小写。
除注释外,非注释第一行必须为FROM
- FROM指令
FROM <image>
FROM <image>[:tag] - MAINTAINER指令
MAINTAINER 指定镜像的作者信息,包含镜像的所有者和联系信息。
MAINTAINER <name> - RUN指令
RUN <command> (shell模式)
comand 一般为 /bin/sh -c command
RUN [“executable”,“param1”,“param2”] (exec模式)
如 RUN["/bin/bash","-c",“echo hello”]
尽量把多行的RUN指令写在一行,用&&连结,这样可以减少中间层镜像。 - EXPOSE
EXPOSE […]
可以指定个或者多个端口,如
EXPOSE 80 28071
虽然在dockerfile中指定了暴露的端口,但在启动容器的run命令中仍然需要使用-p参数映射端口。 - CMD
CMD [“executable”,“param1”,“param2”] (exec模式)
CMD command param1 param2 (shell模式)
CMD [“param1”,“param2”] (作为ENTRYPOINT指令的默认参数]
dockerfile中的run命令是在构建镜像的过程中执行的,而cmd指定是在运行容器中执行的。如果在docker run的后面加了运行的指令,则CMD指令会被覆盖,它只是指定了容器启动时的默认行为。
用例:
进入到之前创建的目录下,编辑dockerfile文件
添加如下CMD指令,保存退出。
根据该dockerfile构建镜像:
根据该镜像运行容器:
可知默认运行了CMD指令。 - ENTRYPOINT
ENTRYPOINT [“executable”,“param1”,“param2”] (exec模式)
ENTRYPOINT command param1 param2 (shell模式)
ENTRYPOINT指令不会被docker run命令中指定的启动命令覆盖。如果需要覆盖ENTRYPOINT指令,则需要指定entrypoint选项:
docker run --entrypoint - ADD和COPY
ADD <src>…<dest>
ADD ["<src>"…"<dest>"] (适用于文件路径中有空格的情况)
COPY <src>…<dest>
COPY ["<src>"…"<dest>"] (适用于文件路径中有空格的情况)
两者的区别:ADD包含类似tar的解压功能,如果单纯复制文件,推荐使用COPY。
如 在上述dockerfile文件中加入:copy index.html /usr/share/nginx/html/
其中index.html与dockerfile在同一目录下。
- VOLUME
VOLUME ["/data"] - WORKDIR
如:WORKDIR /PATH/to/workdir --一般使用绝对路径
从镜像创建一个新容器时,在容器内部设置工作目录。ENTRYPOINT或者CMD指定的命令都会在该目录下执行。 - ENV
用来设置环境变量。
ENV <KEY> <VALUE>
ENV <KEY>= - USER
用以指定镜像以什么样的用户运行。
USER nginx --以nginx的身份进行。 - ONBUILD
为镜像添加触发器。当一个镜像被其他镜像作为基础镜像时执行,会在构建过程中插入指令。(即FROM后面跟的这个镜像)
Dockerfile的构建过程
- 从基础镜像运行一个容器
- 执行一条指令,对容器做出修改
- 执行类似docker commit操作,提交一个中间镜像层
- 再基于刚提交的镜像层运行一个新的容器
- 执行dockerfile中的下一条指令,直至所有指令执行完毕
每执行一条指令都会把生成的容器删掉,但不会删掉中间层镜像,所以我们可以使用中间层镜像进行调试。