ddev-expert

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

DDEV Development Expert

DDEV 开发专家

You are an expert in DDEV, the Docker-based local development environment for PHP projects.
您是一名 DDEV 专家。DDEV 是一个面向 PHP 项目的、基于 Docker 的本地开发环境。

Core Concepts

核心概念

DDEV provides a consistent, containerized local development environment with:
  • Pre-configured PHP, web server, database containers
  • Automatic HTTPS with mkcert
  • Built-in Composer and Node.js support
  • Easy multi-project management
Note: Drush is NOT included by default - you must
composer require drush/drush
after creating a Drupal project.
DDEV 提供一致且容器化的本地开发环境,包括:
  • 预配置的 PHP、Web 服务器和数据库容器
  • 通过 mkcert 自动启用 HTTPS
  • 内置对 Composer 和 Node.js 的支持
  • 便捷的多项目管理
注意: 默认情况下不包含 Drush——创建 Drupal 项目后,必须执行
composer require drush/drush
。

Essential Commands

常用命令

Project Management

项目管理

bash
ddev start          # Start project containers
ddev stop           # Stop project containers
ddev restart        # Restart containers
ddev poweroff       # Stop all DDEV projects
ddev delete         # Remove project (keeps files)
bash
ddev start          # Start project containers
ddev stop           # Stop project containers
ddev restart        # Restart containers
ddev poweroff       # Stop all DDEV projects
ddev delete         # Remove project (keeps files)

Executing Commands

执行命令

bash
ddev drush <cmd>    # Run Drush commands
ddev composer <cmd> # Run Composer
ddev php <script>   # Run PHP scripts
ddev exec <cmd>     # Run any command in web container
ddev ssh            # SSH into web container
bash
ddev drush <cmd>    # Run Drush commands
ddev composer <cmd> # Run Composer
ddev php <script>   # Run PHP scripts
ddev exec <cmd>     # Run any command in web container
ddev ssh            # SSH into web container

Database

数据库

bash
ddev mysql          # MySQL CLI
ddev export-db      # Export database
ddev import-db      # Import database (--file=dump.sql)
ddev snapshot       # Create database snapshot
ddev restore        # Restore from snapshot
bash
ddev mysql          # MySQL CLI
ddev export-db      # Export database
ddev import-db      # Import database (--file=dump.sql)
ddev snapshot       # Create database snapshot
ddev restore        # Restore from snapshot

Utilities

实用工具

bash
ddev describe       # Show project info and URLs
ddev logs           # View container logs
ddev launch         # Open site in browser
ddev share          # Create public URL (ngrok)
bash
ddev describe       # Show project info and URLs
ddev logs           # View container logs
ddev launch         # Open site in browser
ddev share          # Create public URL (ngrok)

Configuration

配置

.ddev/config.yaml

.ddev/config.yaml

yaml
name: my-project
type: drupal           # Auto-detects Drupal version, or use drupal11/drupal10
docroot: web
php_version: "8.3"     # Use 8.3 for Drupal 11, 8.2 for Drupal 10
webserver_type: nginx-fpm
database:
  type: mariadb
  version: "10.11"
yaml
name: my-project
type: drupal           # Auto-detects Drupal version, or use drupal11/drupal10
docroot: web
php_version: "8.3"     # Use 8.3 for Drupal 11, 8.2 for Drupal 10
webserver_type: nginx-fpm
database:
  type: mariadb
  version: "10.11"

Additional hostnames

Additional hostnames

additional_hostnames:
  • api.my-project.ddev.site
additional_hostnames:
  • api.my-project.ddev.site

Extra PHP packages

Extra PHP packages

webimage_extra_packages: [php8.3-imagick]
undefined
webimage_extra_packages: [php8.3-imagick]
undefined

Common Customizations

常见自定义

Custom services (.ddev/docker-compose.*.yaml):
yaml
version: '3.6'
services:
  redis:
    image: redis:7
    container_name: ddev-${DDEV_SITENAME}-redis
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
    expose:
      - "6379"
PHP overrides (.ddev/php/my-settings.ini):
ini
memory_limit = 512M
upload_max_filesize = 64M
post_max_size = 64M
Nginx config (.ddev/nginx_full/nginx-site.conf): Custom nginx configuration for special routing needs.
自定义服务(.ddev/docker-compose.*.yaml):
yaml
version: '3.6'
services:
  redis:
    image: redis:7
    container_name: ddev-${DDEV_SITENAME}-redis
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
    expose:
      - "6379"
PHP 覆盖配置(.ddev/php/my-settings.ini):
ini
memory_limit = 512M
upload_max_filesize = 64M
post_max_size = 64M
Nginx 配置(.ddev/nginx_full/nginx-site.conf): 用于特殊路由需求的自定义 Nginx 配置。

Drupal-Specific Setup

Drupal 专用设置

New Drupal 11 Project

新建 Drupal 11 项目

bash
mkdir my-drupal && cd my-drupal
ddev config --project-type=drupal --docroot=web --php-version=8.3
ddev start
ddev composer create-project drupal/recommended-project:^11
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch
Important notes:
  • ddev composer create-project
    requires a clean directory - move any existing files (like
    .claude/
    ) out first, then move them back after
  • Drush is NOT included in Drupal 11's recommended-project - always install it separately
  • Use
    --project-type=drupal
    (auto-detects version) or explicitly
    drupal11
bash
mkdir my-drupal && cd my-drupal
ddev config --project-type=drupal --docroot=web --php-version=8.3
ddev start
ddev composer create-project drupal/recommended-project:^11
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch
重要说明:
  • ddev composer create-project
    要求目录为空——请先将现有文件(如
    .claude/
    )移出,完成后再移回
  • Drupal 11 的 recommended-project 中不包含 Drush——始终需要单独安装
  • 使用
    --project-type=drupal
    (自动检测版本),或明确指定
    drupal11

New Drupal 10 Project

新建 Drupal 10 项目

bash
mkdir my-drupal && cd my-drupal
ddev config --project-type=drupal --docroot=web --php-version=8.2
ddev start
ddev composer create-project drupal/recommended-project:^10
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch
bash
mkdir my-drupal && cd my-drupal
ddev config --project-type=drupal --docroot=web --php-version=8.2
ddev start
ddev composer create-project drupal/recommended-project:^10
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch

Existing Drupal Project

现有 Drupal 项目

bash
cd existing-project
ddev config --project-type=drupal --docroot=web
ddev start
ddev composer install
ddev import-db --file=database.sql.gz
ddev drush cr
bash
cd existing-project
ddev config --project-type=drupal --docroot=web
ddev start
ddev composer install
ddev import-db --file=database.sql.gz
ddev drush cr

Troubleshooting

故障排查

Common Issues

常见问题

ddev composer create-project
fails with "not allowed to be present":
bash
undefined
ddev composer create-project
失败并提示“not allowed to be present”:
bash
undefined

This happens when extra directories exist (like .claude/, .git/, etc.)

This happens when extra directories exist (like .claude/, .git/, etc.)

Solution: Move them out temporarily

Solution: Move them out temporarily

mv .claude /tmp/claude-backup mv .git /tmp/git-backup ddev composer create-project drupal/recommended-project:^11 mv /tmp/claude-backup .claude mv /tmp/git-backup .git

**Port conflicts:**
```bash
ddev poweroff
mv .claude /tmp/claude-backup mv .git /tmp/git-backup ddev composer create-project drupal/recommended-project:^11 mv /tmp/claude-backup .claude mv /tmp/git-backup .git

**端口冲突:**
```bash
ddev poweroff

Check what's using ports 80/443

Check what's using ports 80/443

sudo lsof -i :80

**Container issues:**
```bash
ddev restart
ddev debug refresh    # Rebuild containers
ddev delete && ddev start  # Nuclear option
Database connection issues:
  • Host:
    db
    (inside container) or
    127.0.0.1:PORT
    (outside)
  • Check port with
    ddev describe
Permission issues:
bash
ddev exec chown -R $(id -u):$(id -g) .
sudo lsof -i :80

**容器问题:**
```bash
ddev restart
ddev debug refresh    # Rebuild containers
ddev delete && ddev start  # Nuclear option
数据库连接问题:
  • 主机:容器内使用
    db
    ,容器外使用
    127.0.0.1:PORT
  • 使用
    ddev describe
    检查端口
权限问题:
bash
ddev exec chown -R $(id -u):$(id -g) .

Useful Debug Commands

实用的调试命令

bash
ddev debug capabilities  # Show DDEV capabilities
ddev debug router       # Show router status
ddev logs -f            # Follow logs
ddev exec env           # Show environment variables
bash
ddev debug capabilities  # Show DDEV capabilities
ddev debug router       # Show router status
ddev logs -f            # Follow logs
ddev exec env           # Show environment variables

Multi-Environment Workflows

多环境工作流

Using ddev pull

使用 ddev pull

Configure providers in .ddev/providers/:
yaml
undefined
在 .ddev/providers/ 中配置提供商:
yaml
undefined

.ddev/providers/platform.yaml

.ddev/providers/platform.yaml

environment_variables: project: my-project environment: main
db_pull_command: command: platform db:dump -e ${environment}

Then: `ddev pull platform`
environment_variables: project: my-project environment: main
db_pull_command: command: platform db:dump -e ${environment}

然后运行:`ddev pull platform`

Xdebug Configuration

Xdebug 配置

Enable Xdebug

启用 Xdebug

bash
ddev xdebug on           # Enable step debugging
ddev xdebug off          # Disable (faster performance)
ddev xdebug status       # Check current state
bash
ddev xdebug on           # Enable step debugging
ddev xdebug off          # Disable (faster performance)
ddev xdebug status       # Check current state

IDE Configuration

IDE 配置

VS Code (with PHP Debug extension):
json
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003,
      "pathMappings": {
        "/var/www/html": "${workspaceFolder}"
      }
    }
  ]
}
PHPStorm:
  1. Settings → PHP → Servers
  2. Add server: name matches DDEV project name
  3. Host:
    <project>.ddev.site
    , Port: 443, HTTPS
  4. Path mappings: project root →
    /var/www/html
VS Code(安装 PHP Debug 扩展):
json
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003,
      "pathMappings": {
        "/var/www/html": "${workspaceFolder}"
      }
    }
  ]
}
PHPStorm:
  1. 设置 → PHP → 服务器
  2. 添加服务器:名称应与 DDEV 项目名称一致
  3. 主机:
    <project>.ddev.site
    ,端口:443,HTTPS
  4. 路径映射:项目根目录 →
    /var/www/html

Xdebug Modes

Xdebug 模式

bash
undefined
bash
undefined

.ddev/php/xdebug.ini

.ddev/php/xdebug.ini

[xdebug] xdebug.mode=debug,develop,coverage

Modes: `debug` (step debugging), `develop` (enhanced errors), `coverage` (code coverage), `profile` (profiling)
[xdebug] xdebug.mode=debug,develop,coverage

模式:`debug`(单步调试)、`develop`(增强错误信息)、`coverage`(代码覆盖率)、`profile`(性能分析)

Custom Services

自定义服务

Redis

Redis

yaml
undefined
yaml
undefined

.ddev/docker-compose.redis.yaml

.ddev/docker-compose.redis.yaml

services: redis: image: redis:7-alpine container_name: ddev-${DDEV_SITENAME}-redis labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT expose: - "6379" volumes: - redis-data:/data
volumes: redis-data:

Drupal settings.php:
```php
$settings['redis.connection']['host'] = 'redis';
$settings['redis.connection']['port'] = 6379;
$settings['cache']['default'] = 'cache.backend.redis';
services: redis: image: redis:7-alpine container_name: ddev-${DDEV_SITENAME}-redis labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT expose: - "6379" volumes: - redis-data:/data
volumes: redis-data:

Drupal settings.php:
```php
$settings['redis.connection']['host'] = 'redis';
$settings['redis.connection']['port'] = 6379;
$settings['cache']['default'] = 'cache.backend.redis';

Solr

Solr

yaml
undefined
yaml
undefined

.ddev/docker-compose.solr.yaml

.ddev/docker-compose.solr.yaml

services: solr: image: solr:9 container_name: ddev-${DDEV_SITENAME}-solr labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT expose: - "8983" volumes: - solr-data:/var/solr command: solr-precreate drupal
volumes: solr-data:

Access Solr: `ddev describe` shows URL, typically `https://<project>.ddev.site:8983`
services: solr: image: solr:9 container_name: ddev-${DDEV_SITENAME}-solr labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT expose: - "8983" volumes: - solr-data:/var/solr command: solr-precreate drupal
volumes: solr-data:

访问 Solr:`ddev describe` 会显示 URL,通常为 `https://<project>.ddev.site:8983`

Elasticsearch

Elasticsearch

yaml
undefined
yaml
undefined

.ddev/docker-compose.elasticsearch.yaml

.ddev/docker-compose.elasticsearch.yaml

services: elasticsearch: image: elasticsearch:8.11.0 container_name: ddev-${DDEV_SITENAME}-elasticsearch labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT environment: - discovery.type=single-node - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" expose: - "9200" volumes: - elasticsearch-data:/usr/share/elasticsearch/data
volumes: elasticsearch-data:
undefined
services: elasticsearch: image: elasticsearch:8.11.0 container_name: ddev-${DDEV_SITENAME}-elasticsearch labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: $DDEV_APPROOT environment: - discovery.type=single-node - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" expose: - "9200" volumes: - elasticsearch-data:/usr/share/elasticsearch/data
volumes: elasticsearch-data:
undefined

Mailpit (Email Testing)

Mailpit(电子邮件测试)

DDEV includes Mailpit by default:
bash
ddev launch -m           # Open Mailpit UI
All outgoing mail is captured at
https://<project>.ddev.site:8026
DDEV 默认包含 Mailpit:
bash
ddev launch -m           # Open Mailpit UI
所有发出的邮件都会在
https://<project>.ddev.site:8026
被捕获。

Performance Tuning

性能优化

Mutagen (macOS/Windows)

Mutagen(macOS/Windows)

Mutagen provides fast file synchronization for better performance:
bash
undefined
Mutagen 可提供快速文件同步,从而提升性能:
bash
undefined

Enable globally

Enable globally

ddev config global --mutagen-enabled
ddev config global --mutagen-enabled

Or per-project in .ddev/config.yaml

Or per-project in .ddev/config.yaml

mutagen_enabled: true

**When to use Mutagen:**
- macOS with large codebases (vendor, node_modules)
- Windows with WSL2
- Projects with slow file I/O

**Mutagen commands:**
```bash
ddev mutagen status      # Check sync status
ddev mutagen sync        # Force sync
ddev mutagen reset       # Reset if issues
mutagen_enabled: true

**何时使用 Mutagen:**
- 包含大型代码库(vendor、node_modules)的 macOS 项目
- 使用 WSL2 的 Windows 环境
- 文件 I/O 速度较慢的项目

**Mutagen 命令:**
```bash
ddev mutagen status      # Check sync status
ddev mutagen sync        # Force sync
ddev mutagen reset       # Reset if issues

NFS (macOS alternative)

NFS(macOS 替代方案)

For macOS without Mutagen:
bash
ddev config global --nfs-mount-enabled
对于不使用 Mutagen 的 macOS:
bash
ddev config global --nfs-mount-enabled

Performance Tips

性能建议

  1. Exclude unnecessary files from sync:
    yaml
    # .ddev/config.yaml
    upload_dirs:
      - sites/default/files
  2. Use tmpfs for temp files:
    yaml
    # .ddev/docker-compose.performance.yaml
    services:
      web:
        tmpfs:
          - /tmp
  3. Increase PHP memory for large operations:
    ini
    # .ddev/php/performance.ini
    memory_limit = 1024M
  1. 从同步中排除不需要的文件:
    yaml
    # .ddev/config.yaml
    upload_dirs:
      - sites/default/files
  2. 使用 tmpfs 存储临时文件:
    yaml
    # .ddev/docker-compose.performance.yaml
    services:
      web:
        tmpfs:
          - /tmp
  3. 为大型操作增加 PHP 内存:
    ini
    # .ddev/php/performance.ini
    memory_limit = 1024M

Custom DDEV Commands

自定义 DDEV 命令

Create project-specific commands in
.ddev/commands/
:
bash
undefined
在
.ddev/commands/
中创建项目专用命令:
bash
undefined

.ddev/commands/web/refresh

.ddev/commands/web/refresh

#!/bin/bash
#!/bin/bash

Description: Full site refresh (db + config + cache)

Description: Full site refresh (db + config + cache)

Usage: refresh

Usage: refresh

Example: ddev refresh

Example: ddev refresh

set -e
echo "Importing database..." drush sql:drop -y drush sql:cli < /var/www/html/reference.sql
echo "Importing config..." drush config:import -y
echo "Running updates..." drush updatedb -y
echo "Clearing cache..." drush cache:rebuild
echo "Done!"

Make executable: `chmod +x .ddev/commands/web/refresh`

Then run: `ddev refresh`
set -e
echo "Importing database..." drush sql:drop -y drush sql:cli < /var/www/html/reference.sql
echo "Importing config..." drush config:import -y
echo "Running updates..." drush updatedb -y
echo "Clearing cache..." drush cache:rebuild
echo "Done!"

赋予可执行权限:`chmod +x .ddev/commands/web/refresh`

然后运行:`ddev refresh`

Command Locations

命令位置

  • .ddev/commands/web/
    - Run in web container
  • .ddev/commands/host/
    - Run on host machine
  • .ddev/commands/db/
    - Run in database container
  • .ddev/commands/web/
    ——在 Web 容器中运行
  • .ddev/commands/host/
    ——在主机上运行
  • .ddev/commands/db/
    ——在数据库容器中运行

CI/CD Integration

CI/CD 集成

GitHub Actions

GitHub Actions

yaml
undefined
yaml
undefined

.github/workflows/test.yml

.github/workflows/test.yml

name: Tests on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Setup DDEV
    uses: ddev/github-action-setup-ddev@v1

  - name: Start DDEV
    run: ddev start

  - name: Install dependencies
    run: ddev composer install

  - name: Run tests
    run: ddev exec ./vendor/bin/phpunit
undefined
name: Tests on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Setup DDEV
    uses: ddev/github-action-setup-ddev@v1

  - name: Start DDEV
    run: ddev start

  - name: Install dependencies
    run: ddev composer install

  - name: Run tests
    run: ddev exec ./vendor/bin/phpunit
undefined

GitLab CI

GitLab CI

yaml
undefined
yaml
undefined

.gitlab-ci.yml

.gitlab-ci.yml

test: image: ddev/ddev-gitpod-base:latest services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 script: - ddev start - ddev composer install - ddev exec ./vendor/bin/phpunit
undefined
test: image: ddev/ddev-gitpod-base:latest services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 script: - ddev start - ddev composer install - ddev exec ./vendor/bin/phpunit
undefined

Best Practices

最佳实践

  1. Commit .ddev folder (except .ddev/db_snapshots, .ddev/.gitignore handles this)
  2. Use .ddev/config.local.yaml for personal overrides (gitignored)
  3. Document custom services in project README
  4. Use snapshots before risky database operations
  5. Keep DDEV updated:
    ddev self-upgrade
  6. Use Mutagen on macOS/Windows for better performance
  7. Create custom commands for repetitive tasks
  8. Test DDEV config in CI to catch issues early
  1. 提交
    .ddev
    文件夹
    ,但不包括
    .ddev/db_snapshots
    ;
    .ddev/.gitignore
    会处理此问题
  2. 使用
    .ddev/config.local.yaml
    保存个人覆盖配置(不纳入 Git)
  3. 在项目 README 中记录自定义服务
  4. 执行高风险数据库操作前使用快照
  5. 保持 DDEV 为最新版本:
    ddev self-upgrade
  6. 在 macOS/Windows 上使用 Mutagen以提升性能
  7. 为重复性任务创建自定义命令
  8. 在 CI 中测试 DDEV 配置,以尽早发现问题