Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Docker通过读取Dockerfile中的指令自动生成镜像。通常用法:
1.使用当前目录的 Dockerfile 创建镜像:
docker build -t iom:1 .
2.通过 -f Dockerfile 文件的位置创建镜像:
docker build -t iom:2 -f /usr/docker/Dockerfile .
指令 | 说明 |
---|---|
FROM | 设置构建镜像时使用的基础镜像 |
MAINTAINER | 镜像的创建者 |
RUN | 构建镜像时用于执行后面跟着的命令行命令(在 docker build 时执行) |
CMD | 类似于 RUN 指令,启动容器时用于执行后面跟着的命令行命令(在 docker run 时执行) |
ENTRYPOINT | 启动容器时会将其后面的命令当作参数,结合CMD 指令的命令一起执行 |
COPY | 构建镜像时复制文件或者目录到容器里指定路径 |
ADD | 功能与COPY指令类似,不同点在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令会自动复制并解压到 <目标路径>,在不解压的前提下,无法复制 tar 压缩文件(推荐使用 COPY指令) |
ENV | 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量 |
ARG | 构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量 |
VOLUME | 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷 |
EXPOSE | 声明端口 |
WORKDIR | 指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。 |
USER | 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 |
LABEL | 用来给镜像添加一些元数据(metadata),以键值对的形式 |
ONBUILD | 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令 |
格式:
FROM
FROM :
FROM @
示例: FROM mysql:5.6
注意:必须为第一个命令,tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像。
格式:
MAINTAINER
示例:
MAINTAINER Jack
1.shell 格式:
RUN <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。
示例:RUN yum install wget
2.exec 格式:
RUN ["可执行文件或命令", "参数1", "参数2"]
示例:RUN ["./test.php", "dev", "offline"] # 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
1.shell 格式:
CMD <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。
示例:CMD yum install wget
2.exec 格式:
CMD ["可执行文件或命令", "参数1", "参数2"]
示例:CMD ["./test.php", "dev", "offline"] # 等价于 RUN ./test.php dev offline
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。且CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。如下:
1. 一个Dockerfile 中同时存在下面这两个命令
CMD yum install wget
CMD ["./test.php", "dev", "offline"]
2. 通过传参方式运行容器
docker run php:test -c /etc/php/new.conf
最终只会执行命令 ./test.php -c /etc/php/new.conf
CMD yum install wget 命令不会执行
CMD ["./test.php", "dev", "offline"] 命令中的 "dev", "offline"会被覆盖
ENTRYPOINT ["可执行文件或命令","param1","param2",...]
示例:ENTRYPOINT ["nginx", "-c"]
注意:
1.如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
2.但ENTRYPOINT指令指定的程序不会被 docker run 命令行参数中指定要运行的程序所覆盖。
3.如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。
4.可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。如下:
1.假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
2.不传参运行
docker run nginx:test
容器内会默认运行命令:nginx -c /etc/nginx/nginx.conf 启动主进程
3.传参运行
docker run nginx:test -c /etc/nginx/new.conf
# run语句的参数不会覆盖ENTRYPOINT指令的 "-c"定参,但是会替换掉CMD指令的"/etc/nginx/nginx.conf"变参
最终容器内会默认运行命令:nginx -c /etc/nginx/new.conf 启动主进程
COPY [--chown=:] <源路径1>... <目标路径>
COPY [--chown=:] ["<源路径1>",... "<目标路径>"]
示例:COPY hom* /mydir/ ## 将所有以hom开头的文件复制到 /mydir/目录
注意:
1.[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
2.<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。
3.<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD [--chown=:] <源路径1>... <目标路径>
ADD [--chown=:] ["<源路径1>",... "<目标路径>"]
示例:ADD hom* /mydir/ ## 将所有以hom开头的文件复制到 /mydir/目录
注意:若复制的文件为压缩文件,在没有解压这个文件的前提下时无法复制该文件到指定路径的。
ENV
ENV = =...
示例:设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
ARG <参数名>[=<默认值>]
示例:ARG build_user=www
注意:构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖Dockerfile设置的值。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
EXPOSE <端口1> [<端口2>...]
示例:EXPOSE 80 443
WORKDIR <工作目录路径>
示例:WORKDIR /data (这时工作目录为/data)
USER <用户名>[:<用户组>]
示例:USER user:group
注意:用户和用户组必须提前已经存在
LABEL = = = ...
示例:LABEL version="1.0" description="这是一个Web服务器" by="njh"
ONBUILD <其它指令>
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src