DDEV for WordPress and PHP Development: Say Goodbye to “Works on My Machine”
If you’ve ever spent an entire afternoon wrestling with MAMP, XAMPP, or a tangled mess of Homebrew PHP versions, you already know the pain. Local development environments for WordPress and PHP projects have historically been a nightmare of configuration drift, version conflicts, and the dreaded “works on my machine” excuse.
Enter DDEV — an open-source tool that wraps Docker containers into a developer-friendly CLI, giving you reproducible, project-specific environments in minutes. No more fiddling with php.ini files. No more MySQL version roulette. Just consistent, shareable environments that work the same on every machine.
Let me show you why DDEV has become my go-to for every WordPress and PHP project.
What Is DDEV and Why Should You Care?
DDEV is a local development tool built on top of Docker that provides pre-configured containers for everything a PHP project needs: a web server (nginx or Apache), PHP (any version you want), a database (MySQL, MariaDB, or PostgreSQL), and a suite of developer tools like Composer, WP-CLI, and Xdebug.
The magic is in what DDEV abstracts away. You don’t need to understand Docker networking, volume mounts, or container orchestration. You describe your project in a simple YAML file, and DDEV handles the rest.
Here’s what makes it special:
- Project isolation: Each project gets its own containers, so PHP 7.4 for your legacy site and PHP 8.3 for your new one coexist peacefully.
- Reproducibility: Your
.ddev/config.yamlfile lives in version control. New team members run one command and they’re up and running. - Performance: DDEV uses Mutagen for file syncing on macOS, solving the infamous Docker-on-Mac speed problem.
- Batteries included: Mailpit for email testing, phpMyAdmin, Redis, Elasticsearch — all available as simple add-ons.
If you’re doing any kind of local development with PHP, DDEV eliminates an entire category of problems.
Getting Started: WordPress in Under 5 Minutes
Let’s walk through setting up a fresh WordPress project. First, make sure you have Docker Desktop (or Colima/OrbStack on macOS) and DDEV installed. On macOS with Homebrew:
# Install DDEV
brew install ddev/ddev/ddev
# Create a project directory
mkdir my-wordpress-site && cd my-wordpress-site
# Initialize DDEV with WordPress defaults
ddev config --project-type=wordpress --php-version=8.2 --docroot=.
# Download WordPress core
ddev start
ddev wp core download
# Create wp-config.php with DDEV's database credentials
ddev wp config create \
--dbname=db \
--dbuser=db \
--dbpass=db \
--dbhost=db
# Install WordPress
ddev wp core install \
--url='$DDEV_PRIMARY_URL' \
--title='My DDEV Site' \
--admin_user=admin \
--admin_password=admin \
--admin_email=admin@example.com
# Open it in your browser
ddev launch
That’s it. You now have a fully functional WordPress installation running with PHP 8.2, MariaDB, nginx, and a proper .ddev configuration directory. The site is accessible at https://my-wordpress-site.ddev.site with a real TLS certificate (thanks to DDEV’s built-in mkcert integration).
Let’s look at the configuration file that DDEV generated:
# .ddev/config.yaml
name: my-wordpress-site
type: wordpress
docroot: ""
php_version: "8.2"
webserver_type: nginx-fpm
database:
type: mariadb
version: "10.11"
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
additional_hostnames: []
additional_fqdns: []
hooks:
post-start:
- exec: "wp cache flush || true"
This file is the contract for your environment. Commit it to Git, and every developer on your team gets an identical setup. Notice the hooks section — you can run arbitrary commands at various lifecycle points. I’ve added a cache flush on start, but you could run database migrations, compile assets, or anything else.
Beyond the Basics: Real-World Configuration
A vanilla WordPress install is nice, but real projects have real requirements. Let’s look at some patterns I use constantly.
Custom PHP Configuration
Need to increase the upload limit or tweak PHP settings? Drop a file into .ddev/php/:
; .ddev/php/my-php.ini
upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 512M
max_execution_time = 300
display_errors = On
DDEV picks this up automatically on the next ddev restart. No hunting for which php.ini is active.
Adding Services with Add-ons
Need Redis for object caching? It’s one command:
# Add Redis
ddev get ddev/ddev-redis
# Restart to apply
ddev restart
# Verify it's running
ddev redis-cli ping
# Output: PONG
Now install the Redis Object Cache plugin in WordPress, and your local environment mirrors production. The same pattern works for Elasticsearch, Memcached, Solr, and dozens of other services.
Custom Docker Compose Overrides
For anything DDEV doesn’t handle out of the box, you can add custom Docker Compose files. Here’s an example that adds a Node.js container for compiling your theme assets:
# .ddev/docker-compose.node.yaml
services:
node:
container_name: ddev-${DDEV_SITENAME}-node
image: node:20-alpine
working_dir: /var/www/html/wp-content/themes/my-theme
volumes:
- ".:/mnt/ddev_config:ro"
- "ddev-global-cache:/mnt/ddev-global-cache"
- "../:/var/www/html"
command: sh -c "npm install && npm run watch"
labels:
com.ddev.site-name: ${DDEV_SITENAME}
Database Snapshots
One of my favorite DDEV features for WordPress development is database snapshots:
# Save current database state
ddev snapshot --name=before-migration
# Do something risky...
ddev wp plugin activate sketchy-plugin
# Something broke? Restore in seconds
ddev snapshot restore --latest
# List all snapshots
ddev snapshot --list
This is infinitely faster than importing SQL dumps and gives you instant rollback capability during development.
Team Workflow and CI Integration
Where DDEV really shines is team consistency. Here’s a pattern I use for onboarding:
#!/bin/bash
# scripts/setup.sh — One command to rule them all
set -e
echo "🚀 Setting up development environment..."
# Start DDEV
ddev start
# Install PHP dependencies
ddev composer install
# Install WordPress if not present
if [ ! -f wp-includes/version.php ]; then
ddev wp core download
fi
# Import seed database
ddev import-db --file=.ddev/seeds/development.sql.gz
# Install theme dependencies
ddev exec -d /var/www/html/wp-content/themes/my-theme npm install
ddev exec -d /var/www/html/wp-content/themes/my-theme npm run build
echo "✅ Done! Run 'ddev launch' to open the site."
A new developer clones the repo, runs bash scripts/setup.sh, and has a working environment with seeded data. No wiki pages with 47 steps. No Slack messages asking “how do I set up the project?”
Conclusion: Make the Switch
DDEV has fundamentally changed how I approach local development for WordPress and PHP projects. The combination of simplicity, power, and reproducibility makes it hard to justify any other approach.
Here’s what I’d recommend as next steps:
- Install DDEV and try the WordPress quickstart above on a throwaway project. Feel how fast it is.
- Convert an existing project by running
ddev configin its root directory. DDEV auto-detects most project types. - Explore add-ons at github.com/ddev/awesome-ddev for services your projects need.
- Commit your
.ddevdirectory to version control and watch your team thank you.
The days of environment inconsistency are over. Your future self — and your teammates — will appreciate the investment.