使用 Docker 设置现代 PHP 开发环境

在本教程中,我将介绍如何最好地开始设置 PHP 开发环境,并向您介绍如何使用 Docker 进行设置。 设置 PHP 开发环境的方法有很多种,但使用 Docker 是当前的最佳实践。

我将首先简要介绍多年来人们如何设置他们的 PHP 开发环境,以及我们现在所处的位置。 但是如果您宁愿跳过所有这些而只是让您的服务器运行,您可以直接跳到配置步骤。

一点背景

Web 开发的问题之一是事物变化很快。 随着新属性被添加到规范中,CSS 最佳实践也会发生变化。 (如果没有 CSS 网格,我们如何应对?)PHP 现在是第 8 版,甚至我们用来执行 PHP 脚本的工具也在不断改进。 结果,很多教程很快就过时了。

直到几年前,我才派我教过的每个人阅读 Bruno Skvorc 的优秀文章重新介绍 Vagrant:开始使用 PHP 的正确方法。 在当时,这是对(当时)建立本地开发环境的最佳方式的精彩介绍。

那篇文章仅来自 2015 年,但在不断变化的 Web 开发时间尺度中,五六年是一个永恒。 从那时起,“正确的方式”有了很大的进步。

我将快速回顾一下这些年来事情发生了怎样的变化。

1、手动安装PHP、MySQL和Apache

如果像我一样,你的年龄足以在 90 年代开发网站,你会记得那段经历是多么令人沮丧。 那时,如果您是少数不只是在实时 Web 服务器上进行开发的人(是的,我们确实这样做了,是的,这是一个糟糕的主意),您将在您的开发机器上手动安装 Apache、PHP 和 MySQL。

设置开发环境需要大量专业知识。 你需要知道如何配置 Web 服务器,如何配置 PHP,并且你必须经历手动安装和配置你使用的所有软件的过程。 对于新手开发人员来说,这本身就是一项耗时且艰巨的任务。

2. XAMPP等预配置包

到 2000 年代初到中期,人们开始将所有必需的软件放在一个包中,安装和配置您需要的所有软件。 这些包类似于 XAMPP 和 WAMP,只需单击一个按钮,它们就会为您提供一个可用的开发环境。

如果您在各种 PHP facebook 群组中闲逛,您会发现很大一部分新开发人员仍在遵循这个时代的教程,而大量现有开发人员从未继续前进,因此 XAMPP 仍被广泛使用。 如果这描述了你,那么是时候继续前进了。

使用 XAMPP 可以非常轻松地在您的计算机上启动和运行 Web 开发环境。 Bruno 的文章概述了这种方法的问题,但主要问题出现在您希望将站点放到 Web 上时。 PHP、MySQL 和 Apache(或 NGINX)的版本可能与您作为 XAMPP 包的一部分安装的版本不同。 此外,Windows 和 Linux 之间还有一些细微但令人沮丧的差异。 如果您在 Windows 机器上开发站点并将其上传到 Linux 服务器,则您的某些代码在上传后可能根本无法运行。

3.虚拟机和Vagrant

在 2000 年代末和 2010 年代初,开发人员的趋势是转向虚拟机。 这个想法是,您可以运行真实 Web 服务器操作系统的副本及其所有安装的程序 — 与您最终要将网站部署到的实际 Web 服务器完全相同的配置和设置。 这样,当您使网站上线时,它就不可能无法正常工作。

虽然许多程序员看到了这样一个环境的好处,但设置它的难度和时间意味着很少有人这样做。 直到 Vagrant(以及 Puphpet 等相关工具)出现并消除了这样做的所有麻烦。

查看我之前链接的文章,其中对 Vagrant、虚拟机以及以这种方式设置开发环境的好处进行了出色的描述。

4. 码头工人

所有这些背景都把我们带到了今天,也是写这篇文章的原因。 如果 Vagrant 这么棒,为什么要用别的东西代替呢?

使用 Vagrant 设置虚拟环境的主要好处是:

    您的开发 PC 未绑定到特定环境中。 您可以托管多个网站:一个使用 Apache,一个使用 NGINX,一个使用 PHP 7,一个使用 PHP 8。

    当网站上线时,网站将被上传到与开发时完全相同的环境中。

很容易看出开发人员为什么想要这个。 进一步升级到 Docker 可以保留这些好处,同时避免 Vagrant/虚拟机环境的一些缺点。

Vagrant 有什么问题?

尽管有这些好处,基于 Vagrant 的开发环境也引入了它自己的一系列限制和问题。

    系统资源。 Vagrant 需要运行一个完全不同的操作系统。 您需要下载并安装在您的 Web 服务器上运行的操作系统,以及它已安装的所有包。 这会占用大量磁盘空间和内存。 虚拟机通常至少需要 512 MB RAM。 这对于今天的计算机来说不算多,但它很快就会加起来。 如果您想在 PHP 7 上托管一个网站,在 PHP 8 上托管一个网站,您需要在您的计算机上安装和配置两个不同的虚拟机实例。

    您必须确保虚拟机和服务器同步。 每当您更新服务器或更改服务器的配置时,您必须记住用相同的更改更新您的本地开发环境。

    它将您紧紧锁定在服务器操作系统和配置中。 将网站从一台服务器移动到另一台服务器是一项艰巨的任务。 一个网站不仅仅是构成它的 PHP 脚本、图像和 CSS。 特定的服务器配置(例如安装的 PHP 扩展和 nginx.conf/httpd.conf) 也是网站正常运行所必需的。

    可用软件包的选择非常有限。 根据您的 Web 服务器运行的 Linux 发行版,您可能无法选择运行的 PHP 版本。 除非您从第三方存储库安装软件包,否则您将无法使用最新最好的 PHP 版本。 在撰写本文时,PHP 8 最近已可用。 如果您使用的是 CentOS 8/RHEL 8,那么在获得新版本的操作系统之前,您将一直使用 PHP 7.3。 如果您使用的是 Debian,则可用的最新版本是 7.3。 其他发行版将有不同的可用版本。

    服务器配置是全局的。 PHP 有一个名为 php.ini. 更改此项会将更新的配置应用到服务器上托管的每个网站。 同样适用于 nginx.conf 对于 NGINX 或 httpd.conf 对于阿帕奇。 MySQL 数据库实例具有服务器上托管的所有站点的数据库。 进行任何大规模的数据库配置更改都影响深远。 更新 MySQL 设置将影响使用该 MySQL 服务器的每个网站!

    软件包版本在真实服务器上是全局的。 尽管可以在同一个 Web 服务器上运行多个 PHP 版本,但它很难配置,并且会产生奇怪的副作用,具体取决于您的脚本正在做什么(例如,当您有一个脚本要在 systemd 单元/cronjob 中运行时,忘记你应该使用 /bin/php72 而不是 /bin/php).

虽然第 5 点和第 6 点可以在开发机器上通过运行不同的 Vagrant 虚拟机来克服,但您需要一个真实的 Web 服务器来镜像您正在运行的每个配置,以便网站在您上传它们时正常工作。

介绍码头工人

Docker 解决了上面列出的所有问题。 但究竟什么是 Docker,它是如何工作的?

让我们从维基百科的介绍开始:

Docker 是一组平台即服务 (PaaS) 产品,它们使用操作系统级虚拟化在称为容器的包中交付软件。 容器彼此隔离,并捆绑自己的软件、库和配置文件; 他们可以通过明确定义的渠道相互沟通。

在过于技术化之前,作为 Web 开发人员的实际好处是 Docker 允许我们打包网站所需的一切,所有 PHP 代码以及 PHP 可执行文件、MySQL 服务器和 NGINX 服务器,以及那些使用的配置文件程式。

所有网站的代码,以及运行该代码所需的程序的确切版本,都打包在一起,有效地作为一个应用程序。 然后可以在任何操作系统上运行整个应用程序。 当有人运行打包的应用程序时,PHP、MySQL、NGINX 和您编写的所有 PHP 文件都嵌入到应用程序本身中。 更好的是,确切的 MySQL、NGINX 和 PHP 版本是包的一部分。 当您运行该应用程序时,将下载并安装应用程序开发所针对的这些工具的确切版本。

“这不是虚拟机已经在做的事情吗?” 我听到你问。 是的,但是 Vagrant 和 Docker 处理软件安装的方式有很大的不同。

使用 Vagrant,运行虚拟机,具有特定 PHP 版本、MySQL 版本和(通常)服务器配置的完整操作系统是从真实的 Web 服务器克隆的。 当服务器更新时,虚拟机也必须更新。

然而,当使用 Docker 时,PHP/MySQL/NGINX 版本作为称为图像的单个包提供,并且服务器可以运行任意数量的不同图像。

这里的好处是 Web 服务器和您的开发机器都运行完全相同的图像。 您只需将图像上传到网络服务器,在那里运行整个应用程序,您的网站就可以启动,而根本不需要任何网络服务器配置。

此外,每个图像都与服务器上的其他图像完全分开。 每个图像(在这个简化示例中每个网站一个)彼此分开。 每个网站都会有自己的 NGINX 配置,自己的 php.ini 以及它自己安装的 PHP 和 MySQL。 每个网站都可以运行完全不同的 PHP 版本。 您甚至可以同时在同一台机器上让一个网站在 Apache 上运行,一个网站在 NGINX 上运行。 即使当您运行两个不同的 NGINX 网站时,您也会同时运行两个不同的 NGINX 进程,它们具有自己的配置。

这有一个小的内存开销,但它赋予的灵活性使这是一个非常值得的权衡:

    整个网站,以及所需的 PHP/MySQL 版本,所有配置和所有代码都可以轻松移动。 将网站移动到新服务器只需要复制一个文件夹。 您无需对新服务器上的 PHP 或 NGINX 配置进行任何更改。 您甚至不需要在服务器本身上安装 PHP 或 NGINX。 当您启动应用程序时,它们将由 Docker 自动安装。

    您可以在您的开发机器上运行完全相同的图像。 使用 Vagrant,您可以有效地在同一台机器上运行服务器配置/安装包的副本。 使用 Docker,在您的 PC 上运行与在服务器上运行的完全相同的图像以进行开发。

    php.ini 调整, nginx.conf 配置更改或将 PHP 更新到最新版本的处理方式与将更新的 PHP 代码上传到服务器的处理方式相同。 您更新应用程序,无论是更改某些 PHP 代码还是更新都无关紧要 php.ini.

    每个图像都包含在称为“容器”的东西中。 在一个图像中运行的 PHP 脚本无法访问在另一个图像中运行的文件。 思考 open_basedir 但要严格得多。 容器就像一个非常轻量级的虚拟机。 它就像它自己的操作系统,在容器中运行的代码甚至不知道它正在一个容器中运行,同时看不到容器外的任何东西。 如果您的某个 PHP 脚本不安全并为某人提供了有效的 shell 访问权限,则他们只能访问您授予容器访问权限的服务器上的文件。

    与虚拟机不同,如果两个不同的网站位于完全不同的容器中但使用相同的 NGINX 或 PHP 版本,则磁盘空间和 RAM 将在两个容器之间共享。

    因为每个图像都是独立的,所以将网站移动到不同的服务器很容易。 该应用程序不依赖于服务器安装的 PHP 版本,也不关心服务器上安装了哪些包。 如果您想将 Dockerized 应用程序移动到不同的服务器,只需复制所有网站文件并启动应用程序即可。

    您可以在…上运行尽可能多的 Docker 映像

阅读更多

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注