mcpField
D
drupal-ddev

drupal-ddev

github.com/grasmash开发82350 次安装4 周前更新
代码仓库

关于 drupal-ddev

drupal-ddev 是一项技能,介绍如何将 DDEV 用作 Drupal 项目的本地开发环境。内容涵盖环境配置、数据库工作流、调试、性能与恢复,并提供专题参考和故障排查指导。

主要功能

  1. 01配置 Drupal 项目的 DDEV 环境
  2. 02导入、导出和快照数据库
  3. 03使用 Drush 与 Xdebug
  4. 04设置本地 Solr 和自定义命令
  5. 05排查性能与恢复问题

适用场景

  1. 01搭建新的或现有的 Drupal 项目
  2. 02同步或快照项目数据库
  3. 03诊断缓慢或异常的 DDEV 环境
  4. 04配置调试工具或本地 Solr

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/grasmash/drupal-claude-skills --skill drupal-ddev

安装后在 Claude Code 中输入/drupal-ddev确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
config-yaml.md
custom-commands.md
database.md
load-and-recovery.md
performance.md
solr.md
workflows.md
xdebug.md

详细介绍

用 DDEV 进行 Drupal 开发

全面介绍如何将 DDEV 用作本地 Drupal 开发环境,包括设置、配置、工作流优化和故障排查。

此技能的触发条件

在使用 DDEV 进行本地开发时触发,包括:

  • DDEV 配置(.ddev/config.yaml)
  • 本地环境设置和管理
  • 数据库导入/导出操作
  • Drush 集成
  • Xdebug 和调试工具
  • 性能优化
  • 多站点和自定义命令

可用主题

核心设置
  • @references/config-yaml.md - .ddev/config.yaml 参考
  • @references/workflows.md - 新项目/导入项目设置、远程数据库同步、日常工作流、多项目管理
数据库操作
  • @references/database.md - 导入、导出和快照工作流
开发工具
  • @references/xdebug.md - 使用 Xdebug 调试
  • @references/solr.md - 本地 Solr 搜索设置
高级主题
  • @references/custom-commands.md - 创建项目专属命令
  • @references/performance.md - 优化 DDEV 性能
  • @references/load-and-recovery.md - 主机 CPU 饱和、崩溃后的恢复陷阱、缩减 Mutagen 负载、在临时数据库上运行 Kernel 测试、协调多个 Agent 在同一项目上工作

完整文档请参阅 /references/ 目录。

参考资料

任务需要相关细节时,请阅读对应文件;下方的“常见问题”部分保留在此处,因为几乎每次使用时都会用到。

文件适用场景
references/workflows.md设置新项目、导入现有项目、从远程环境同步数据库、遵循每日启动/停止流程、管理多个 DDEV 项目,或清理 Agent 的 git worktree 目录
references/performance.mdDDEV 在 macOS 上运行缓慢(Mutagen 与 NFS 的比较)、调整 MariaDB,或 PHPUnit/Kernel 运行缓慢(快速引导、最小测试范围、Kernel 测试套件的运行位置)
references/xdebug.md开启/关闭 Xdebug,或将 IDE(VSCode launch.json)连接到 Xdebug
references/custom-commands.md在 .ddev/commands/web/ 下编写项目专属的 ddev <command>
references/config-yaml.md编辑 .ddev/config.yaml,且超出下方基本示例所涵盖的范围(PHP、数据库、端口、主机名、钩子、服务、环境变量)
references/database.md导入、导出、创建快照、访问或清理数据库,或数据库导入失败
references/solr.md为 Search API 运行本地 Solr 服务
references/load-and-recovery.md主机负载过高时请求挂起、Docker 崩溃后、缩减 Mutagen 负载、针对临时数据库运行 Kernel 测试,或多个 Agent 共用一个 DDEV 项目

快速参考

必备命令
# Start project
ddev start

# Stop project
ddev stop

# Restart services
ddev restart

# SSH into web container
ddev ssh

# Run Drush commands
ddev drush cr
ddev drush status
ddev drush config:status

# Run Composer
ddev composer require drupal/module_name
ddev composer update

# Database operations
ddev import-db --file=backup.sql.gz
ddev export-db --file=backup.sql.gz
ddev snapshot

# View logs
ddev logs
ddev logs -f    # Follow mode

# Describe project
ddev describe

# Access URLs
ddev launch     # Open site in browser
基本的 .ddev/config.yaml
name: myproject
type: drupal11
docroot: web
php_version: "8.3"
webserver_type: nginx-fpm
database:
  type: mariadb
  version: "10.6"
nodejs_version: "24"

# Additional services
additional_services:
  - solr

# Custom upload/execution limits
upload_dirs:
  - web/sites/default/files

# Performance settings
performance_mode: mutagen  # For macOS

最佳实践

  1. 提交 .ddev/config.yaml - 与团队共享配置
  2. 使用 ddev composer,而不是本地 composer
  3. 不要提交数据库快照 - 文件太大
  4. 执行高风险操作前创建快照
  5. 不调试时禁用 Xdebug - 避免影响性能
  6. 在 macOS 上使用 mutagen - 文件同步速度快得多
  7. 定期运行 ddev poweroff - 释放系统资源
  8. 固定服务版本 - PHP、数据库、Node.js
  9. 使用钩子实现自动化 - 执行启动后任务
  10. 记录自定义命令 - 帮助团队成员

常见问题

站点无法加载
# Restart project
ddev restart

# Check status
ddev describe

# View logs
ddev logs

# Clear Drupal cache
ddev drush cr
数据库连接错误
# Check database is running
ddev describe

# Verify settings.php or settings.ddev.php exists
ddev ssh
ls web/sites/default/settings*.php
端口冲突
# Stop all DDEV projects
ddev poweroff

# Check for port conflicts
lsof -i :80 -i :443

# Change router HTTP port if needed
ddev config --router-http-port=8080 --router-https-port=8443
macOS 上性能缓慢
# Enable mutagen
ddev config --performance-mode=mutagen
ddev restart

# Or use NFS
ddev config --nfs-mount-enabled=true
ddev restart
Drush 中的 PHP 弃用警告

如果运行 Drush 命令时出现 PHP 弃用警告(尤其是在 PHP 8.4 中),请创建自定义 PHP 配置文件来屏蔽这些警告:

.ddev/php/drush.ini:

; Suppress PHP deprecation warnings for Drush commands
[PHP]
error_reporting = 22527
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /tmp/php-errors.log

然后重启 DDEV:

ddev restart

工作原理:

  • error_reporting = 22527 等同于 E_ALL & ~E_DEPRECATED
  • display_errors = Off 可防止警告显示在 STDERR 上
  • display_startup_errors = Off 可屏蔽引导阶段的警告
  • 错误会记录到 /tmp/php-errors.log,而不是直接显示

此配置同时适用于 Web 和 CLI 环境,因为 DDEV 会将 .ddev/php/*.ini 文件复制到 /etc/php/[version]/cli/conf.d/ 和 /etc/php/[version]/fpm/conf.d/。

中断的 ddev composer install 会留下幽灵安装包(补丁从未应用)

如果 ddev composer install/update 在运行中被终止(Docker 因 OOM 以状态码 137 退出、主机超时或崩溃),Composer 可能已在终止前将软件包记录为已安装,因此下一次运行 composer install 时会提示 “Nothing to install, update or remove”,而 composer-patches 也不会应用该软件包的补丁。结果是一个只完成部分构建的 contrib 目录树,导致看似不可能出现的运行时错误(例如 DI ServiceCircularReferenceException、因未打补丁的构造函数导致的 TypeError);修复目录树后,这些错误便不会再出现。

诊断:

# Verify patch application (a verify-patches script if your project has one,
# or spot-check a known-patched file in the vendored tree)
ddev composer install                # says "Nothing to install" despite the missing patches

修复——强制干净地重新安装受影响的软件包(重新应用其补丁):

ddev composer reinstall drupal/<pkg>

规则:在任何 Composer 运行中断后,都应将整个软件包目录树视为可疑。重新安装运行中被处理的软件包,重新验证补丁,然后再调试剩余错误——在目录树损坏期间看到的错误可能已经消失。检查错误日志的时间戳:在着手修复之前,确认致命错误现在仍可复现。

超时终止的 ddev drush 命令会遗留容器内进程

终止主机端的 ddev drush ... 进程(Ctrl-C、工具超时)并不会终止 Web 容器内的 PHP 进程。这些孤儿进程会不断累积、争抢 CPU,导致之后每次 Drush 引导都变得极其缓慢(drush cr/updb/updatedb:status 需要 10 分钟以上——看起来像是卡住,实际上是资源耗尽)。

诊断/清理:

ddev exec "ps aux | grep -v grep | grep -E 'vendor/bin/drush|php /var/www'"
ddev exec "pkill -f 'vendor/bin/drush'"

两个推论:

  1. 长时间运行的 Drush 操作(大型升级时的 updb、冷启动 cr)只运行一次,并在后台执行,设置充足的超时时间——不要反复尝试较短的运行时限;每次终止都会增加一个孤儿进程。
  2. “卡住后被终止”的 updb 可能已经完成了实际工作——更新钩子会逐个记录。重新运行或慌张之前,先检查实际执行了什么:
ddev mysql -e "SELECT value FROM key_value WHERE collection='system.schema' AND name='<module>'"
ddev mysql -N -e "SELECT value FROM key_value WHERE collection='post_update' AND name='existing_updates'" | grep -o "<module>_post_update_[a-z0-9_]*"
Docker Engine 卡死(对 DDEV 反复排查前先检查)

phpunit 以状态码 137 退出、后台任务在运行中死亡、ddev exec 再次触发完整的镜像重建,或每次 ddev start 都提示“container name already in use”——这些看起来像是 DDEV 的问题,但往往是仍驻留的应用进程使 Docker Desktop engine 崩溃所致。请先检查:

timeout 5 docker version   # hangs on the Server section -> engine is dead
docker ps                  # if this responds while `docker version` hangs, engine is wedged

修复:运行 killall -9 com.docker.backend && open -a Docker,轮询 docker ps 直到命令有响应,然后运行 ddev start。如果 engine 本身已停止,就不要继续尝试修复 ddev 层面的问题(poweroff/mutagen reset 等)——这些方法都无法奏效。重启后,留意孤儿容器和首次运行 Drush 缓慢的问题:崩溃后的陷阱。

主机 CPU 饱和(容器正常,但请求挂起)

主机负载远高于核心数;容器运行正常,且 php -v 会立即返回,但每个请求和 Drush 引导都挂起(php-fpm 工作进程阻塞在停滞的 virtiofs 桥接上,处于 request_wait_answer 状态)。在负载下降之前,任何 DDEV 恢复操作都无法解决问题——先降低负载,然后运行一次 ddev poweroff && ddev start。详情请参阅:load-and-recovery.md。

恢复后出现 404 和路由发现警告

恢复操作(Docker 重启、mutagen 重置、核心更新)后立即出现 404 和路由发现警告,且 ddev drush cr 无法修复,这通常是 APCu 中的编译容器过期:即使数据库中的 cache_container 是最新的,php-fpm 的操作码缓存仍保留着更改前的代码。修复方法:docker restart ddev-<project>-web(强制刷新 APCu)——不要再次清除缓存。

容器状态显示正常,但路由器 TLS 连接重置

即使 ddev describe 显示一切正常,且 docker ps 显示 ddev-router 运行正常,对 https://<project>.ddev.site 执行 curl 仍会立即失败并返回退出代码 35(TLS 握手期间“Connection reset by peer”)。应用本身没有问题——是路由器卡住了。

区分应用和路由器的问题(完全绕过路由器):

ddev exec "curl -s -o /dev/null -w '%{http_code}' http://localhost/<path>"

修复方法:

docker restart ddev-router
Docker Desktop overlay2 I/O 错误

如果 Docker Desktop 进入异常状态,产生 overlay2 或 containerd I/O 错误,例如:

Error response from daemon: error creating temporary lease: write /var/lib/desktop-containerd/daemon/io.containerd.metadata.v1.bolt/meta.db: input/output error
Error response from daemon: open /var/lib/docker/overlay2/...: input/output error

正常退出并重启 Docker Desktop 并不足以解决问题。必须强制退出所有 Docker 进程(通过“活动监视器”或运行 killall -9 Docker / killall -9 com.docker.hyperkit),然后重新启动 Docker Desktop。只有彻底强制退出才能清除损坏状态。

“readdirent bad message”变体:这表示虚拟机磁盘在容器元数据层面已损坏,并非暂时性的 overlay2 故障——反复运行 ddev start 无法修复。应隔离损坏容器的元数据目录,而不是反复重启(通过 nsenter 进入 alpine 容器,并将有问题的 /var/lib/docker/containers/<id> 目录移到一旁)。

容器运行不正常 / Mutagen 同步卡住

Docker 崩溃或被强制退出后,DDEV 可能进入异常状态,出现以下情况:

  • ddev start 卡在“Starting Mutagen sync process...”
  • Web 容器报告运行不正常(phpstatus:FAILED、mailpit:FAILED)
  • ddev mutagen reset 失败并显示“CreateOrResumeMutagenSync Failure”

修复方法(按顺序运行):

# 1. Full power off to clean up all containers and networks
ddev poweroff

# 2. Start fresh
ddev start

如果 ddev poweroff 未能解决问题:

# 1. Stop DDEV
ddev stop

# 2. Reset the Mutagen daemon
~/.ddev/bin/mutagen daemon stop
~/.ddev/bin/mutagen daemon start

# 3. Reset Mutagen sync (removes Docker volume, forces full resync)
ddev mutagen reset

# 4. Start fresh
ddev start

排查问题时使用的监控命令:

ddev mutagen status -l      # Detailed sync status
ddev mutagen monitor        # Real-time sync progress
docker inspect --format "{{ json .State.Health }}" ddev-<project>-web  # Container health
磁盘用量:不要相信 ls 或 du

ls -la 报告的是稀疏文件(例如 Docker.raw)的逻辑大小,可能远大于磁盘上的实际占用空间;由于会重复计算快照之间共享的写时复制克隆,du 在 APFS 上会高估用量。这两个命令都无法回答“此操作实际上会占用或释放多少空间”。只相信操作前后立即获取的 df 差值。


相关技能

  • @drupal-config-mgmt - 配置管理工作流
  • @drupal-contrib-mgmt - 使用 Composer 管理模块
  • @drupal-at-your-fingertips - Drupal 通用模式

官方文档:https://ddev.readthedocs.io Drupal DDEV 快速入门:https://ddev.readthedocs.io/en/stable/users/quickstart/ 社区支持:https://discord.gg/5wjP76mBJD

评论

支持 Markdown