制作镜像有两种形式,一种是使用Dockerfile来制作,一种是使用容器来制作,详情可以掺靠之前的文章制作docker镜像-容器.
原则上来说,我们制作一个镜像应该是面向application的,而不是面向配置的,所以让我们想要配置一个容器的环境的时候,应该首选Dockerfile, 因为由一个基础镜像来制作容器环境的镜像成本太高,更重要的一点,使用了Dockerfile,万物皆code,我们的github, CI CD全就可以上了~~哈哈。
Dockerfile is nothing but the source code for building Docker images.
graph TD
A(Dockerfile)-->B(image)
Dockerfile在制作过程中,所有相关的文件都需要在一个文件夹中,这个文件夹叫做工作目录,Dockerfile所在的目录及其子目录。
mkdir /tmp/image1
cd /tmp/image1
除了注释行外,Dockerfile的第一个命令。
Syntax:
FROM [:]
FROM @
repository:指定base image的名称
tag: 指定base image的标签
digest:image的hashcode
已经废弃的命令,用于提供Dockerfile制作者的信息,这个命令可以出现在任何位置,一般建议在FROM指令之后。
Syntax:
MAINTAINER
例如:
MAINTAINER "leveldc"*
替代了MAINTAINER,用key value的形式来描述一个image的metadata。
Syntax:
LABLE =
例如:
LABLE maintainer="leveldc"
用于从宿主机复制文件到镜像文件。
Syntax:
COPY ...
COPY ["",...""]
src: 复制文件的源文件或目录,支持通配符
dist: 目标路径
说明:
1. 必须是build的上下文中的路径,不能是其父目录的文件。
2. 如果是目录,其内部文件及子目录会被递归复制,本身不会被复制。
3. 如果指定了多个或在中使用了通配符,则必须是一个目录,且以/结束。
4. 如果不存在,会被自动创建,包括其父目录。
例如:
COPY index.html /data/web/html
类似COPY命令, 支持TAR文件或者TAR.gz和URL路径。
TAR:拷贝本地的tar文件会自动解压缩到docker镜像中。
URL:拷贝服务器地址上的文件并将文件添加到docker 镜像中。
Syntax:
ADD ...
ADD ["",...""]
src: 添加文件的源文件或目录,支持通配符
dist: 目标路径
说明:
1. 如果为URL且不以/结尾则指定的文件将被直接下载并创建为;如果以/结尾,则文件被拷贝至/
2. 如果是本地tar文件,则被展开为一个目录,如果是一个URL的tar文件,则不会自动展开。
3. 如果有多个,则dist需要以/结尾,否则将会把src的内容直接写进。
例如:
ADD http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gz /usr/local/src/
ADD apache-tomcat-8.5.37.tar.gz /usr/local/src/
指定Docker镜像中的工作路径,可以定义多次,命令执行的时候以最新定义的一次为准。
例如:
WORKDIR /usr/local/
Dockerfile中的卷只能设置容器中的挂载点目录,只能设置docker管理的卷。
例如:
`VOLUME /data/mysql`
为容器打开指定要监听的端口来和外部通信。
Syntax:
EXPOSE [/][[ ]]
protocol:传输协议,tcp/udp, 默认tcp.
可以一次指定多个端口,例如:
`EXPOSE 32332/udp 32332/tcp`
这里的端口并不会直接暴露给宿主机,而是以启动docker容器时候的参数来决定。
docker run -p/-P
定义Dockerfile的环境变量,可以被在Dockfile ENV命令后面的其他命令引用。
Syntax:
ENV
ENV = ...
说明:
1.第一种格式key后面的所有内容都被认为是value,只可以定义一个
2.第二种格式可以定义多个=, 如果value中有空格,需要加"\"进行转义,也可以对value加双引号。另外反斜杠可以用来表示续行。
建议使用第二种。
3.Dockerfile中定义的ENV可以在启动容器以后直接使用,在运行为容器的时候通过-e参数可以重新给变量赋值。要分清什么参数是在build阶段的,什么是在容器启动阶段。
RUN命令时基于基础镜像所提供的命令来运行,发生在创建镜像的过程中。目的是为了创建镜像。
RUN 命令如果执行了yum,需要在安装完成后删除缓存以减小镜像大小。
Syntax:
RUN
RUN ["","",""]
说明:
第一种默认启动为/bin/sh 子进程。
第二种执行方式是由linux直接来执行,没有/bin/sh,所以不支持shell的语法,如果需要可以使用:
RUN ["/bin/bash","-c","",""]来执行。
例如:
RUN cd /usr/local/src/ && \
tar -xf ${WEB_SERVER_VERSION}
CMD命令发生在容器启动时,当一个镜像文件被创建为容器的时候执行,一个容器默认只启动一个进程,所以一个Dockerfile中只可以有一个CMD,如果有多个,则最后一个生效用来指定容器启动时默认执行的程。
Syntax:
CMD
CMD ["","",""]
CMD ["",""]
说明:
在执行docker run命令的时候,可以指定新的命来来覆盖CMD的内容。如果docker在启动的时候不希望接受命令行输入的命令,可以使用ENTRYPOINT.
和CMD功能类似,但是不接受在docker run的时候修改启动命令,docker run的参数只能以变量的形式传给ENTRYPOINT定义的启动程序。
如果需要改变,需要在docker run的时候指定 --entrypoints参数。
ENTRYPOINT用来支持多环境
用于指定运行image或运行Dockerfile中的RUN CMD ENTRYPOINT指令指定的程序时的用户名或者UID。
Syntax:
USER |
CMD ["","",""]
CMD ["",""]
容器健康检测
Syntax:
HEALTHCHECK [OPTIONS] CMD command
OPTIONS:
--interval=DURATION(间隔多久检测)
--timeout=DURATION(检测超时)
--start-period=DURATION(等待多久开始检测,default=0)
--retries=N(default=3)
returns:
0:success
1:unhealthy
2:reserved
例如:
HEALTHCHECK --interval=5m --timeout=30s CMD curl -f http://localhost/ || exit 1
镜像默认的shell
Syntax:
SHELL ["executable","parameters"]
进程为1的命令可以接受docker stop命令,主进程停止,容器就停止。
在build的过程中起作用,使一个dockerfile可以适用多个环境,用法和ENV类似,但是起作用的时间不一样。该变量可以通过 build --arg参数修改。
在Dockerfile中定义一个并发器,当别的镜像是基于有ONBUILD的镜像构建新的镜像的时候,会触发ONBOUILD指令
Syntax
ONBUILD
创建docker镜像
docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
OPTIONS: 参考docker build --help
PATH: Dockerfiles所在的文件目录
URL:
例如:
docker build ./ -t leveldc/busybox:index
# this is a test image
FROM busybox:latest
MAINTAINER "leveldc"
ENV DOC_ROOT="/data/web/html/" \
WEB_SERVER_VERSION="apache-tomcat-8.5.37.tar.gz"
# LABEL maintainer="leveldc"
#COPY index.html /data/web/html/
COPY index.html ${DOC_ROOT}
COPY yum.repos.d /etc/yum.repos.d/
ADD http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.37/bin/${WEB_SERVER_VERSION} /usr/local/src/
# ADD apache-tomcat-8.5.37.tar.gz /usr/local/src/
#WORKDIR /usr/lcoal/
#ADD apache-tomcat-8.5.37.tar.gz ./src/
#ADD ${WEB_SERVER_VERSION} ./src/
#VOLUME /data/mysql
EXPOSE 80/tcp
RUN cd /usr/local/src/ && \
tar -xf ${WEB_SERVER_VERSION}
FROM nginx:1.14-alpine
LABEL maintainer="leveldc"
ENV NGX_DOC_ROOT="/data/web/html/"
ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
HEALTHCHECK --start-period=2s CMD wget -O -q http://${IP:-0.0.0.0}:${PORT:-80}/
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
FROM busybox
LABEL maintainer="leveldc"
ENV DOCKER_ROOT="/data/web/html/"
RUN mkdir -p ${DOCKER_ROOT} && \
echo "hello world" > ${DOCKER_ROOT}index.html
# CMD /bin/httpd -f -h ${DOCKER_ROOT}
ENTRYPOINT /bin/httpd -f -h ${DOCKER_ROOT}
~~完