Every Build in Its Own Docker Container

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

Docker 是一个命令行工具,可以在一个虚拟的 Linux 环境中运行一个 shell 命令,并在一个隔离的文件系统中运行。每次构建我们的项目时,我们希望它们能在自己的 Docker 容器中运行。以这个 Maven 项目为例:

这个命令将启动一个新的Ubuntu系统,并在其中执行mvn clean test。我们的虚拟助手Rultor.com在部署、打包、测试和合并时,会完全按照这个方式来执行我们的构建。

它给我们带来了哪些好处?既然存在许多其他虚拟化技术(例如LXC),为什么要选择Docker呢?

嗯,这里有几个非常重要的好处:

  • Versioning

  • “Application-centric” in Chinese: “以应用为中心的”

让我们详细讨论它们。

Docker通过其位于hub.docker.com的公共仓库实现镜像共享。这意味着在我为我的应用程序准备好工作环境后,我会将其制作成镜像并推送到仓库中。

假设我希望在一个已经安装了graphviz软件包(以便启用dot命令行工具)的容器中执行我的Maven构建。首先,我会启动一个普通的Ubuntu容器,并在其中安装graphviz

我有一个在几秒钟前停止的容器。容器的ID是215d2696e8ad。现在,我想要在Rultor.com上将其变成可重用的,供所有后续测试使用。我必须从中创建一个镜像。

我刚刚将我的新提交提交到了一个名为yegor256/beta的新镜像中。这个镜像现在可以被重复使用。我可以从这个镜像中创建一个新的容器,里面将安装graphviz

现在是时候在Docker Hub上分享我的镜像,以便让它对Rultor可用了。

最后一步是配置Rultor在所有构建中使用这个镜像。为了做到这一点,我将编辑我GitHub存储库根目录下的.rultor.yml文件。

就是这样。从现在开始,Rultor将在每次构建(合并,发布,部署等)中使用我定制的预安装了 graphviz 的 Docker 镜像。

此外,如果我想要向镜像添加其他内容,这很容易做到。比如说,我想要在我的构建镜像中安装Ruby。我从镜像中启动一个容器并进行安装(注意,我现在不再从 ubuntu 镜像中启动容器,而是从 yegor256/beta 镜像中启动)。

现在您可以看到我有两个容器。第一个是我正在使用的容器,它包含了Ruby。第二个是我之前使用过的容器,它包含了graphviz

现在我需要再次提交并推送:

因此,这个Docker hub对于Rultor和类似的系统来说是一个非常方便的功能。

正如您在上面的示例中所见,对Docker镜像的每个更改都有其自己的版本(哈希值),可以对更改进行跟踪。还可以回滚到任何特定的更改。

Rultor本身并未使用此功能,但Rultor用户能够以更高的精确度控制其构建配置。

Docker,与LXC或者Vagrant不同,是以应用为中心的。这意味着当我们启动一个容器时,我们启动的是一个应用。而使用其他虚拟化技术时,当你获得一个虚拟机时,你会得到一个完全功能的Unix环境,在这个环境中,你可以通过SSH登录并做任何你想做的事情。

Docker让事情变得更简单。它不会给你容器提供SSH访问权限,但是在容器内运行应用程序,并显示其输出。这正是Rultor所需要的。我们需要运行一个自动化构建(例如Maven或Bundler),查看其输出并获取其退出码。如果退出码不为零,我们会失败并向用户报告。

这是我们运行Maven构建的方式:

如您所见,Maven会立即启动。我们不必担心容器的内部细节,只需在其中启动一个应用程序。

此外,由于--rm选项,容器在Maven执行完成后立即被销毁。

这就是所谓的以应用为中心。

我们对Docker的整体印象非常积极。

附:此文章的简化版本已在devops.com发布。

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

sixnines availability badge   GitHub stars