Docker WordPress极度缓慢

23

我在Docker中安装了WordPress来进行本地开发,但速度非常缓慢。我的docker-compose.yml文件如下:

version: '3.3'

services:
  db:
    image: mysql:5.7
    volumes:
      - ./db_data:/var/lib/mysql
      - ./dbconfig.cnf:/etc/mysql/conf.d/custom.cnf
    restart: always
    ports:
      - "3308:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: wp_database
      MYSQL_USER: db_user
      MYSQL_PASSWORD: some_secure_password

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "80:80"
      - "443:443"
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content
      - ./.htaccess:/var/www/html/.htaccess
      - ./wp-config.php:/var/www/html/wp-config.php
      - ./logs/debug.log:/var/www/html/wp-content/debug.log
volumes:
  db_data: {}
  wp_content: {}
据我在线阅读的内容,可能是因为我挂载了wp-content卷的原因导致页面加载缓慢(例如,加载一个jquery文件需要约半秒钟,并且对于一个页面,它必须加载大量文件)。
是否有解决方法?我阅读过NFS的相关资料,但无法通过docker-compose配置NFS,总是出现“权限错误”。另一方面,macOS的Docker界面已经显示了一个“共享文件夹”选项卡,但我不知道是否正在使用这些共享文件夹或者只是再次挂载它们。
非常感谢任何帮助。
6个回答

12

TL;DR 将容器挂载到临时文件夹,使用Bindfs将该文件夹与公共服务器文件夹同步。 直接挂载WP站点很慢,因为容器必须逐个访问主机文件,这是一个重量级的过程。从公共文件夹提供服务,而文件直接成为容器的一部分,速度更快。

我在Docker Compose开发中遇到了完全相同的问题。无论你的电脑有多快,挂载容器中的文件仍然很慢。

我还尝试了像NFS和其他建议(如正确排除防病毒软件中的项目、添加.dockerignore等)的解决方案,但最多只能稍微改善性能。

在寻找类似速度提升的过程中,我发现了WordPress Starter存储库中的这个Dockerfile https://github.com/visiblevc/wordpress-starter/blob/cd7a3c4dc1dacdfb247fa6a86001cf6909734c87/Dockerfile。如果你查看这个文件,你会发现他们在容器中初始化和挂载项目的方式不是直接挂载到例如/var/www/html/,而是一个临时文件夹。然后他们通过bindfs将这个临时文件夹同步到/var/www/html/。这样,每当你在浏览器中加载WordPress页面时,它都会非常快,因为它不需要在每个请求上访问和读取主机文件。WordPress文件是Linux容器的一部分。当你更改代码时,这些更改将反映在容器临时文件夹中,并且bindfs将立即将这些更改同步到公共容器文件夹中,反之亦然。所有在公共文件夹上进行的更改都将同步到临时文件夹中,然后再同步到你的主机项目文件中。

13
那会是一个 404。 - Mac
3
你只需要回到过去,找到发布日期附近的存储库,就能找到@ArmanShahinyan建议的dockerfile:https://github.com/visiblevc/wordpress-starter/blob/cd7a3c4dc1dacdfb247fa6a86001cf6909734c87/Dockerfile - Mike Averto
1
感谢您指出正确的方向。但是我没有使用bindfs,因为它不太流行,而且我试图避免从未知来源获取太多依赖项。但是我找到了一个具有类似功能的程序,语法非常简单:lsyncd --rsync /source/path /target/path。虽然它不是双向的。 https://github.com/axkibe/lsyncd - FullStack Alex
1
通常 TL;DR 应该在您的帖子顶部,而不是底部。如果有人读完整个帖子然后在结尾处看到 TL;DR 部分,那么这并不太有帮助。此时,他们已经阅读了全部内容,不再需要 TL;DR 部分。 - Adam
我尝试将这个适应到我的nginx设置中,答案是不要这样做,只需克隆这个仓库并按照设置步骤进行即可。如果你想加快本地开发速度,绝对没有理由不使用这个仓库。这是我使用过的最快的docker/WordPress设置,比MAMP还要快。 - undefined
显示剩余3条评论

11
在Mac和Windows中,我们应该考虑一些卷性能问题
我在我的docker-compose.yml中做出了更改。
请注意,我已经将短语法转换为长语法
这种标记允许添加一致性选项
我添加了wp-contentphp-conf(以获取php.ini),因为它们是每次在浏览器中加载Wordpress页面时最频繁调用的文件目录。
services:
    wordpress:

        ...

        volumes:
            - ./data:/data
            - ./scripts:/docker-entrypoint-initwp.d
            #- ./wp-content:/app/wp-content
            - type: bind
              source: ./wp-content
              target: /app/wp-content
              consistency: cached
            #- ./php-conf:/usr/local/etc/php
            - type: bind
              source: ./php-conf
              target: /usr/local/etc/php
              consistency: cached

enter image description here


1
在 macOS 上没有任何更改 - John White

3

我也遇到了相同的问题,但是可能已经找到了解决方案。

在 Docker Desktop 应用程序中(位于顶部,看起来像一只鲸鱼)

打开设置。选择“资源” -> “文件共享”。

添加相关文件夹。我的MySQL和WordPress文件夹在同一个父文件夹中,因此添加了它们。

点击“应用并重启”。

这样我的网站速度明显加快了。

希望这可以帮到你。


完全没有帮助 :( 在我的情况下,负载时间仍然非常糟糕。您可以分享一些docker-compose.yml和/或Dockerfile的屏幕截图或代码片段吗? - FullStack Alex

3

如何解决程序运行缓慢的问题?

根据 Docker 最佳实践,性能会更高,如果从 Linux 文件系统绑定挂载文件,而不是从 Windows 主机远程访问。只有当原始文件存储在 Linux 文件系统中时,Linux 容器才会接收文件更改事件,“inotify 事件”,这有助于在文件更改时重新加载,而不是扫描所有文件。

使用的 docker-compse.yml 文件参考: https://www.hostinger.in/tutorials/run-docker-wordpress [根据需要更改版本,并在 wordpress 容器的卷部分应用以下修复方法]

1. 对于 Windows 上的 Docker,请在 docker-compose.yml 中使用以下代码:

volumes:
  ["~/{replace_with_a_wsl_dir/}:/var/www/html"]

2. 在Windows中创建Linux目录,用作上述代码中的卷主目录:

我们需要在Windows 10或11上运行Docker时使用WSL1或WSL2。 Windows子系统让开发人员运行GNU / Linux环境。

打开Windows命令提示符(windows> cmd),并输入以下命令以在Windows的Linux中创建一个目录

wsl
cd ~
mkdir wsl_dir
sudo chmod 777 ~/wsl_dir

我们需要从wsl本身运行docker compose,如果yml文件在Windows文件系统中,也不用担心,因为我们可以从wsl本身访问它。Windows文件系统将默认挂载在/mnt,您可以使用'ls /mnt'来检查。

cd /mnt/{windows_path_to_the_docker_compose_file}
docker compose up -d

干得好,你完成了!


谢谢!我的笔记:我们实际上是将文件添加到WSL Linux中的用户文件夹中: /home/yourname/website-folder整个重点是避免使用/mnt/c/...路径,这才是导致速度变慢的原因。我们正在WSL内部运行整个程序。你仍然可以在Windows资源管理器中访问这些文件,只需转到: \wsl.localhost\Ubuntu-22.04\home\yourname\website-folder (我正在使用Ubuntu,你可能需要根据你的发行版更改路径)而且你可以在Visual Studio Code中打开此文件夹,但它会询问你是否要使用特殊的WSL模式,所以选择是。 - Purple Tentacle
谢谢!我的笔记:我们实际上是将文件添加到WSL Linux中的用户文件夹中: /home/yourname/website-folder整个重点是避免使用/mnt/c/...路径,这是导致速度变慢的原因。我们正在WSL内部运行整个程序。你仍然可以在Windows资源管理器中访问这些文件,只需转到: \wsl.localhost\Ubuntu-22.04\home\yourname\website-folder (我正在使用Ubuntu,你可能需要更改路径以适应你的发行版)你也可以在Visual Studio Code中打开此文件夹,但它会询问你是否要使用特殊的WSL模式,所以选择是。 - undefined

2

我意识到,如果您缩小Docker查找运行网站的目录范围,它将运行得更快。例如,在Docker桌面设置中,/ Users是默认设置在“设置”>“资源”>“文件共享”中。如果您删除该资源,并仅将其缩小到您的网站所在的目录,则可以消除Docker的很多开销。

enter image description here


0

备注:我在使用 OS X 操作系统。我尝试了增加 Docker 分配的 RAM 和 CPU,以及将文件夹包含为资源,但仍然很慢。

我尽可能地改进了 Docker,并且对我最有帮助的是:

  1. 我必须确保不要将任何额外的文件加载到容器中。在我的项目中,由于某种原因,有人想要将当前的 $PWD 加载到容器中。移除它可以大大提高效率

  2. 我向 mysql volume 添加了 :delegated 标志。为什么要使用这个而不是 :cached 呢?因为我只是在本地开发,所以我不希望文件被缓存,否则我需要重新加载页面才能获取最新的更改。

然后,在这些改进之后,我的页面加载时间约为 1-3 分钟。几周过去了,我想到关闭所有涉及读取或写入数据库的 Wordpress 功能,这些功能在开发时并不必要,比如编辑时的自动保存和 wp-cron;这些都是生产环境下很好的功能,但是在开发时会做太多的工作,导致页面加载时间过长。这是我在 wp-config.php 文件中使用的语句,仅用于本地开发:

define( 'AUTOSAVE_INTERVAL', 60*60*60*24*365 ); // Set autosave interval to 1x per year
define( 'EMPTY_TRASH_DAYS',  0 ); // Empty trash now: Zero days
define( 'WP_POST_REVISIONS', false );
define( 'DISABLE_WP_CRON', true ); // sends an XHR request with timestamp to server on every page load which queries db for posts that may need to be published and does so; :gross:

希望这能帮助到某些人。在我看来,我不应该这样做,因为我可以很好地运行带有WordPress的MAMP/LAMP堆栈。我没有答案,为什么Docker和WordPress在我的操作系统上以及使用Docker桌面版时表现如此糟糕。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接