Docker图像可以"构建" ("已编译")不需要Docker?

时间:2018-04-29 03:00:45

标签: php laravel docker docker-compose 12factor

我对Docker的实验和开发经验非常少,而且在暂存和部署方面没有使用Docker的经验 - 所以原谅任何听起来很幼稚的东西。

主要问题

假设我有一个Docker镜像(甚至包含多个图像和服务的docker-compose.yml文件),这些文件在运行时会为我的应用程序设置环境并运行我的应用程序 - 允许公开连接端口并响应请求。

为了在生产中运行此映像(因此为了在生产中运行我的应用程序),生产服务器必须安装Docker。这感觉违反The Twelve-Factor App设计。特别是当你考虑Port Binding原则时:

  

十二因素应用是完全独立的

正如应用程序不应该依赖Apache或nginx一样,应用程序是否也不应该依赖Docker来安装?

这让我想知道是否有办法打包"打包",#34; build"或其他"编译" Docker运行时和图像成为可执行的二进制文件。可以部署到任何服务器并作为单个进程运行的东西,而无需先安装Docker。

现在,我可能只是想到这完全错了。出于这个原因,我详细说明了我所关注的问题和问题的具体细节

带来了什么

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

但是,我偶尔会遇到外部依赖性的挑战。有些东西在开发中运行良好,然后当我把它推向生产时,我意识到生产服务器有一个过时的MySQL版本。或者生产服务器上安装的pngquant版本有一个错误。或者服务器上的nginx配置与开发中的nginx配置完全匹配,并且在路由格式错误的请求时会造成一些边缘情况。

今天,当我尝试在CodeAnywhere而非Cloud9中加载项目时,所有这些问题都立即出现了。我必须确保:

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

我花了小时试图让这段代码运行 - 它的代码 写了

所有这些问题让我想起The Twelve-Factor App设计。所以我跳到了网站,并想了解我做错了什么。

注意:我不是单独开发,而是直接部署到生产环境。我实际上在BitBucket中设置了这个项目,我使用票务系统来跟踪更改,为每个票证创建一个分支,并在分组到主服务器之前在分段环境中检出分支。因此,我创建了一个非常强大的系统来管理变更,以避免错误进入生产并允许敏捷开发。但是,当您在暂存 生产时签出分支时,它是相同的手动废话:git pullcomposer update,{ {1}},npm install

我喜欢Docker

在源代码控制的配置文件中定义我的工作环境的能力将消除我的大部分问题。我再也不需要确保PHP是最新的,确保NodeJS是最新的,确保安装了cURL等。如果Docker镜像具有所有依赖关系,那么在部署或生产时它仍将具有这些依赖关系。所有发展阶段之间环境的一致性将使我的生活变得更加轻松

此外,我还没有使用任何这个高级版,但我要理解Docker设置自动部署很容易。如果我可以点击BitBucket中的分支,然后点击"发送到暂存"一分钟后,它已部署并准备测试 - 这将节省我每周的时间。如果我可以同样将代码自动部署到生产中,当它被合并到master时,这不仅可以节省我的时间,而且可以避免在BitBucket中完成功能的风险,并且永远不会在客户面前。

最后,这最终可能是一个没有实际意义的点,我要了解Docker使绿色/蓝色部署 更容易。目前,当我将新的更改推送到生产时,生产服务器会短暂脱机。通常只有15-20秒,但一旦整整一个小时。在这15-20秒的窗口中,我正在运行gulpcomposer updatenpm install。前两个命令通常不需要做任何事情(因为我的依赖关系不经常改变),gulp通常在15秒内完成。但是,当依赖关系 执行 更改或存在更大问题(例如需要升级MySQL)时,该网站可能会停机一整个小时。如果我可以缓慢而平静地部署到辅助生产服务器,那么当我确认它正常工作时,可以在几毫秒内翻转开关,这意味着减少停机时间和更快乐的客户。

当然最后一个可能是一个没有实际意义的点,因为我目前没有使用" build"步骤(12因素应用程序的另一部分),所有这些步骤应该是" build"阶段 - 不是"部署"相。

我不喜欢Docker

还有一个学习工具。为了理解和开发我的应用程序,您需要了解:

  • PHP
  • 作曲
  • Symfony的
  • Laravel
  • 的NodeJS
  • NPM
  • 咕嘟咕嘟
  • 自举
  • VueJS
  • (可能还有很多其他我现在想不到的东西)

添加" Docker"对于那个列表来说,这意味着如果我将这个项目交给另一个开发人员,那么这个项目就会变得更加困难。我希望更少依赖项,而不是更多。

此外,Docker并没有默认使用我所知道的任何操作系统。所以它不像cURL,虽然它在技术上是第三方依赖,但你通常可以期望人们拥有它。相反,它是一个必须单独安装的整个野兽。

前一个问题我无法避免。如果我选择使用Docker,则意味着在我的工具箱中为此应用添加一个工具。但是,如果Docker镜像可以某种方式编译为独立的二进制文件,则可以避免后一个问题。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

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