【docker系列】使用Dockerfile构建镜像

举报
字母哥哥 发表于 2022/05/22 23:07:20 2022/05/22
【摘要】 在《【docker系列】逐行解析Nginx镜像Dockerfile(学习经典)》文章中我们已经将Dokcerfile的核心指令做了详尽的说明解释,本文我们就学习使用Dockerfile构建镜像,以及对Do...

《【docker系列】逐行解析Nginx镜像Dockerfile(学习经典)》文章中我们已经将Dokcerfile的核心指令做了详尽的说明解释,本文我们就学习使用Dockerfile构建镜像,以及对Dockerfile的使用做一些补充说明。

一、使用Dockerfile构建镜像

使用docker build指令构建镜像如下所示:

docker build  -t <镜像名称>:<标签或版本号>  /path/to/a/Dockerfile

  
 
  • 1
  • -t− 给镜像指定名称并且添加一个标签或版本号
  • /path/to/a/Dockerfile Dockerfile所在的路径

我们写一个最简单的Dockerfile用来做实验

from ubuntu
CMD echo "hello world from zimug"

  
 
  • 1
  • 2

把Dockerfile放入一个目录,并在该目录下执行下面的构建命令。命令行最后的一个点表示当前路径。

docker build  -t helloworld:1.0  .

  
 
  • 1

构建过程分为2步,因为我们只写了2个指令。

通过docker images查看构建完成的镜像

# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
helloworld   1.0       a4c0e3f907ee   2 minutes ago   72.8MB

  
 
  • 1
  • 2
  • 3

运行docker run从镜像启动一个容器,可以看到echo命令生效,终端显示“hello world from zimug”

二、 .dockerignore 文件

细心的读者可能会看到,上文中在执行构建命令docker build的时候出现了下面的这一行日志。这是因为在执行镜像构建的时候,会将Dockerfile所在路径的文件发给Docker daemon,也就是说这个目录下的所有文件全部提交给Docker daemon,如果这个路径下文件比较多就会很耗时。

Sending build context to Docker daemon  1.864GB

  
 
  • 1

当然我们在构建镜像的时候,尽量保证Dockerfile所在路径不存在镜像构建无关的文件。除此之外,还有一种方式就是写一个.dockerignore文件,将与构建镜像无关的文件全都写道这个文件里面。如:

*.log
*.md
data
logs

  
 
  • 1
  • 2
  • 3
  • 4

这样在执行构建命令的时候,无关的文件就不会被发往Docker daemon,构建过程也更加快速。

Sending build context to Docker daemon  83.95MB

  
 
  • 1

三、用户切换USER

对于绝大多数软件,使用ROOT用户启动是不够安全的,甚至有些软件服务根本就不允许使用root用户启动。所以我们需要一个在容器内切换用户的指令,他就是USER。比如:

RUN groupadd -r redis && useradd -r -g redis redis
USER redis

  
 
  • 1
  • 2

需要说明的是USER只能切换用户,前提是该用户已经存在。如果不存在,我们可以像上文一样先用RUN指令+shell命令去创建。

四、VOLUME指令(不建议使用)

Dockerfile还有另外一个指令,我没有为大家介绍过,从我个人的经验来看不建议使用它。

VOLUME ["/data1","/data2"]

  
 
  • 1

比如上面的VOLUME会在容器启动时,将容器内的"/data1","/data2"路径映射到宿主机本地目录,映射关系可能是

容器内路径 宿主机路径
“/data1” /var/lib/docker/volumes/一长串随机字符串/_data
“/data1” /var/lib/docker/volumes/一长串随机字符串/_data

当我们容器被销毁后这个路径仍然存在,会造成垃圾数据。如果确实需要Volume数据卷可以使用docker run -v显示指定,或者使用后面文章中会为大家介绍的docker volume来命名创建数据卷。

五、ADD与COPY的区别(不建议使用ADD)

在我之前的文章中已经介绍COPY指令的作用是将执行镜像构建的本地文件或目录src拷贝到宿主机的文件目录dest中去。还有一个和COPY指令非常相似的指令就是ADD指令,语法和COPY几乎一致,但是功能比COPY更加强大。

COPY <src> <dest>
ADD  <src> <dest>

  
 
  • 1
  • 2

那么ADD比COPY强大在那些地方呢?

  • ADD支撑从URL下载文件并添加文件到镜像中,也就是上文中的src可以是URL路径。
  • ADD指令,如果源文件是压缩文件,会自动解压到镜像文件中去。

虽然ADD比COPY功能更强大,但是不建议使用。特别在使用压缩包时它会使构建缓存失效,也会带来一些令人迷惑的问题。如果确实需要解压缩压缩包,使用RUN指令加上shell脚本的解压命令行进行压缩包解压即可。

六、哪些指令会产生镜像分层

在镜像构建过程中,需要向镜像写入数据的时候会产生分层,一个写操作命令产生一个分层。 那么哪些指令可能产生“写入操作”呢?

一定会产生写入数据操作的是下面的三个指令

  • FROM
  • ADD
  • COPY

有可能产生写入数据操作的指令是下面三个,是否产生写操作取决于其脚本执行过程是否有磁盘写操作

  • RUN
  • CMD
  • ENTRYPOINT

文章来源: zimug.blog.csdn.net,作者:字母哥哥,版权归原作者所有,如需转载,请联系作者。

原文链接:zimug.blog.csdn.net/article/details/124906253

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。