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

使用 docker-sync 将 Docker for Mac 的响应时间缩短一半

使用 docker-sync 将 Docker for Mac 的响应时间缩短一半

我真的很喜欢 Docker 和容器化的概念。我的 MAMP 开发环境已经一年多没动过了,本地的 PHP 命令行界面也几乎不用了。但是,性能问题一直存在。Laravel 应用的响应时间通常只有一秒,而规模较大的 WordPress 应用的响应时间也只有 3-7 秒。幸运的是,这个问题有一个解决方案,而且不需要你更换整个技术栈:docker-sync。

什么是 docker-sync?

Docker for Mac(以及 Windows)的性能问题根源在于 Docker 和操作系统之间的文件系统层。在 Linux 系统上,Docker 可以直接挂载文件系统中的文件和文件夹,而在 Mac 系统上,Docker 必须将请求传递给操作系统,由操作系统负责将文件写入磁盘。对于 macOS 而言,OSXFS 文件系统就是一个显而易见的缺陷。虽然这听起来似乎无关紧要,但实际上影响巨大。即使只有一毫秒的延迟,如果你的应用程序需要读取 500 个源文件,累积起来也会造成半秒的延迟。

幸运的是,如果你将文件放入卷中,Docker 可以使用原生挂载功能,这些卷由 Linux 内核处理。而这正是 docker-sync 的工作原理。它会创建一个卷来存放所有应用程序的源文件,并使其可供应用程序访问,应用程序可以快速地读写该卷。由于卷通常不与外部世界(即你的文件系统)绑定,docker-sync 实现了不同的工具来负责将容器内部与主机文件系统同步。这样,你就可以在编辑器中编辑任何文件,这些文件都会同步到卷中,你的应用程序可以访问它们。

docker-sync 基准测试

我对 docker-sync 进行了基准测试,因为我想查看具体的数值,而不是猜测请求速度是否更快。以下两个应用程序分别基于 Laravel 和 WordPress,并且都使用了Bitnami 的镜像来运行。这里使用的主要指标是 TTFB(首字节到达时间),单位为毫秒。我连续打开这两个应用程序的页面 10 次,没有启用任何页面缓存。两个应用程序都运行在 PHP 7.3 版本上。

应用程序 docker-sync 最大限度 中位数 不同之处
Laravel 5.8 离开 1035毫秒 2158毫秒 1386毫秒
234毫秒 303毫秒 251毫秒 -81%
WordPress 5.2 离开 2467毫秒 3942毫秒 2722毫秒
881毫秒 1589毫秒 1271毫秒 -53%

如何使用 docker-sync

我敢肯定你已经上瘾了,对吧?响应时间最多能缩短 80%,听起来确实有点不可思议,但……这是真的。那么,我们现在该如何设置 docker-sync 呢?

1. 安装该工具

docker-sync 是用 Ruby 编写的,因此即使您的 Ruby 版本没有升级(目前 macOS 自带的是 v2.3),也可以轻松安装。要安装它,请运行以下命令:

gem install --user-install docker-sync
# or globally via
sudo gem install docker-sync
Enter fullscreen mode Exit fullscreen mode

2. 向项目中添加一个新的 docker-sync.yml 文件

此配置文件告诉 docker-sync 要存储和同步哪些文件、使用哪些模式等等。以下是一个基本配置文件,您可以直接将其放入根文件夹:

version: "2"
syncs:
  your-app-files:
    notify_terminal: true
    src: './'
    sync_excludes: ['.git', '.idea', 'node_modules']
Enter fullscreen mode Exit fullscreen mode

首先,在syncs选项中,您可以指定要创建的卷。请注意,卷的名称(your-app-files此处)在您的整台机器上必须是唯一的。该src选项定义了默认情况下应复制到卷中的文件,您可以使用该sync_excludes选项排除特定的目录或文件。我在这里排除了 Git、PhpStorm 和 node_modules 文件夹。Git 和 IDE 文件夹与应用程序本身无关,因此容器中不需要它们。排除 node_modules 文件夹是因为它们对于常规 PHP 应用程序也不需要,因此可以删除,尤其是在同步 4596895 个文件和文件夹可能需要很长时间的情况下……

您可以在官方文档中找到有关卷的其他配置参数。

3. 添加 docker-compose-dev.yml 文件

当前版本的 Docker Compose 允许您覆盖先前 docker-compose.yml 文件中的某些配置。这非常方便,因为我们可以直接使用当前的 docker-compose.yml 文件,无需任何修改。如果您暂时不想使用 docker-sync,也可以使用常规docker-compose up命令启动应用程序。

以下是我使用的示例文件:

version: "2"
services:

  php:
    volumes:
      - your-app-files:/app:nocopy

  nginx:
    volumes:
      - your-app-files:/app:nocopy

volumes:
  your-app-files:
    external: true
Enter fullscreen mode Exit fullscreen mode

这个文件告诉 Docker Compose 不要使用 docker-compose.yml 文件中的常规挂载点,而是将your-app-files卷挂载到容器中。请注意,您必须将卷添加到所有需要访问这些文件的容器中,在本例中包括 PHP 和 nginx 容器。基本就是这样。

4. 启动 docker-sync 堆栈

实际上有两种方法可以使用 docker-sync 启动堆栈:

  1. 通过使用docker-sync-stack
  2. 通过使用docker-syncdocker-compose

docker-sync-stack

docker-sync-stack start
Enter fullscreen mode Exit fullscreen mode

这条命令首先会启动 docker-sync,它会创建卷并做好使用准备,然后通过调用 `docker run` 命令运行容器
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up,该命令会启动 Docker Compose 并使用两个 docker-compose 配置文件。

缺点是,同步和 Docker 堆栈都会在前台运行。我个人不喜欢这样,因为你需要不断地为同一个应用程序打开多个终端窗口,但它的确快速高效。

要停止堆栈,请按CMD+ C

docker-sync + docker-compose

docker-sync start
# wait until the command finishes creating the volume, then:
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -d
Enter fullscreen mode Exit fullscreen mode

这是我目前使用的方法,以后可能会为此编写一个 bash 函数或别名。您可以继续在终端中工作,我推荐使用Kitematic来快速查看容器日志。(附注:Kitematic 已内置于 Docker for Mac 安装包中。)

如何解决权限问题

如果你也像我一样遇到权限问题,比如 Laravel 无法写入日志,WordPress 无法存储上传文件,那么你可能需要指定另一个用户 ID。在我目前使用 Bitnami 容器的 Docker 环境中,我遇到了一个问题:docker-sync 默认使用 root 用户存储所有文件,而 PHP FPM 运行在普通daemon用户下。这会导致文件保存时发生冲突。为了避免这种情况,你需要sync_userid: '1'在 docker-sync.yml 配置文件中添加一行,其中 ` 1<userID>` 是容器内守护进程用户的用户 ID。

添加这行代码后,所有问题都立即消失了,我可以正常使用这个配置了。

结论

搭建完整的堆栈花了我不少时间。我觉得文档不太容易理解,不过通过研究项目维护者提供的各种示例,我最终还是搭建了一个干净的堆栈。在又花了几个小时解决权限问题后,我终于能够使用 docker-sync 堆栈运行我的应用程序,工作效率也得到了极大的提升。现在页面加载速度飞快,这个小工具带来的改变真是令人难以置信。

非常感谢维护者 Eugen Mayer 和所有贡献者,感谢他们发布了这款出色的工具。


本文最初发表于Blog.Kovah.de

文章来源:https://dev.to/kovah/cut-your-docker-for-mac-response-times-in-half-with-docker-sync-1e8j