由于提供的答案仅适用于 macOSX,但适用于 Windows 的 Docker 也存在性能问题,并且首选答案对我的情况没有帮助。我在 SO 上对类似问题的回答中部分描述了不同的方法。
根据 Performance Best Practices Symfony 应用程序中负载较重的文件夹(例如 vendor 和 var)不应成为共享挂载的一部分。如果您需要保留这些文件夹,您应该改用卷。
为了防止干扰 /app 中的共享卷,我将这两个文件夹重新定位到容器中的单独文件夹 /symfony。在 Dockerfile 文件夹中还创建了 /symfony/var 和 /symfony/vendor。
在容器启动时运行的脚本将符号链接设置为从 /app/var 到 /symfony/var 和从 /app/vendor 到 /symfony/vendor。然后将这两个新文件夹安装到卷,例如在docker-compose.yml 文件中。
这是我添加到我的 Dockerfile 的内容:
RUN mkdir /app && mkdir /symfony/{var,vendor}
COPY setup-symfony.sh /setup-symfony.sh
VOLUME /symfony/var
VOLUME /symfony/vendor
这是我在调用composer update 或通过bin/console 执行任何任务之前添加到我的启动脚本中的内容:
[ -e /app/var ] || ln -s /symfony/var /app/var
[ -e /app/vendor ] || ln -s /symfony/vendor /app/vendor
这就是我的作文最终的样子:
version: "3.5"
services:
database:
build:
context: docker/mysql
volumes:
- "dbdata:/var/lib/mysql"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
application:
depends_on:
- database
build:
context: docker/lamps
ports:
- "8000:8000"
volumes:
- ".:/app:cached"
- "var:/symfony/var"
- "vendor:/symfony/vendor"
environment:
DATABASE_URL: mysql://dbuser:dbuser@database/dbname
volumes:
dbdata:
var:
vendor:
使用这种设置,Symfony 会在 500 毫秒内做出响应,而不是 4000 毫秒甚至更多。
更新:在使用 IDE 开发基于 Symfony 的应用程序(如 PhpStorm)时,您可能需要 vendor/ 中的文件来进行代码辅助或类似操作。在我的情况下,我能够拍摄这些文件的快照并将它们放入另一个文件夹中,该文件夹也与主机共享,但 Symfony/PSR 并未积极使用,例如vendor.dis/。此快照在每次安装/升级时手动拍摄一次,例如通过像这样使用 shell 进入正在运行的容器:
docker exec -it IDofContainer /bin/sh
然后在shell中调用
cp -Lr vendor vendor.dis
也许您必须修复路径名或确保先切换到包含您的应用的文件夹。
在我使用 PhpStorm 的情况下,vendor.dis/ 被后台索引拾取并通过代码检查和代码辅助来遵守。 Visual Studio 代码存在与 git 相关的大量未跟踪更改的问题,因此我必须明确地让 git 忽略此快照,并将其名称添加到 .gitignore 文件中。
2020 年更新: 更新的设置可能会在访问 /symfony/templates 或 /symfony/public 等文件夹时出现问题,例如关于预热缓存。这显然是由于上述重定位导致在/symfony/vendor 中存在的自动加载代码中使用了相对文件夹。作为一个选项,您可以直接在/app/var 和/app/vendor 中挂载额外的卷,而不是/symfony/var 和/symfony/vendor。在 /app/var.dis 和 /app/vendor.dis 中创建这些文件夹的深层副本会继续在主机文件系统中启用代码辅助和检查。