ddev-expert
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDDEV Development Expert
DDEV开发专家指南
You are an expert in DDEV, the Docker-based local development environment for PHP projects.
您是DDEV领域的专家,DDEV是一款基于Docker的PHP项目本地开发环境。
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 after creating a Drupal project.
composer require drush/drushDDEV 提供一致的容器化本地开发环境,具备以下特性:
- 预配置的PHP、Web服务器、数据库容器
- 基于mkcert的自动HTTPS支持
- 内置Composer和Node.js支持
- 便捷的多项目管理
注意: 默认不包含Drush - 创建Drupal项目后必须执行进行安装。
composer require drush/drushEssential 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 containerbash
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 containerDatabase
数据库管理
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 snapshotbash
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 snapshotUtilities
实用工具
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]
undefinedwebimage_extra_packages: [php8.3-imagick]
undefinedCommon 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 = 64MNginx 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 = 64MNginx配置 (.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 launchImportant notes:
- requires a clean directory - move any existing files (like
ddev composer create-project) out first, then move them back after.claude/ - Drush is NOT included in Drupal 11's recommended-project - always install it separately
- Use (auto-detects version) or explicitly
--project-type=drupaldrupal11
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的推荐项目模板中不包含Drush - 务必单独安装
- 使用 (自动检测版本)或显式指定
--project-type=drupaldrupal11
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 launchbash
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 launchExisting 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 crbash
cd existing-project
ddev config --project-type=drupal --docroot=web
ddev start
ddev composer install
ddev import-db --file=database.sql.gz
ddev drush crTroubleshooting
故障排查
Common Issues
常见问题
ddev composer create-projectbash
undefinedddev composer create-projectbash
undefinedThis 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 poweroffmv .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 poweroffCheck 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 optionDatabase connection issues:
- Host: (inside container) or
db(outside)127.0.0.1:PORT - 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数据库连接问题:
- 主机:容器内使用,外部使用
db127.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 variablesbash
ddev debug capabilities # Show DDEV capabilities
ddev debug router # Show router status
ddev logs -f # Follow logs
ddev exec env # Show environment variablesMulti-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 statebash
ddev xdebug on # Enable step debugging
ddev xdebug off # Disable (faster performance)
ddev xdebug status # Check current stateIDE 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:
- Settings → PHP → Servers
- Add server: name matches DDEV project name
- Host: , Port: 443, HTTPS
<project>.ddev.site - 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:
- 设置 → PHP → 服务器
- 添加服务器:名称与DDEV项目名称一致
- 主机:,端口:443,启用HTTPS
<project>.ddev.site - 路径映射:项目根目录 →
/var/www/html
Xdebug Modes
Xdebug模式
bash
undefinedbash
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
undefinedyaml
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
undefinedyaml
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
undefinedyaml
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:
undefinedservices:
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:
undefinedMailpit (Email Testing)
Mailpit(邮件测试)
DDEV includes Mailpit by default:
bash
ddev launch -m # Open Mailpit UIAll outgoing mail is captured at
https://<project>.ddev.site:8026DDEV默认包含Mailpit:
bash
ddev launch -m # Open Mailpit UI所有外发邮件都会被捕获,可通过查看
https://<project>.ddev.site:8026Performance Tuning
性能优化
Mutagen (macOS/Windows)
Mutagen(macOS/Windows)
Mutagen provides fast file synchronization for better performance:
bash
undefinedMutagen提供快速文件同步,提升性能:
bash
undefinedEnable 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 issuesmutagen_enabled: true
**适用场景:**
- macOS系统下的大型代码库(如vendor、node_modules)
- Windows系统搭配WSL2使用
- 文件I/O较慢的项目
**Mutagen相关命令:**
```bash
ddev mutagen status # Check sync status
ddev mutagen sync # Force sync
ddev mutagen reset # Reset if issuesNFS (macOS alternative)
NFS(macOS替代方案)
For macOS without Mutagen:
bash
ddev config global --nfs-mount-enabled对于不使用Mutagen的macOS用户:
bash
ddev config global --nfs-mount-enabledPerformance Tips
性能优化技巧
-
Exclude unnecessary files from sync:yaml
# .ddev/config.yaml upload_dirs: - sites/default/files -
Use tmpfs for temp files:yaml
# .ddev/docker-compose.performance.yaml services: web: tmpfs: - /tmp -
Increase PHP memory for large operations:ini
# .ddev/php/performance.ini memory_limit = 1024M
-
排除不必要的文件同步:yaml
# .ddev/config.yaml upload_dirs: - sites/default/files -
使用tmpfs存储临时文件:yaml
# .ddev/docker-compose.performance.yaml services: web: tmpfs: - /tmp -
为大型操作增加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
命令存放位置
- - Run in web container
.ddev/commands/web/ - - Run on host machine
.ddev/commands/host/ - - Run in database container
.ddev/commands/db/
- - 在Web容器中执行
.ddev/commands/web/ - - 在本地主机执行
.ddev/commands/host/ - - 在数据库容器中执行
.ddev/commands/db/
CI/CD Integration
CI/CD集成
GitHub Actions
GitHub Actions
yaml
undefinedyaml
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/phpunitundefinedname: 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/phpunitundefinedGitLab CI
GitLab CI
yaml
undefinedyaml
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
undefinedtest:
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
undefinedBest Practices
最佳实践
- Commit .ddev folder (except .ddev/db_snapshots, .ddev/.gitignore handles this)
- Use .ddev/config.local.yaml for personal overrides (gitignored)
- Document custom services in project README
- Use snapshots before risky database operations
- Keep DDEV updated:
ddev self-upgrade - Use Mutagen on macOS/Windows for better performance
- Create custom commands for repetitive tasks
- Test DDEV config in CI to catch issues early
- 提交.ddev目录到版本控制(.ddev/db_snapshots除外,已被.ddev/.gitignore忽略)
- 使用.ddev/config.local.yaml进行个人自定义配置(已被Git忽略)
- 在项目README中记录自定义服务
- 在执行高风险数据库操作前创建快照
- 保持DDEV更新:
ddev self-upgrade - 在macOS/Windows上使用Mutagen提升性能
- 创建自定义命令简化重复任务
- 在CI中测试DDEV配置,提前发现问题