发布于 2026-01-06 0 阅读
0

通过移动 vendor 目录加速 Docker 中的 Laravel DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

通过移动 vendor 目录来加速 Docker 中的 Laravel

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

我正在我的 MacBook Pro 上使用 Docker 构建一个 Laravel 应用,方法是将项目文件夹挂载到 Docker 容器中。我当时正在开发应用中的一个 API 端点,它的响应时间略超过一秒。这导致连接的 React 应用的交互体验非常缓慢。

本文将向您展示如何在 MacOS 和 Windows 上开发时,通过将 Composer 的 vendor 目录移动到容器内部来提高容器化 Laravel 应用程序的速度。

为什么 Laravel 在 Docker 中运行缓慢

造成性能缓慢的原因有两个,分别是 PHP 请求模型和 Docker Desktop 的 Linux 虚拟机与主机 MacOS 机器之间传输数据时的延迟。

当 PHP 收到请求时,它会逐个加载所有依赖项。请求完成后,它会丢弃所有已加载的数据。这与 Node.js 等框架不同,Node.js 由单个线程处理所有请求,并且每个模块在首次加载时都会被缓存。

与Node相比,PHP加载依赖项的方式效率已经很低了。而且,当你在非Linux机器上进行Docker开发时,每次加载依赖项文件,都需要在Docker Desktop的Linux虚拟机和挂载的主机文件夹之间进行交互,这会增加额外的开销。这就像把书从一个书架搬到另一个书架,和把书搬到街对面房子里的书架之间的区别一样。

为了保持 Docker 的运行速度,我们需要尽量减少 Docker Desktop 的 Linux 虚拟机与宿主机之间的数据传输次数。我们可以通过将 Composervendor/文件夹存储在容器内部,而不是挂载的项目目录中来实现这一点。

移动供应商目录

在本文的剩余部分,我们将假设您有一个容器,您的应用程序就存储在其中/srv/app/。我们将在容器中安装 Composer 依赖项/srv/vendor/

RUN在 Dockerfile 中,我们将使用以下命令安装 Composer 依赖项:

# ...previous Dockerfile commands
WORKDIR /srv/app
COPY . .
RUN COMPOSER_VENDOR_DIR="/srv/vendor" composer install
Enter fullscreen mode Exit fullscreen mode

这将把 Composer 依赖项安装到该/srv/vendor目录中,但 Laravel 无法找到它们:它期望依赖项位于项目根vendor/目录中。我们必须更新 Laravel 加载 Composer 自动加载文件的位置。

public/index.php和 中artisan,找到以下行:

require __DIR__.'/vendor/autoload.php';
Enter fullscreen mode Exit fullscreen mode

并将其替换为:

require __DIR__.'/../vendor/autoload.php';
Enter fullscreen mode Exit fullscreen mode

同时更新路径phpunit.xml

运行docker build(或者docker-compose build如果您使用 Compose),然后重新启动容器。当您在浏览器中访问 Laravel 项目时,应该会发现页面加载速度明显提升。在我的项目中,API 请求时间从大约 1000 毫秒降至大约 200 毫秒。

Gotchcas

页面加载速度更快固然不错,但如果您使用 IntelliSense 和自动完成功能,您肯定希望将依赖项放在已挂载的项目目录中,以便编辑器能够识别它们。

在 Laravel 容器运行时,您可以通过在主机上运行以下命令,将 Composer 依赖项安装到已挂载的项目目录中:

docker exec your-container-name composer install
Enter fullscreen mode Exit fullscreen mode

使用该composer require命令安装新依赖项时,可能会出现另一个“陷阱”。您有时可能会遇到如下错误:

Class "Laravel\Breeze\BreezeServiceProvider" not found  

Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
Enter fullscreen mode Exit fullscreen mode

出现此错误的原因是,安装完成后,它会尝试加载 Laravel 应用——而 Laravel 应用会访问vendor/容器内部的文件夹。安装依赖项时,最好运行composer require两次命令:一次针对容器内的 vendor 文件夹,一次针对与主机共享的目录。

# Install in the container first
COMPOSER_VENDOR_DIR="/srv/vendor" composer require [package-name]

# Then install in the directory shared with your host
composer require [package-name]
Enter fullscreen mode Exit fullscreen mode

之后可能还需要重新构建镜像:如果您使用的是 Docker Compose,那么一旦停止容器,您的更改将不会保留。

延伸阅读

除了将依赖项移到容器中之外,你还可以启用 PHP 的 OpCache 来进一步加快 Laravel 的加载速度。Kristoffer Högberg 写了一篇简明扼要的文章,介绍了如何做到这一点

Michaël Perrin 写了一篇题为“三种方法让你的 Symfony 应用更快地运行 Docker for Mac”的文章,其中包含一些优化前后的性能对比数据,非常有趣。本文的灵感就来源于 Michaël 的文章,绝对值得一读。

另外,也有人提到,使用Octane或许可以完全避免这些与 Docker 相关的性能问题,所以如果您需要最佳性能,也可以考虑一下 Octane。


附录

我使用这种设置已经大约十天了,我觉得有必要发出一个明确而明确的警告:移动你的供应商文件夹会导致问题

这种配置导致php artisan test我的持续集成(CI)系统完全停止工作。在这种配置下运行 xdebug 几乎无法使用。我正在积极解决这些问题,以便享受性能提升带来的好处,但如果您使用此配置,将会遇到问题。不过,您或许仍然认为这些权衡是值得的。

文章来源:https://dev.to/tylerlwsmith/speed-up-laravel-in-docker-by-moving-vendor-directory-19b9