带有 Laravel 应用程序的自包含 Docker 映像(无共享卷)

Bin*_*ntz 10 php nginx laravel docker

网络上至少有十几个关于如何使用 Docker 设置 Laravel 应用程序的教程。他们都使用的基本设置是 3 个 Docker 容器:

  • nginx容器
  • php-fpm 容器
  • mysql 容器

Nginx 和 PHP-fpm 容器依赖于共享卷。HTTP 请求进入 Nginx 以获取共享卷上的文件。Nginx 将请求交给 PHP-fpm。Php-fpm 还可以访问共享卷中的文件,因此它可以运行脚本。

对于开发来说,这太棒了。我可以编辑共享卷中的文件并立即测试更改。但我在质疑我是否希望将其用于生产。我真的希望我的任何代码都在运行 Docker 的服务器上吗?这似乎首先违背了 Dockerising 的一些目的。似乎我希望代码在运行 nginx 和 PHP-fpm 的 Docker 容器中自包含(数据库可以是托管环境中的单独容器或服务)。

我的想法在这里正确吗?在 Docker 中部署 Laravel 进行生产的最佳实践是什么?

β.ε*_*.βε 2

您在这里忽略了一个非常重要的事实:在生产服务器上,卷不应该是绑定安装,它们大多是“正常”卷,并且它们的目的之一确实是能够在容器之间共享数据。

\n
\n

卷是持久保存 Docker 容器生成和使用的数据的首选机制。虽然绑定挂载取决于主机的目录结构和操作系统,但卷完全由 Docker 管理。与绑定挂载相比,卷有几个优点:

\n
    \n
  • 卷比绑定安装更容易备份或迁移。
  • \n
  • 您可以使用 Docker CLI 命令或 Docker API 管理卷。
  • \n
  • 卷适用于 Linux 和 Windows 容器。
  • \n
  • 卷可以在多个容器之间更安全地共享。
  • \n
  • 卷驱动程序允许您将卷存储在远程主机或云提供商上,以加密卷的内容,或添加其他\n功能。
  • \n
  • 新卷的内容可以由容器预先填充。
  • \n
  • Docker Desktop 上的卷比 Mac 和 Windows 主机上的绑定挂载具有更高的性能。
  • \n
\n

此外,卷通常是比将数据持久保存在容器\xe2\x80\x99s 可写层中更好的选择,因为卷不会增加使用它的容器的大小,并且卷\xe2\x80\x99s 的内容存在于外部给定容器的生命周期。

\n

Docker 卷类型

\n

如果您的容器生成非持久状态数据,请考虑使用 tmpfs 挂载以避免将数据永久存储在任何位置,并通过避免写入容器\xe2\x80\x99s 可写层来提高容器\xe2\x80\x99s 的性能。

\n

卷使用 rprivate 绑定传播,且绑定传播不可针对卷进行配置。

\n
\n

来源: https: //docs.docker.com/storage/volumes/,强调,我的

\n

因此,正如您在这里所看到的,即使是 Docker 的文献也建议卷不要将某些特定情况的持久数据捆绑在容器本身中。

\n

拥有一个捆绑 NGINX 和 PHP 的容器也会破坏容器化的想法:

\n
\n

通常建议您通过每个容器使用一项服务来分隔关注区域。该服务可能会分叉为多个进程(例如,Apache Web 服务器启动多个工作进程)。拥有多个进程是可以的,但为了充分利用 Docker,请避免一个容器负责整个应用程序的多个方面。您可以使用用户定义的网络和共享卷连接多个容器。

\n
\n

来源: https: //docs.docker.com/config/containers/multi-service_container/

\n
\n

每个容器应该只有一个关注点。将应用程序解耦到多个容器中可以更轻松地水平扩展和重用容器。例如,Web 应用程序堆栈可能由三个独立的容器组成,每个容器都有自己独特的映像,以解耦的方式管理 Web 应用程序、数据库和内存缓存。

\n

将每个容器限制为一个进程是一个很好的经验法则,但这并不是一个硬性规定。例如,不仅可以使用init 进程生成容器,某些程序还可能自行生成其他进程。例如,Celery可以生成多个工作进程,而Apache可以为每个请求创建一个进程。

\n

运用您的最佳判断力,尽可能保持容器清洁和模块化。如果容器之间相互依赖,可以使用Docker容器网络来确保这些容器可以通信。

\n
\n

来源:https ://docs.docker.com/develop/develop-images/dockerfile_best-practices/#de Couple-applications

\n
\n

在您的特定用例中,捆绑 NGINX + PHP-FPM 容器会违背您可能希望独立于 PHP-FPM 扩展 NGINX 的事实,例如,如果您在 NGNIX 级别上进行反向代理缓存,您将很快需要的 NGINX 容器副本比您需要的 PHP 容器多得多。

\n

因此,将它们分开将有利于您的水平扩展需求,并且更接近应用程序容器化的原则。

\n

在这种情况下我会问自己一个问题:

\n
\n

如果我要将这些流程捆绑在一个容器中,那么我是否需要启动任何类型的流程控制系统,例如该容器中的主管

\n
\n

如果答案是肯定的,那么我肯定会问自己,我是否没有违背应用程序容器化的目的。

\n
\n

相关问题:

\n\n