当前位置 博文首页 > 山间漫步人生路的博客:Dockerfile到底是个啥
Dockerfile是一个Docker镜像的描述文件,Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
#基于centos镜像
FROM centos
#维护人的信息
MAINTAINER The CentOS Project <qq@qq.com>
#安装httpd软件包
RUN yum -y update
RUN yum -y install httpd
#开启80端口
EXPOSE 80
#复制网站首页文件至镜像中web站点下
ADD index.html /var/www/html/index.html
#复制该脚本至镜像中,并修改其权限
ADD run.sh /run.sh
RUN chmod 775 /run.sh
#当启动容器时执行的脚本文件
CMD ["/run.sh"]
由上可知,Dockerfile结构大致分为四个部分:
(1)基础镜像信息
(2)维护者信息
(3)镜像操作指令
(4)容器启动时执行指令。
Dockerfile每行支持一条指令,每条指令可带多个参数,支持使用以#号开头的注释。
指令 | 含义 |
---|---|
FROM镜像 | 指定新镜像所基于的镜像,必须为第一条指令 |
MAINTAINER 名字 | 新镜像的维护人信息 |
RUN 命令 | 在所基于的镜像上执行命令,并提交到新镜像中 |
EXPOSE端口号 | 指定新镜像加载到Docker时开启的端口号 |
ENV 环境变量 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ADD 源文件/目录 目标文件/目录 | 将源文件复制到目标文件,源文件要与Dockerfile位于同一目录下,或者为一个URL |
COPY 源文件/目录 目标文件/目录 | 将本地主机上的源文件/目录复制到目标地点,源文件/目录要与Dockerfile在同一目录下 |
VOLUME[“目录”] | 在容器中创建一个挂载点 |
USER 用户名 /UID | 指定运行容器时的用户 |
WORKDIR 路径 | 为后续的RUN、CMD、ENTRYPOINT指定工作目录 |
ONBUILD命令 | 指定所生成的镜像作为一个基础镜像时所要运行的命令 |
CMD[“要运行的程序”,“参数1”,“参数2”] | 指定启动容器时运行的命令或脚本,只能有一条CMD命令,多条时只有最后一条被执行 |
FROM 指令
FROM busybox:latest
MAINTAINER
用于让dockerfile制作者提供本人的详细信息
dockerfile 并不限制MAINTAINER 指令可在出现的位置,但推荐将其放置于FROM指令之后
例如
MAINTAINER email <qq@qq.com>
COPY
用于从docker 主机复制新文件或者目录至创建的新镜像指定路径中
例如
如果是复制目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制;需要把复制目录名字也写在容器中要复制的路径下!
COPY coalminehwaui /usr/local/tomcat/webapps/coalminehwaui/
ADD
ADD 指令类似于COPY指令,ADD支持使用TAR文件和URL路径
ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/
或者先下载到本地
ADD nginx-1.15.8.tar.gz /usr/local/src/
WORKDIR
用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录
在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径; 另外,WORKDIR也可调用由ENV指定定义的变量;
WORKDIR /usr/local/
ADD nginx-1.15.8.tar.gz ./src/
VOLUME
用于在image中创建一个挂载点目录,以挂载Docker host.上的卷或其它容器上的卷
VOLUME /data/mysql
EXPOSE
用于为容器打开指定要监听的端口以实现与外部通信
用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
EXPOSE指令可一次指定多个端口,例如:EXPOSE 11211/udp 11211/tcp
ENV
设置环境内环境变量
用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用
调用格式为$variable_ name 或 ${variable_ name}
ENV <key> <value> 或
ENV <key>=<value> . .
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME=/usr/local/jdk1.8.0_45
RUN
用于指定docker build过程中运行的程序,其可以是任何命令
第一种格式中,通常是一个shell命令, 且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop 命令停止容器时,此进程接收不到SIGTERM信号;
第二种语法格式中的参数是一个JSON格式的数组,其中为要运行的命令,后面的 为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式。
RUN ["/bin/bash", “-c”, “”, “”]
RUN <command> 或
RUN ["<executable>", "<param1>", "<param2>"]
CMD
类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同
RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时
CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
CMD <command> 或
CMD [“<executable>",“<param1>","<param2>"] 或
CMD ["<param1>","<param2>"]
前两种语法格式的意义同RUN
第三种则用于为ENTRYPOINT指令提供默认参数
json数组中,要使用双引号,单引号会出错
ENTRYPOINT
类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序
不过,docker run命令的 --entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
ENTR YPOINT <command>
ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效
ARG
ARG指令类似ENV,定义了一个变量;区别于ENV:用户可以在构建时docker build --build-arg <varname> = <value>
进行对变量的修改;ENV不可以;
如果用户指定了未在Dockerfile中定义的构建参数,那么构建输出警告。
ARG <name>[= <default value>]
例如
FROM java:8
ARG JAR_FILE
VOLUME /tmp
COPY ${JAR_FILE} app.jar
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone #设置时区
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
docker build --build-arg JAR_FILE=task-flow-server-1.0-SNAPSHOT.jar -t test:latest
Dockerfile可以包含一个或多个ARG指令