我真的很喜欢 Docker 和容器化的概念。我已经有一年多没有碰过我的 MAMP 开发设置了,几乎没有使用我的本地 PHP CLI。但是存在并且一直存在一个问题:性能。 Laravel 应用程序的响应时间为一秒,大型 Wordpress 堆栈的响应时间为 3-7 秒,这很常见。值得庆幸的是,这个问题有一个解决方案,不需要改变你的整个技术栈:docker-sync。

什么是 docker-sync?

Docker for Mac(和 Windows)性能问题的根源在于 Docker 和 OS 之间的 OS 文件系统层。在 Linux 上,Docker 可以直接从文件系统挂载文件和文件夹,而在 Mac 上,Docker 必须将请求传递给负责将文件写入磁盘的操作系统。对于 macOS,OSXFS 是房间里的大象。虽然这听起来没什么大不了的,但确实如此。如果您有 500 个需要读取的源文件,即使是一毫秒的差异也可能对您的整个应用程序堆积半秒。

值得庆幸的是,如果您将文件放入卷中,Docker 能够使用本机挂载,然后由 Linux 内核处理。这正是 docker-sync 所做的。它创建了一个存储所有应用程序源文件的卷,并使其可用于您的应用程序,该应用程序可以非常快速地读取和写入该卷。由于卷通常不绑定到外部世界(即您的文件系统),因此 docker-sync 实现了不同的工具来负责将容器内部与您的主机文件系统同步。这允许您在编辑器中编辑任何文件,它们会同步到卷中并且您的应用可以访问它。

docker-sync 基准测试

我对 docker-sync 进行了基准测试,因为我想查看硬数字而不是猜测请求是否更快。以下两个应用程序基于 Laravel 和 Wordpress,同时有来自 Bitnami](https://blog.kovah.de/en/5gw1x8-a-drop-in-docker-stack-for-php-app/)的[个图像用于运行两者。这里使用的主要指标是 TTFB,或 time to first byte,以毫秒为单位。我连续 10 次打开这两个应用程序的页面,没有特定的页面缓存。这两个应用程序都使用 PHP 7.3 运行。

应用程序

码头同步

最大限度

中位数

区别

拉拉维尔 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 版本(v2.3 目前随 macOS 一起提供)。要安装它,请运行以下命令:

gem install --user-install docker-sync
# or globally via
sudo gem install docker-sync

进入全屏模式 退出全屏模式

2\。将新的 docker-sync.yml 文件添加到您的项目中

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

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

进入全屏模式 退出全屏模式

首先,在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

进入全屏模式 退出全屏模式

该文件告诉 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 start

进入全屏模式 退出全屏模式

该命令将首先启动 docker-sync 来创建卷并准备使用,然后通过调用运行容器

docker-compose -f docker-compose.yml -f docker-compose-dev.yml up,它使用两个 docker-compose 配置文件启动 Docker Compose。

这里的缺点是,同步和 Docker 堆栈都将在前台运行。我个人不喜欢这种方式,因为您经常需要为一个应用程序打开多个终端窗口,但它又快又高效。

要停止堆栈,请按CMD+C

码头同步 + 码头组合

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

进入全屏模式 退出全屏模式

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

如何解决权限问题

如果你遇到像我这样的权限问题,Laravel 无法写入日志,Wordpress 无法存储上传,你可能需要指定另一个用户 ID。对于我当前使用 Bitnami 容器的 Docker 堆栈,我遇到了问题,因为 docker-sync be default 使用 root 用户存储所有文件,而 PHP FPM 以daemon用户身份运行。这将导致保存文件时发生冲突。为了防止这种情况,您必须将sync_userid: '1'添加到您的 docker-sync.yml 配置文件中,其中1是容器内守护程序用户的用户 ID。

添加该行后,所有问题立即消失,我能够使用该设置。

结论

运行完整的堆栈需要相当长的时间。我发现文档不是那么容易理解,但我能够通过查看项目维护者本身提供的各种示例来设置一个干净的堆栈。在花费额外的时间解决权限问题后,我能够使用 docker-sync 堆栈运行我的应用程序,并获得了巨大的生产力提升。现在页面加载速度如此之快,令人难以置信的是,这个小工具能带来多大的不同。

非常感谢维护者 Eugen Mayer 和所有贡献者发布了这个很棒的工具。


这篇文章最初发表于Blog.Kovah.de

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐