本地网站开发环境搭建的八项规则
开发环境是任何网站开发项目的关键组成部分。借助它,我们能够在生产环境之外运行网站,这样在处理功能添加或漏洞修复时,就不会对实时网站产生影响。
多年来,我在构建网站时一直使用本地开发环境,并且一直在遵循一套让工作更轻松的规则。这些规则并非强制要求,但遵循它们能让开发团队的每个人的工作都更顺畅。我见过不少开发人员花费大量时间解决本地开发环境的问题,而这些时间本可以更高效地用于实际的项目开发。
我公司从另一家公司接手一个网站项目后,我便开始整理这些规则。这个网站需使用特定的本地开发栈,这是托管服务提供商的要求。然而,每次为项目添加新的开发人员时,由于本地环境复杂,至少得花两天时间进行入职培训。项目本身并不复杂,但因为使用的本地开发系统,我们花费了大量时间才让项目正常运行。
我们必须遵循的文档长达 10 页,其中包含许多检查特定版本和在本地安装大量软件包的步骤。它对开发人员机器的设置要求极为严格,稍有偏差就可能要花费数小时安装合适版本的软件。
我很惊讶竟然有人认为为了让项目启动和运行付出这么多努力是可以接受的。我设定的目标之一是将该项目从那个设置中迁移出来,之后项目的后续开发就容易多了。而且,我们不用再浪费大量时间让新开发人员融入项目。
最近发布的 2023 Drupal 本地开发调查结果让我再次想起了这些规则,所以我想把它们整理成一篇文章。这里我主要会讨论 Vagrant、Docker 或云端设置。我已经很多年没有使用本地安装的 LAMP 栈作为本地开发环境了,所以不会涉及这方面的内容。实际上,如果你还在使用本地 LAMP 栈,我强烈建议你考虑基于 Docker 的设置,因为这会让 Drupal 开发变得轻松很多。
以下是这些规则的列表,如果你想跳着看可以参考。
- 所需软件包应易于安装
- 对项目的影响应最小化
- 新开发人员应易于融入
- 设置应易于修改
- 应尽可能模拟生产环境的设置
- 开发人员无需数据库和所有用户文件即可开展项目工作
- 应具备合理的覆盖设置
- 应封装和/或记录常见任务
一、所需软件包应易于安装
理想的本地开发环境,应该只需几条指令就能安装到新机器上。就算需要先安装一些东西,或者运行一些指令,只要不是有好几页复杂的说明和严苛的版本要求,那都没问题。
这并非关乎安装所需的时间,而是安装过程的复杂程度。启动安装过程后若需要等待 10 分钟来下载容器,那么这段时间可以用来阅读项目文档。
要是项目没有太多第三方依赖,那就再好不过了。大多数现代开发环境都通过 Docker 或 Vagrant 完成所有设置,这些软件包有很好的支持,并且被广泛使用。而某些需要 20 个步骤才能安装或需要手动编译的晦涩软件包,并非最佳选择。
你还得考虑开发解决方案所支持的操作系统。肯定不想因为开发人员的系统与开发解决方案不兼容,而不得不购买新设备或拒绝承包商。
二、对项目的影响应最小化
理想情况是,环境所需的所有内容都应保存在一个目录甚至一个文件中。
本地 LAMP 栈符合这一点,因为它们对项目没有影响,但这意味着每个开发人员的设置可能会略有不同。这可能会由于版本不兼容或软件问题而引入漏洞和错误。
关键在于,如果你想从该开发环境中迁移出来,不应花费数周时间从系统中拆解所有内容。
这也意味着你不应为了让项目在该环境中运行而对其进行修改。当你为了适应开发系统而修改代码时,一旦将代码推送到上游,就难免会出现容易被忽略的漏洞。
三、新开发人员应易于融入
如果你的设置指南是一份包含大量步骤且必须按精确顺序执行的冗长文档,那你就做错了。花费一整天时间来让本地开发环境运行起来是一种极大的时间浪费。这些时间开发人员本可以用于为项目做出有益的贡献。
理想情况是,开发人员只需克隆代码仓库,然后运行一条指令就能让所有东西运行起来。新开发人员应该能够通过阅读一页文档来了解如何启动和运行项目,以及如何对项目进行调整和更改。
即便对于一个成熟的项目,也很容易对设置的简便性掉以轻心。从头开始的开发人员可能会遇到在日常项目工作中未被发现的问题。所以,你应该始终确保新开发人员在开始项目时有一定的支持,以应对这类问题。
四、设置应易于修改
设置应该为所需系统提供合理的默认值,包括 Nginx 和 PHP 的最新版本。为项目设置自定义配置不可避免,因此这些配置必须能够以某种方式进行调整。
例如,你可能在项目开始时使用 PHP 7.4,之后某个时候需要升级到 PHP 8.1。理想情况是,你只需在配置文件中添加或编辑一个设置,然后重新构建项目(如果是基于 Docker 的,只需重新构建该容器)即可完成更改。
进行修改应该简单易行,并且涉及的配置文件数量应尽可能少。这些文件可设置的值的文档应该易于查找并保持更新。
同样重要的是,要将这些更改告知项目团队的其他成员。如果你在配置文件中更改了一个值,可以将其提交到源代码中,以便团队其他成员能够轻松地修改他们的配置,使其保持一致。
五、应尽可能模拟生产环境的设置
虽不需要完全一致,但你的本地设置至少应该使用与生产环境相同的软件包。这还应包括每个软件包的不同版本和配置选项。
不同版本或配置选项之间可能会引发许多问题。我曾遇到过在不同系统上运行不同版本的 PHP、MySQL 甚至 Node 时出现的问题,一旦代码部署到生产环境,就会导致严重的漏洞。
不过,问题可能更微妙。例如,如果你使用的是 MySQL/MariaDB,应该确保其配置与生产环境相同,因为这些配置选项可能会影响查询的执行方式。我见过一些网站出现错误,原因是开发人员编写的查询在本地运行正常,但部署后由于配置设置的差异而出现问题。
六、开发人员无需数据库和所有用户文件即可开展项目工作
开发人员在检出项目文件后,只需运行几条命令就可以开始项目工作。这意味着他们不需要获取最新的数据库副本就可以开始工作。
当然,在某些情况下这可能无法实现,特别是在调查特定用户问题或编写迁移脚本时。但在日常开发过程中,不应该有此需求。
Drupal 针对此类问题有一些很好的解决方案。像 Default Content Deploy 这样的 Drupal 模块可以用于直接向数据库填充内容,它可以与安装配置文件和配置一起使用,以便设置所有内容来模拟生产网站的结构。
Drupal 的 Stage File Proxy 模块允许在需要时将生产网站上的任何文件下载到本地。这意味着你不需要下载整个文件系统就能让本地网站正常运行。
如果确实需要数据库,应该使用 Drush sanitize 等工具清除网站上的个人信息。这能让你放心,因为这意味着开发人员不会访问到他们不需要的数据,也不会在本地设置中意外向真实用户发送邮件。理想情况下,应该在开发人员获取数据之前自动对数据进行清理。
你也可以在开发系统中包含一个小的存根数据库,这样开发人员就可以快速启动和运行项目,甚至可以进行系统的单元测试。为了使其有效,需要对其进行正确维护,因此如何更新它应该有详细的文档说明。
七、应具备合理的覆盖设置
作为开发环境,应该具备合理的覆盖设置,以防止开发人员遗漏问题或犯错。
最基本的是要启用合理的错误报告级别。例如,如果项目使用 PHP,网站应该显示所有类型的错误。这样开发人员就能及时发现自己的错误,若像在生产环境中那样隐藏错误,他们可能就会错过这些问题。
运行开发环境(特别是包含生产数据的环境)存在的一个风险是可能会泄露信息。最典型的例子是,当网站使用邮件功能,而你的开发环境没有抑制邮件发送时。没有什么比因为开发人员向真实用户发送测试邮件而向客户道歉更尴尬的了,而你的本地设置应该能够轻松避免这种情况。
你的开发环境应该始终以对开发人员友好的方式进行设置,以防止信息泄露和常见错误。
八、应封装和/或记录常见任务
最后,为了让开发人员的工作更轻松,环境应该封装常用的任务。这样可以节省设置时间,或者在执行语法检查或单元测试等其他常见任务时提高效率。在项目中包含一个 README.md 文件,列出一些有用的命令也是个好主意。
这不一定是本地环境系统的一部分,但应该被视为项目的一部分,因为它会影响开发人员对系统的使用体验。
例如,如果你的环境有一个可以安装项目的功能,但该命令需要一些参数。在这种情况下,你应该用某种运行器封装该命令。Bash 脚本、Make 文件、Composer 文件甚至命令运行器都是可行的,只要开发人员不必记住这些命令即可。
许多工具也具备自我文档化的功能。例如,你可以在项目中创建一个 Makefile,通过单独运行 'make' 命令就可以打印出其中所有可用的命令(虽然这需要一些配置)。这意味着开发人员在需要运行某个命令但忘记了具体内容时,无需查看 Makefile 或查找文档。
关键是要让任务运行器能够轻松地与你的开发工具集成。如果你要运行的命令需要在 Docker 容器中执行,那么应该能够在 Makefile 中轻松操作该容器。
这种技术在测试或运行代码分析时非常有用。让开发人员能够轻松地在你的网站上运行单元测试套件非常有帮助,将其封装在一条命令中会让操作变得更加简单。更棒的是,当你为项目创建持续开发环境时,可以直接运行相同的命令,无需从头开始。
结论
我通常发现,如果你遵循这些规则,那么你和团队中的开发人员都会更轻松。这体现在环境搭建、日常工作流程、调试问题以及将代码部署到上游等方面。你的本地开发环境应该有助于你的工作,而不是成为完成工作的障碍。
项目中系统的持续维护也是一个重要的考虑因素。我见过一些公司花费大量时间设置一个自定义开发环境,使用的编程语言或技术开发团队中没有人了解。这会造成一个相当严重的瓶颈,当出现问题时,开发团队只能依靠原作者来解决。在开发这些解决方案时,确保团队成员熟悉相关内容同样重要。
DDEV 软件包在很多方面都符合上述规则,它易于安装、文档完善、高度可配置,并且对项目本身的影响很小。该系统最初是为 Drupal 创建的,但现在可以用于许多不同的 PHP 项目,包括 WordPress 和 Typo3。可以使用一条命令将 DDEV 添加到新项目中,这意味着新成员入职和环境设置都很简单。这是通过 ddev config 命令实现的,只需回答几个问题,就可以将 DDEV 软件包添加到任何项目中。
DDEV 和 Lando 等软件包是 Drupal 开发人员非常受欢迎的工具,我认为这是因为它们符合这里列出的许多要求。像 docker4drupal 这样的系统不太受欢迎,我认为这是因为它们只是简单的 Docker 栈,要充分发挥其强大功能需要一些 Docker 知识。
像 GitPod (以及用于 Drupal 网站的 DrupalPod 等扩展)这样的系统可以解决许多这些问题,而无需在本地机器上安装任何东西。这些是基于云端的开发环境,这意味着你要开发网站的各个方面,只需要一个浏览器和互联网连接即可。唯一的缺点是你需要一个稳定的网络连接,在一些办公室可能无法保证。我曾在一些办公室遇到网络不稳定的情况,但由于所有工作都是在本地进行的,对团队的影响很小。不过,在受限制的系统上进行开发时,它可以避免安装任何东西就能启动和运行的问题。
选择开发环境应该是项目开发生命周期中的一个重要环节。这通常被称为“零冲刺阶段”,因为它发生在项目的实际工作开始之前,但却是项目不可或缺的一部分。我见过一些项目由于开发环境选择不当而难以推进,这对项目的影响比你想象的要大。如果选择了错误的环境,可能会在项目后期引发问题,还可能导致开发人员疲劳和倦怠,仅仅是因为项目难以开展。
你认为我这里有遗漏的内容吗?你的团队有多遵循这些规则?你是否遇到过由于开发环境不符合这些规则而导致项目出现困难的情况?请留下评论,告诉我你的想法。


