使用 Docker 和 Docker-Swarm 运行 Symfony 5 项目的最佳实践

问题描述

我有一个现有的 Symfony 5 项目,其中包含一个 MysqL 数据库一个 Nginx 网络服务器。我想对这个项目进行 dockerize,但在网络上我发现了如何做到这一点的不同意见。

我的计划是编写一个多阶段的 Docker 文件,其中至少有一个开发阶段和一个生产阶段,然后使用 docker-swarm 进行构建。在我看来,在构建过程中安装完整的代码并拥有多个 composer.json 文件(每个阶段一个)很有用。在网络上,我发现不要在每次构建时都安装新的应用程序,而是将供应商和 var 文件夹复制到容器中。另一种意见是在容器的构建过程准备就绪后开始安装。但我认为,当应用程序成功部署时,服务还没有准备好。

您认为这里的最佳做法是什么?

解决方法

为所有环境构建完全相同的镜像

不要为 prod 和 dev 构建 2 个不同的映像。 Docker 的主要优势之一是,您可以为生产和开发提供完全相同的环境。

您应该使用 ENV 变量来控制您的环境。例如,您可以为 Xdebug 启用 dev 并为 prod 禁用它。

Composer 可以选择安装开发包和生产包。您应该使用此功能。

如果您决定安装一些软件包到 dev。尝试对两种环境使用相同的 Dockerfile。不要使用 Dockerfile.prodDockerfile.dev,它会在未来引入一些混乱。

多阶段构建

如果您的构建环境需要比运行时更多的依赖项,您可以执行 the official Docker documentation 中描述的多阶段构建。

它的例子是程序的编译。在编译期间,您需要大量库,并且生成单个二进制文件。所以你的运行时不需要所有的开发库。

第一阶段可以在第二阶段构建,您只需复制二进制文件即可。

将所有包构建到 docker 镜像中

您应该在构建 Docker 镜像时构建您的应用程序。所有的库和包都应该复制到镜像中,你不应该在应用程序启动时安装它们。原因:

  • 安装一切后应用程序启动速度更快
  • 某些库将来可以更改或删除。您会遇到麻烦,并且可能会花费大量时间进行调试。

实施健康检查

您应该实施健康检查。应用程序需要外部依赖项,例如密码、API KEY、一些非敏感数据。通常,我们使用环境变量注入数据。

在您的应用程序启动之前,您应该检查是否所有必需的变量都已通过,并且格式是否正确。您可以实施健康检查,也可以在入口点进行检查。

在发布之前测试您的解决方案

您应该实施测试图像的机制。例如在 CI 中:

  • 在构建映像之前运行单元测试
  • 构建 Docker 镜像
  • 使用虚拟数据启动新的应用程序映像。如果您需要 PostgreSQL DB,您可以启动另一个容器,
  • 运行集成测试。
  • 仅当所有测试都通过时才发布新版本的图像。