Dockerfile详解

1.什么是Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Docker通过读取Dockerfile中的指令自动生成镜像。通常用法:

1.使用当前目录的 Dockerfile 创建镜像:
  docker build -t iom:1 .
2.通过 -f Dockerfile 文件的位置创建镜像:
  docker build -t iom:2 -f /usr/docker/Dockerfile .
2.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 指定的命令
3.常用指令用法
  1. FROM指令:
格式:
  FROM 
  FROM :
  FROM @
示例: FROM mysql:5.6

注意:必须为第一个命令,tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像。

  1. MAINTAINER 指令:
格式:
    MAINTAINER 
示例:
    MAINTAINER Jack
  1. RUN 指令:
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. CMD 指令:
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"会被覆盖
  1. ENTRYPOINT 指令:
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 启动主进程
  1. COPY 指令:
COPY [--chown=:] <源路径1>...  <目标路径>
COPY [--chown=:] ["<源路径1>",...  "<目标路径>"]
示例:COPY hom* /mydir/   ## 将所有以hom开头的文件复制到 /mydir/目录

注意:
1.[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
2.<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。
3.<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

  1. ADD 指令:
ADD [--chown=:] <源路径1>...  <目标路径>
ADD [--chown=:] ["<源路径1>",...  "<目标路径>"]
示例:ADD hom* /mydir/   ## 将所有以hom开头的文件复制到 /mydir/目录

注意:若复制的文件为压缩文件,在没有解压这个文件的前提下时无法复制该文件到指定路径的。

  1. ENV 指令:
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"
  1. ARG 指令:
ARG <参数名>[=<默认值>]
示例:ARG build_user=www

注意:构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖Dockerfile设置的值。

  1. VOLUME 指令:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
  1. EXPOSE 指令:
EXPOSE <端口1> [<端口2>...]
示例:EXPOSE 80 443
  1. WORKDIR 指令:
WORKDIR <工作目录路径>
示例:WORKDIR /data  (这时工作目录为/data)
  1. USER 指令:
USER <用户名>[:<用户组>]
示例:USER user:group

注意:用户和用户组必须提前已经存在

  1. LABEL 指令:
LABEL = = = ...
示例:LABEL version="1.0" description="这是一个Web服务器" by="njh"
  1. ONBUILD 指令:
ONBUILD <其它指令>
示例: 
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src

你可能感兴趣的:(docker,docker)