MCPInstall

ddev-expert

DDEV local development expertise. Use when working with DDEV projects, containers, configuration, or troubleshooting DDEV environments.

Installs
323
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/madsnorgaard/drupal-agent-resources --skill ddev-expert
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads ddev-expert automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

DDEV Development Expert

You are an expert in DDEV, the Docker-based local development environment for PHP projects.

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.

Essential Commands

Project Management

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

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

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

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

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:
  - api.my-project.ddev.site

# Extra PHP packages
webimage_extra_packages: [php8.3-imagick]

Common Customizations

Custom services (.ddev/docker-compose.*.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):

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.

Drupal-Specific Setup

New Drupal 11 Project

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

New Drupal 10 Project

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

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":

# This happens when extra directories exist (like .claude/, .git/, etc.)
# 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:

ddev poweroff
# Check what's using ports 80/443
sudo lsof -i :80

Container issues:

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:

ddev exec chown -R $(id -u):$(id -g) .

Useful Debug Commands

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

Configure providers in .ddev/providers/:

# .ddev/providers/platform.yaml
environment_variables:
  project: my-project
  environment: main

db_pull_command:
  command: platform db:dump -e ${environment}

Then: ddev pull platform

Xdebug Configuration

Enable Xdebug

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

IDE Configuration

VS Code (with PHP Debug extension):

// .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

Xdebug Modes

# .ddev/php/xdebug.ini
[xdebug]
xdebug.mode=debug,develop,coverage

Modes: debug (step debugging), develop (enhanced errors), coverage (code coverage), profile (profiling)

Custom Services

Redis

# .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:

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

Solr

# .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

Elasticsearch

# .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:

Mailpit (Email Testing)

DDEV includes Mailpit by default:

ddev launch -m           # Open Mailpit UI

All outgoing mail is captured at https://<project>.ddev.site:8026

Performance Tuning

Mutagen (macOS/Windows)

Mutagen provides fast file synchronization for better performance:

# Enable globally
ddev config global --mutagen-enabled

# 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:

ddev mutagen status      # Check sync status
ddev mutagen sync        # Force sync
ddev mutagen reset       # Reset if issues

NFS (macOS alternative)

For macOS without Mutagen:

ddev config global --nfs-mount-enabled

Performance Tips

  1. Exclude unnecessary files from sync:

    # .ddev/config.yaml
    upload_dirs:
      - sites/default/files
    
  2. Use tmpfs for temp files:

    # .ddev/docker-compose.performance.yaml
    services:
      web:
        tmpfs:
          - /tmp
    
  3. Increase PHP memory for large operations:

    # .ddev/php/performance.ini
    memory_limit = 1024M
    

Custom DDEV Commands

Create project-specific commands in .ddev/commands/:

# .ddev/commands/web/refresh
#!/bin/bash

## Description: Full site refresh (db + config + cache)
## Usage: 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

Command Locations

  • .ddev/commands/web/ - Run in web container
  • .ddev/commands/host/ - Run on host machine
  • .ddev/commands/db/ - Run in database container

CI/CD Integration

GitHub Actions

# .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

GitLab CI

# .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

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

FAQ

What does the ddev-expert skill do?

DDEV local development expertise. Use when working with DDEV projects, containers, configuration, or troubleshooting DDEV environments.

How do I install ddev-expert?

Run npx skills add https://github.com/madsnorgaard/drupal-agent-resources --skill ddev-expert in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/ddev-expert/ (personal) or .claude/skills/ddev-expert/ (project).

Which AI agents can use ddev-expert?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is ddev-expert safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains ddev-expert?

It is published by madsnorgaard in madsnorgaard/drupal-agent-resources. It has 323 recorded installs.

More from madsnorgaard/drupal-agent-resources

View all →

drupal-expert

madsnorgaard/drupal-agent-resources

Drupal 10/11 development expertise. Use when working with Drupal modules, themes, hooks, services, configuration, or migrations. Triggers on mentions of Drupal, Drush, Twig, modules, themes, or Drupal API.

Backend & APIs1.1K installs

drupal-security

madsnorgaard/drupal-agent-resources

Drupal security expertise. Auto-activates when writing forms, controllers, queries, or handling user input. Prevents XSS, SQL injection, and access bypass vulnerabilities.

Security830 installs

drupal-migration

madsnorgaard/drupal-agent-resources

Drupal migration expertise. Use when working with D7-to-D10 migrations, CSV imports, JSON API imports, or custom migration plugins.

docker-local

madsnorgaard/drupal-agent-resources

Open the skill to read its SKILL.md instructions.

DevOps & Cloud101 installs

Popular other skills

View category →

hyperframes-cli

heygen-com/hyperframes

The HyperFrames CLI by job - scaffold, check, look at frames, edit the timeline, preview, render locally or in the cloud, publish, project history - plus reading its JSON and recovering from build or render failures.

1.3M installs

triage

mattpocock/skills

Move issues and external PRs through a state machine of triage roles, categorise, verify, grill if needed, and write agent-ready briefs.

1M installs

ask-matt

mattpocock/skills

Ask which skill or flow fits your situation. A router over the skills in this repo.

778.4K installs

to-questionnaire

mattpocock/skills

Turn a decision you can't fully answer into a questionnaire for someone else to fill in.

508.9K installs

wait-what

mattpocock/skills

Stop. That last message did not land: re-pitch it.

459.7K installs

loop-me

mattpocock/skills

Grill me about specs for the workflows I want to build, within this workspace.

447.9K installs