Docker学习2 - Dockerfile

容器的构建方式

1. 通过容器构建镜像

通过容器构建是将部署好的容器,使用docker commit命令将该容器打包成一个镜像

docker commit 容器名 镜像名:版本
#版本不填默认为latest

优点:
1. 交互性好
缺点:
1. 每次做更改都需要再次commit来构建
2. 无法查看容器的构建历史:做过哪些更改

2. Dockerfile构建镜像

Dockerfile 是一个文件,里面记录了镜像构建的步骤,它有自己的语法规则。

编写Dockerfile
一个Dockerfile的示例如下所示:

#基于centos镜像
FROM centos

#维护人的信息
MAINTAINER The CentOS Project <303323496@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每行支持一条指令,每条指令可带多个参数,支持使用以#号开头的注释。下面会对上面使用到的一些常用指令做一些介绍。
  
构建
有了Dockerfile 我们就可以构建镜像了

docker build -t 镜像名:版本号 .
# .表示当前目录(docker会自动查找该目录下的Dockerfile文件
3. 命令解释

FROM: 表示基于什么基础镜像进行构建
MAINTAINER:构建者信息,说明是谁构建的
WORKDIR:指定后续执行步骤的工作目录,比如拷贝文件,创建文件操作在哪个目录下执行
RUN:构建镜像时运行的Shell命令,比如创建文件 touch xxx.txt
COPY:拷贝数据,即将主机上的文件拷贝到容器中去
ADD:也是拷贝数据,不同的是如果拷贝文件是压缩文件,那么拷贝到容器中会自动解压
ENV:指定环境变量,该变量可以在Dockerfile文件中使用,同时也能在容器中生效
CMD:启动容器时执行的Shell命令
ENTRPRINT:同CMD相似,稍有区别

更多详情可参考:你必须知道的Dockerfile

RUN, CMD,ENTRYPOINT的区别

  1. RUN指令是在构建镜像时执行的指令。通常会用来安装软件,操作文件夹等。CDMENTRPRINT是在启动容器时执行的指令。
  2. CMDENTRPRINT的相同点是:都是执行shell指令,但当出现多条CMDENTRPRINT指令时,仅有最后一个会生效。
  3. CMDENTRPRINT的不同点是:CMD指令或被容器启动时run后面指定的参数替代,而ENTRPRINT不会被替代

CMDENTRYPOINT的区别决定了二者使用上的不同:
4. 由于CMD命令会被docker run 的命令替换,因此它可用来设置默认启动命令,如果用户不想使用默认命令,就可以在docker run指令中指定自己的容器的启动命令
5. ENTRYPOINT是必须执行的命令,所以往往用来启动应用程序或者服务,设置容器启动命令的最好方式是使用ENTRYPOINT命令,不要使用CMD

4. CMD和ENTRPRINT命令格式

CMD命令的3种格式:

  1. Exec格式
    格式: CMD [“命令”,“参数1”,“参数2”,…]
CMD ["echo","hello","world"]
  1. Shell格式
    格式: CMD 命令 参数1 参数2 …
CMD echo "hello" "world"
  1. 为ENTRPRINT提供参数
ENTRPRINT ["echo","I","am"]
CMD ["entrprint1"]
# I am entrprint1

ENTRPRINT同样支持第一和第二种格式。除此之外,RUN同样适用这两种格式

Exec和Shell两种格式的区别:
主要区别在于:Shell 格式底层会调用/bin/sh -c,而Exec不会。
比如:

ENV VERSION "1.0.2"
ENTRPRINT echo "hello,$VERSION"
# hello,1.0.2
ENV VERSION "1.0.2"
ENTRPRINT ["/bin/echo", "hello,$VERSION"]
# hello,$VERSION

可见Exec格式下的变量并没有被替换,需要改成

ENV VERSION "1.0.2"
ENTRPRINT ["/bin/sh""-c","echo hello,$VERSION"]
# hello,1.0.2

可见Exec底层不会调用/bin/sh -c,需要自己补齐。

对于两种格式,推荐使用exec格式,因为可读性好,容易理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值