繁体   English   中英

是否可以“构建”(“编译”)Docker镜像以不需要Docker?

[英]Can Docker images be “built” (“compiled”) to not require Docker?

我在Docker上进行实验和开发的经验非常少,而在登台和部署方面,Docker的经验则为零,因此请原谅任何听起来很幼稚的事情。

主要问题

假设我有一个Docker映像(甚至是由几个映像和服务组成的docker-compose.yml文件),在运行时,它会为我的应用设置环境并运行我的应用-允许在公共开放端口上进行连接并响应要求。

为了在生产环境中运行此映像(并因此在生产环境中运行我的应用程序),生产服务器必须安装了Docker。 这感觉像是违反了十二要素应用程序的设计。 特别是当您考虑端口绑定原则时:

十二要素应用程序完全独立

就像应用程序不应该依赖Apache或nginx来安装一样,应用程序也不应该依赖Docker吗?

这使我想知道是否有办法将Docker运行时和映像“打包”,“构建”或以其他方式“编译”为可执行二进制文件。 可以部署到任何服务器并可以作为单个进程运行的东西,而无需先安装Docker。

现在,可能我只是在考虑这完全错误。 因此,我在下面详细说明了所关注的问题和细节

是什么导致了这个

我有一个以前使用Cloud9开发的Web应用程序项目。 当我将该项目推向生产环境时,我会通过SSH手动登录生产服务器并执行git pullcomposer updatenpm installgulp 我有点麻烦,但对于规模非常小的,我在这方面的工作已经足够了,这是一个很多比通过FTP上传我的所有依赖更好的地狱

但是,我偶尔会遇到外部依赖项带来的挑战。 某些东西在开发中工作正常,然后将其推向生产环境时,我意识到生产服务器具有过时的MySQL版本。 或生产服务器上安装的pngquant版本有错误。 或者服务器上的nginx配置与开发中的nginx配置不完全匹配,并且在路由格式错误的请求时会导致一些边缘情况。

今天,当我尝试在CodeAnywhere而不是Cloud9中加载项目时,所有这些问题一下子解决了。 我必须确保:

  • PHP版本已更新
  • NodeJS已更新
  • NPM已更新
  • cURL已安装
  • 已安装所有必需的PHP扩展
  • 安装了几个GNU库
  • 等等

我花了几个小时试图使此代码运行-这是编写的代码

有所有这些问题使我想起了十二要素应用程序的设计。 因此,我跳到该网站,并做了一些思考来弄清楚我做错了什么。

注意:我不只是单独开发然后直接部署到生产中。 我实际上是在BitBucket中设置了这个项目,我使用票务系统跟踪更改,为每个票证创建了一个分支,并且在合并到master之前在临时环境中检出了分支。 因此,我创建了一个相当强大的系统来管理更改,以避免错误渗入生产环境并允许进行敏捷开发。 但是,在登台生产中签出分支时,它是相同的手动操作: git pullcomposer updatenpm installgulp

我喜欢Docker的什么

在源代码控制的配置文件中定义我的工作环境的能力将消除我的大部分问题。 我再也不需要确保PHP是最新的,确保NodeJS是最新的,确保已安装cURL等。如果Docker映像具有所有依赖项,则在阶段或生产中部署时,它仍将具有那些依赖项。 发展的各个阶段之间的环境的一致性会让我的生活轻松了许多

另外,我还没有玩过任何这种高级功能,但是我想了解到,使用Docker可以很容易地设置自动化部署。 如果我可以单击BitBucket中的一个分支,然后单击“发送到暂存”,然后在一分钟后将其部署并准备进行测试-这样可以每周节省我数小时的时间。 如果我可以类似地将代码合并到母版中时将代码自动部署到生产中,那不仅可以节省我的时间,而且可以避免完成的功能在BitBucket中失效并且永远不会出现在客户面前的风险。

最后,这最终可能是一个有争议的话题,我将了解Docker使绿色/蓝色部署更加容易。 目前,当我对生产进行新更改时,生产服务器会暂时脱机。 通常只持续15到20秒,但一次是一个小时。 在这15到20秒的窗口中,我正在运行composer updatenpm installgulp 前两个命令通常不需要执行任何操作(因为我的依赖关系不会经常更改),并且gulp通常在15秒内完成。 但是,当依赖关系确实发生变化或存在较大问题(例如需要升级MySQL)时,该站点可能会关闭一整小时。 如果我可以缓慢而从容地部署到辅助生产服务器,然后在验证运行正常的情况下以毫秒为单位切换该开关,则这将意味着减少停机时间并带来更多客户满意。

当然,最后一个可能是有争议的,因为我目前没有使用“构建”步骤(十二要素应用程序的另一部分),并且所有这些步骤都应该是“构建”阶段的一部分-而不是“部署”阶段。

我不喜欢Docker的地方

它是又一种学习工具 为了了解和开发我的应用,您已经需要了解:

  • 的PHP
  • 作曲家
  • Symfony
  • 拉拉韦尔
  • 节点JS
  • NPM
  • 古尔普
  • 引导程序
  • VueJS
  • (可能我现在想不出的许多其他事情)

如果将“ Docker”添加到该列表中,则意味着如果我将其交付给其他开发人员,则该项目将很难培训某个人。 我想要更少的依赖关系,而不是更多。

另外,Docker并不是我所知道的任何默认操作系统。 因此,这与cURL不同,尽管从技术上讲它是第三方依赖项,但通常可以期望人们拥有它。 相反,它是一个完整的野兽,必须单独安装。

前一个问题我无法真正解决。 如果我选择使用Docker,则意味着向该应用程序的工具箱中添加了一个工具。 但是,如果可以将Docker映像以某种方式编译为独立的二进制文件,则可以避免后一个问题。

严格来说,您可以从没有docker的docker镜像运行容器。 Docker映像是一种众所周知的格式。 有关此规范的更多详细信息,请参见https://github.com/opencontainers/image-spec OCI映像的运行时有多种实现。 Docker本身实际上并不运行容器,该任务已外包给容器。

但是,映像附带文件系统(也称为一堆tar文件),但是容器也希望使用命名空间来隔离应用程序。 您需要某种运行时来实现这一点。 容器不仅是打包应用程序的一种方法,而且是一种隔离运行它们的方法,尝试将它们拆开将比docker本身做更多的工作,并且需要学习的东西更大。

Docker映像确实确实需要在计算机上安装docker,但这是一个小得多的问题,而要设置您提到的所有其他依赖项。

虽然可能可以创建某种自包含的docker映像,但是它可能不如docker映像那样可移植,因为二进制文件将依赖于os。

还应考虑到,如果您使用云提供商,则它们可以“直接在云上”部署docker映像-也就是说,您不必管理底层服务器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM