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 <image>
  FROM <image>:<tag>
  FROM <image>@<digest>
示例: FROM mysql:5.6

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

  1. MAINTAINER 指令:
格式:
    MAINTAINER <name>
示例:
    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=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
示例:COPY hom* /mydir/   ## 将所有以hom开头的文件复制到 /mydir/目录

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

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

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

  1. ENV 指令:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
示例:设置 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 <key>=<value> <key>=<value> <key>=<value> ...
示例: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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值