【发布时间】:2018-04-29 03:00:45
【问题描述】:
我在 Docker 方面的实验和开发经验非常少,在 Docker 暂存和部署方面的经验为零 - 所以请原谅任何听起来幼稚的事情。
主要问题
假设我有一个 Docker 映像(甚至是一个由多个映像和服务组成的 docker-compose.yml 文件),它在运行时为我的应用程序设置环境并运行我的应用程序 - 允许在公共开放端口上进行连接,并且响应请求。
为了在生产环境中运行这个镜像(因此为了在生产环境中运行我的应用程序),生产服务器必须安装 Docker。这感觉像是违反The Twelve-Factor App 设计。特别是当您考虑Port Binding 的信条时:
十二要素应用完全独立
就像一个应用不应该依赖 Apache 或 nginx 来安装一样,一个应用也应该不依赖 Docker 来安装吗?
这让我想知道是否有办法将 Docker 运行时和映像“打包”、“构建”或以其他方式“编译”成可执行二进制文件。可以部署到任何服务器并作为单个进程运行而无需先安装 Docker。
现在,我可能只是想完全错误。出于这个原因,我在下面详细说明了我遇到的顾虑和问题
是什么造成的
我有一个以前使用 Cloud9 开发的 Web 应用程序项目。当我将此项目推送到生产环境时,我通过 SSH 手动登录到生产服务器并执行git pull、composer update、npm install 和gulp。我有点麻烦,但是对于我正在从事的非常小规模的工作来说已经足够了,而且它地狱要好得多而不是通过 FTP 上传我的所有依赖项。
不过,我偶尔会遇到外部依赖项的挑战。有些东西在开发中运行良好,然后当我将它推送到生产环境时,我意识到生产服务器有一个过时的 MySQL 版本。或者生产服务器上安装的 pngquant 版本有 bug。或者服务器上的 nginx 配置与开发中的 nginx 配置不完全匹配,并且在路由格式错误的请求时会导致一些边缘情况。
今天,当我尝试在 CodeAnywhere 而不是 Cloud9 中加载我的项目时,所有这些问题都立即出现了。我必须确保:
- PHP 版本已更新
- NodeJS 已更新
- NPM 已更新
- cURL 已安装
- 已安装所有必需的 PHP 扩展
- 安装了几个 GNU 库
- 等
我花了 小时 试图让这段代码运行 - 它是 我 编写的代码
所有这些问题让我想起了The Twelve-Factor App 设计。所以我跳到网站上,想了想弄清楚我做错了什么。
注意:我不只是单独开发,然后直接部署到生产环境。我实际上在 BitBucket 中设置了这个项目,我使用票务系统来跟踪更改,为每个票创建一个分支,并在合并到 master 之前在暂存环境中签出分支。因此,我创建了一个非常强大的系统来管理更改,以避免错误进入生产环境并允许敏捷开发。然而,当谈到在暂存或生产中检查一个分支时,它是相同的手动废话:git pull、composer update、npm install、gulp。
我喜欢 Docker 的原因
在源代码控制的配置文件中定义我的工作环境的能力将消除我的大部分问题。我再也不需要确保 PHP 是最新的、确保 NodeJS 是最新的、确保安装了 cURL 等。如果 Docker 映像具有所有依赖项,那么在部署到暂存或生产时它仍然具有这些依赖项.所有发展阶段之间的环境一致性将使我的生活很多更轻松。
另外,我还没有玩过这么高级的任何东西,但我知道使用 Docker 很容易设置自动部署。如果我可以单击 BitBucket 中的一个分支,然后单击“发送到暂存”,一分钟后将其部署并准备好进行测试——这将每周为我节省数小时的时间。如果我可以类似地在将代码合并到 master 时将代码自动部署到生产中,那不仅可以节省我的时间,而且可以避免完成的功能在 BitBucket 中停滞不前并且永远不会出现在客户面前的风险。
最后,这可能最终成为一个有争议的问题,我理解 Docker 使绿色/蓝色部署大大更容易。目前,当我将新更改推送到生产环境时,生产服务器会短暂脱机。通常只持续 15-20 秒,但一次是整整一个小时。在这 15-20 秒的窗口中,我正在运行 composer update、npm install 和 gulp。前两个命令通常不需要做任何事情(因为我的依赖项不经常更改),gulp 通常在 15 秒内完成。但是,当依赖关系确实发生变化或出现较大问题(例如需要升级 MySQL)时,站点可能会宕机一小时。如果我可以缓慢而平静地部署到辅助生产服务器,然后在我验证它工作正常时在几毫秒内切换开关,这将意味着更少的停机时间和更多的客户满意度。
当然,最后一个可能有争议,因为我目前没有使用“构建”步骤(十二要素应用程序的另一部分),所有这些步骤都应该是“构建”阶段的一部分-- 不是“部署”阶段。
我不喜欢 Docker 的地方
它是又一种学习工具。为了理解和开发我的应用,您需要了解:
- PHP
- 作曲家
- Symfony
- Laravel
- NodeJS
- NPM
- 吞咽
- 引导程序
- VueJS
- (可能还有很多我现在想不出来的事情)
将“Docker”添加到该列表仅意味着如果我将这个项目交给另一个开发人员,那么培训某人会变得更加困难。我想要更少依赖,而不是更多。
此外,我所知道的任何操作系统都没有默认 Docker。因此,它不像 cURL,虽然它在技术上是第三方依赖项,但您通常可以期望人们拥有它。相反,它是一个必须单独安装的整体野兽。
前一个问题我无法真正规避。如果我选择使用 Docker,这意味着在我的工具箱中为这个应用程序添加了一个工具。但是,如果 Docker 映像可以以某种方式编译为独立的二进制文件,则可以避免后一个问题。
【问题讨论】:
-
我认为不可能将 docker 图像转换为二进制文件,但在某些时候它必须依赖 apache 或 nginx 才能提供内容,否则有什么意义。顺便说一句,它很容易学习
-
其实web应用不需要需要依赖Apache或者nginx来提供内容。 Apache 和 nginx 所做的只是解析 HTTP 请求并自动为您处理一些错误情况。如果您的应用能够解释 HTTP 请求,那么您的应用可以充当自己的 HTTP 服务器(直接绑定到端口 80)。这就是 NodeJS Web 应用程序的工作量。然后将 Apache 和 nginx 用作负载均衡等的代理层。
标签: php laravel docker docker-compose 12factor