侧边栏壁纸
  • 累计撰写 47 篇文章
  • 累计收到 0 条评论

Dockerfile 与 Docker-Compose 的区别

2022-12-30 / 0 评论 / 168 阅读
温馨提示:
本文最后更新于 2022-12-30,已超过半年没有更新,若内容或图片失效,请留言反馈。

先简单理解 Docker 的使用过程,它分为镜像构建容器启动

  • 镜像构建 即创建一个镜像,它包含安装运行所需的环境程序代码等。这个创建过程就是使用 Dockerfile 来完成的。
  • 容器启动 容器最终运行起来是通过拉取构建好的镜像,通过一系列运行指令(如端口映射外部数据挂载环境变量等)来启动服务的。针对单个容器,这可以通过 docker run 来运行。

而如果涉及多个容器的运行(如服务编排)就可以通过 docker-compose 来实现,它可以轻松的将多个容器作为 service 来运行(当然也可仅运行其中的某个),并且提供了 scale (服务扩容) 的功能。

  • dockerfile - 构建镜像
  • docker run - 启动容器
  • docker-compose - 启动服务

我们从头梳理下。

假如你不用 docker, 搭建个 wordpress 项目应该怎么弄? 大概是这样的: 首先应该是找台服务器, 假设其 OS 是 CentOS, 然后按照文档一步步敲命令, 写配置。

docker 呢?大概是这样的: 找台服务器,不管什么操作系统,只要支持 docker 就行, 执行命令 docker run centos, docker 会从官方源里拉取最新的 CentOS 镜像,可以认为你开了个 CentOS 虚拟机,然后一步步安装,跟上面一样。

但是你发现没有? 这样安装有个显著的缺点,一旦 container 被删,你做的工作就都没了。当然可以用 docker commit 来保存成镜像,这样就可以复用了。
但是镜像一般比较大,而且只分享镜像的话,别人也不知道你这镜像到底包含什么,这些问题都不利于分享复用

一个直观的解决方案就是,写个脚本把安装过程全部记录下来,这样再次安装的时候,执行脚本就行了。 Dockerfile 就是这样的脚本,它记录了一个镜像的制作过程。

有了 Dockerfile, 只要执行 docker build . 就能制作镜像,而且 Dockerfile 就是文本文件,修改也很方便。

现在有了 wordpress 的镜像,只需要 docker run 就把 wordpress 启动起来了。

如果仅仅是 wordpress, 这也就够了。但是很多时候,需要多个镜像合作才能启动一个服务,比如前端要有 Nginx ,数据库 Mysql, 邮件服务等,当然你可以把所有这些都弄到一个镜像里去,但这样做就无法复用了。

更常见的是, nginx, mysql, smtp 都分别是个镜像,然后这些镜像合作,共同服务一个项目。
docker-compose 就是解决这个问题的。你的项目需要哪些镜像,每个镜像怎么配置,要挂载哪些 volume 等信息都包含在 docker-compose.yml 里。
要启动服务,只需要 docker-compose up 就行,停止也只需要 docker-compose stop/down

简而言之, Dockerfile 记录单个镜像的构建过程。 docker-compose.yml 记录一个项目(project, 一般是多个镜像)的构建过程。

有些教程用了 dockerfile + docker-compose, 是因为 docker-compose.yml 本身没有镜像构建的信息,如果镜像是从 docker registry 拉取下来的,那么 Dockerfile 就不需要了; 如果镜像是需要 build 的,那就需要提供 Dockerfile


docker-compose编排容器 的。例如, 你有一个php镜像,一个mysql镜像,一个nginx镜像。如果没有docker-compose,那么每次启动的时候,你需要敲各个容器的启动参数环境变量容器命名,指定不同容器的链接参数等一系列的操作,相当繁琐。而用了docker-compose之后,你就可以把这些命令一次性写在docker-composer.yml文件中,以后每次启动这一整个环境(含3个容器)的时候,你只要敲一个docker-composer up命令就ok了。

Dockerfile 的作用是 从无到有的构建镜像Dockerfile - 为 docker build 命令准备的,用于建立一个独立的 image 。在 docker-compose 里也可以用来实时 build docker-compose.yml - 为 docker-compose 准备的脚本,可以同时管理多个 container, 包括他们之间的关系、用官方 image 还是自己 build、各种网络端口定义、储存空间定义等。

评论一下?

OωO
取消