Deployment Script vs. Rultor

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

当我解释Rultor如何自动化部署/发布流程时,经常会听到这样的说法:

这个回应非常常见,所以我决定在一篇文章中总结我对自动化Rultor部署/发布流程的三个主要论点:1)隔离的docker容器,2)日志的可见性,3)凭证的安全性。

阅读这些内容,看看Rultor为您的现有部署脚本提供了什么。

在我们开始论证之前,让我强调一下,Rultor是一个有用的界面,可以用于您的自定义脚本。当您决定使用Rultor自动化部署时,并不会抛弃您现有的任何脚本。您只需要教会Rultor如何调用它们。

一旦你开始从Rultor调用部署脚本,你将获得的第一个优势是使用Docker。我相信你知道Docker是什么,但是对于那些不知道的人来说,它是一个虚拟Linux“机器”的管理工具。它是一个命令行脚本,当你需要在一个新的虚拟机(也称为“容器”)中运行一些脚本时,你会调用它。Docker几乎立即启动容器并运行你的脚本。Docker的美妙之处在于每个容器都是一个完全隔离的Linux环境,拥有自己的文件系统、内存、进程等。

当你告诉Rultor运行你的部署脚本时,它会启动一个新的Docker容器并在其中运行你的脚本。但是你可能会问,这给我带来了什么好处?

主要的好处是在你的脚本运行完毕后容器就被销毁了。这意味着你可以在容器内部进行所有的预配置,而不用担心与你的主要工作平台发生冲突。让我举个例子。

我在MacBook上开发,在那里我安装和删除我需要用于开发的软件包。与此同时,我有一个项目需要部署,需要PHP 5.3、MySQL 5.6、Phing、PHPUnit、PHPCS和xdebug。每个MacOS版本都需要特别配置才能运行这些应用程序,这是一项耗时的工作。

我可以更换笔记本电脑,也可以更换MacOS版本,但是项目保持不变。它仍然需要同样一套软件包才能成功运行其部署脚本。而且这个项目已经不再活跃开发。我现在主要使用Java,因此在日常工作中不需要这些软件包。但是,当我需要对那个PHP项目进行微小修复并部署时,我必须安装所有必需的PHP软件包并进行配置。只有在安装完成后,我才能部署这个微小的修复。

这真是令人讨厌。

Docker使我能够自动化完成所有这些工作。我的现有部署脚本将会获得一个开头,它将在一个干净的Ubuntu容器中安装和配置所有必需的与PHP相关的软件包。这个开头将在每次运行我的部署脚本时,在一个Docker容器内部执行。例如,它可能是这样的:

在我开始使用Rultor之前,我的部署脚本是这样的:

只有两行。第一行是完整的单元测试运行。第二行是将文件传输到生产服务器的FTP部署。非常简单。但是,只有在安装了PHP 5.3、MySQL、Phing、xdebug、PHPCS和PHPUnit的情况下,这个脚本才能正常工作。再次强调,每次升级我的MacOS或更换笔记本电脑时,安装和配置它们都是一项繁重的工作。

不用说,如果有人加入项目并尝试运行我的脚本,他/她将不得不再次进行这个预安装工作。

因此,这是一个新的脚本,我现在正在使用它。它每次都在一个新的Docker容器中执行:

很显然,在我的MacBook上运行这个脚本(没有虚拟化)会引起很多麻烦。嗯,我这里甚至没有apt-get。

因此,Rultor给你提供的第一个好处是将你的部署脚本隔离在自己的虚拟环境中。我们主要是通过Docker实现这一点。

传统上,我们将部署脚本保存在某个 ~/deploy 目录中,并使用一组神秘的参数来运行它们。在小项目中,您自己完成这个操作,这个目录位于您自己的笔记本电脑上。在大项目中,有一个“部署”服务器,该服务器上有一个包含一组只能由少数可信赖的高级开发人员执行的脚本的神奇目录。我见过很多次这种设置。

这里最大的问题是可追溯性。几乎不可能找出是谁部署了什么以及为什么某个特定的部署失败。高级部署专家只需通过 SSH 连接到服务器并使用神奇的参数运行这些脚本。日志通常会丢失,问题跟踪非常困难或者根本不可能。

Rultor 提供了不同的解决方案。使用 Rultor,不再需要 SSH 访问部署脚本。所有脚本都保存在 .rultor.yml 配置文件中,并且您可以通过在问题跟踪系统(例如 GitHub、JIRA 或 Trac)中发布消息来启动它们。Rultor 运行脚本并将完整的日志发布到您的工单中。日志将永远与您的项目保持在一起。您始终可以回到您正在处理的工单并检查为什么部署失败以及实际执行了哪些指令。

例如,请查看这个 GitHub 工单,我在其中部署了一个新版本的 Rultor,并多次失败:yegor256/rultor#563。我所有的失败尝试都被记录下来。我始终可以回到它们并进行调查。对于大型项目而言,这些信息至关重要。

因此,Rultor 相对于独立的部署脚本的第二个好处是每个操作的可见性。

当你有一个自定义脚本存储在你的笔记本电脑或那个保密的团队部署服务器中时,你的生产凭据就靠近它了。没有其他办法。如果你的软件与数据库一起工作,它必须知道登录凭据(用户名、密码、数据库名称、端口号等)。嗯,在最糟糕的情况下,有些人直接将这些信息硬编码到源代码中。我们甚至不打算讨论这种情况,因为它太糟糕了。

但是假设你将数据库凭据与源代码分离。你会有一个类似于 db.propertiesdb.ini 的文件,在部署之前将其附加到应用程序上。你也可以直接将该文件保存在生产服务器上,这样做甚至更好,但并非总是可能的,特别是在 PaaS 部署中。

存储库中部署物件时也存在类似的问题。比如,你经常部署到 RubyGems.org。你的 ~/.gem/credentials 文件中包含了你的秘密 API 密钥。

因此,很多时候,你的部署脚本都会附带一些包含敏感和安全信息的文件。而这些文件中的信息是以明文、开放的格式存在的。没有加密,没有保护。只是明文的用户名、密码、代码和令牌。

为什么这样不好呢?对于一个仅有一台笔记本电脑的开发人员来说,这听起来不是一个问题。尽管如此,我不喜欢在机场的某个地方丢失一台笔记本电脑,而所有凭据都是公开且随时可用的。你可能会争辩说有一些磁盘保护工具,比如 MacOS 的 FileVault 或 Windows 的 BestCrypt。是的,也许。

但是,当我们有一个团队的开发人员一起工作并共享那些带有凭据的部署脚本和文件时,情况就不同了。一旦你将部署脚本的访问权限交给团队的新成员,你就必须共享所有敏感数据。没有办法绕过这一点。为了使用这些脚本,他/她必须能够打开包含凭据的文件。

如果你关心数据的安全性,这就是一个问题。

Rultor通过在部署脚本使用敏感数据之前提供即时的GPG解密来解决这个问题。在 .rultor.yml 配置文件中,你只需要写上:

然后,您可以使用Rultor GPG密钥对db.ini进行加密,然后毫不犹豫地将db.ini.asc提交到存储库中。除了Rultor服务器在运行部署脚本之前,没有其他人能够打开和阅读该文件。

因此,与独立部署脚本相比,Rultor的第三个好处是对敏感数据的适当安全性保护。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-16 at 15:03

sixnines availability badge   GitHub stars