How to Use DDEV for Local Development
System Requirements
- Windows 10 22H2 or newer, or Windows 11
- Virtualization enabled in BIOS (usually enabled by default on modern machines)
- Administrator access on Windows
Why DDEV
DDEV is a local development environment designed primarily for WordPress, Drupal, and PHP-based projects, with first-class support for Docker and WSL2 on Windows.
It provides a consistent, reproducible environment that matches production more closely than traditional local stacks.
DDEV replaces the need to install PHP, MySQL, Apache, or Nginx locally. Everything runs in containers.
If you value consistency, reproducibility, and clean environments, DDEV is a strong choice.
- DDEV is not the simplest tool, but it is one of the most reliable
- It scales from one site to dozens
- It works the same on Windows, macOS, and Linux
- It keeps your system clean and your projects isolated
What Problems DDEV Solves
Without DDEV, local development often involves:
- Installing PHP manually
- Managing multiple PHP versions
- Installing MySQL or MariaDB locally
- Debugging OS-specific issues
- “Works on my machine” problems
DDEV solves this by:
- Running everything in Docker containers
- Isolating each project
- Making environments disposable and repeatable
- Using simple, explicit CLI commands
DDEV vs Other Local Development Solutions
DDEV vs Local by Flywheel
Local focuses on ease of use and UI-driven workflows.
DDEV focuses on consistency, portability, and automation.
| Feature | DDEV | Local |
|---|---|---|
| Docker-based | Yes | Partially / abstracted |
| CLI-first | Yes | No (GUI-first) |
| Best for teams | Yes | Limited |
| Config in Git | Yes | No |
| Linux parity | Excellent | Medium |
| CI compatibility | Yes | No |
Use Local if:
- You want the fastest “click-and-run” setup
- You prefer GUIs over terminals
- You work solo on small projects
Use DDEV if:
- You work with teams
- You use Git-based workflows
- You want environments to behave the same everywhere
DDEV vs Manual Docker / Docker Compose
Manual Docker setups give full control but require:
- Writing and maintaining
docker-compose.yml - Managing PHP, Nginx, and database images
- Handling networking, volumes, and ports
- Debugging low-level Docker issues
DDEV provides:
- Preconfigured, battle-tested images
- Automatic routing and HTTPS
- Simple commands (
ddev start,ddev stop) - Sensible defaults with escape hatches
| Feature | DDEV | Manual Docker |
|---|---|---|
| Setup time | Minutes | Hours |
| Maintenance | Low | High |
| WordPress tooling | Built-in | Manual |
| Database tools | Built-in | Manual |
| Onboarding | Easy | Hard |
DDEV is effectively Docker without the boilerplate.
DDEV vs Traditional Local Stacks (XAMPP, MAMP, WAMP)
Traditional stacks install services directly on your OS.
Problems with this approach:
- Conflicting PHP versions
- Hard-to-remove services
- Global configuration bleed
- Difficult upgrades and rollbacks
DDEV avoids this entirely:
- No global PHP
- No global MySQL
- No system-level web server
- Easy cleanup (
ddev delete,ddev poweroff)
This is especially important on Windows.
Why DDEV + WSL2 on Windows
On Windows, DDEV + WSL2 provides:
- Near-native Linux performance
- Fewer filesystem issues
- Better Docker compatibility
- Behavior closer to production servers
This setup is:
- Officially supported
- Widely used in professional teams
- Stable for long-term projects
When DDEV is Not the Right Choice
DDEV may not be ideal if:
- You want a zero-terminal experience
- You only build static sites
- You don’t use Docker at all
- You strongly prefer GUI tools
In those cases, simpler tools may be a better fit.
Getting Started
Useful Commands
Daily Workflow
# Right-click the Windows Terminal
# Select: DDEV (this opens the correct WSL distro)
# You will land in: /home/<user>
# Go to your project
cd sites/my-wordpress-site
# Start the site
ddev start
# Open the site in your Windows browser
ddev launch
# (During the day, when needed)
ddev wp cache flush
ddev logs
# Stop the site when you’re done
ddev stop
Basic Commands
# Start the project containers (creates them if missing)
ddev start
# Stop containers for the current project (nothing is deleted)
ddev stop
# Restart containers (useful after config or env changes)
ddev restart
# Stop all DDEV projects
ddev poweroff
# Show project info: URLs, services, ports, status
ddev describe
Logs & Debugging
# Show logs from all project containers
ddev logs
# Show logs from a specific service (web, db, etc.)
ddev logs web
WordPress / WP-CLI
# Run WP-CLI inside the container
ddev wp
# List WordPress users
ddev wp user list
# Generate a one-time login link and open wp-admin
# Example: Username = "mihaicircea"
ddev wp login create mihaicircea --launch
Database Commands
# Export the project database to a SQL file
ddev export-db
# Import a SQL dump into the project database
ddev import-db --file=db.sql
# Open phpMyAdmin for this project
ddev launch phpmyadmin
# Open Adminer for this project
ddev launch adminer
Project Lifecycle
# Rule you’ll remember in practice
# start / stop → runtime only
# delete → DDEV forgets the project
# rm -rf → files are gone forever
# Stop containers but keep project and config
ddev stop
# Remove containers, volumes, and DDEV config (files stay)
ddev delete
# Manually delete project files from disk
rm -rf ~/sites/my-wordpress-site
Global / Machine-wide
# List all DDEV projects and their current status
ddev list
# Start all DDEV projects
ddev start --all
# Stop ALL DDEV containers on the machine
ddev poweroff
Using Git with DDEV Projects
DDEV works very well with Git. Git tracks your project files, not the DDEV containers.
Start Using Git
Initialize a Git repository:
cd ~/sites/my-wordpress-site
git init
Create a .gitingore file in the project root, a.k.a. DO NOT commit these:
# DDEV
.ddev/.dbimageBuild/
.ddev/.dbimage/
.ddev/.snapshot/
.ddev/.imported
.ddev/db_snapshots/
# WordPress
web/wp-config.php
web/wp-content/uploads/
# OS / tooling
.DS_Store
.vscode/
node_modules/
This keeps:
- Databases out of Git
- Uploads out of Git
- Machine-specific files out of Git
Commit these:
web/(WordPress core, themes, plugins).ddev/config.yaml.ddev/docker-compose.*.yaml(if you customize them)- Custom themes and plugins
- Project configuration files
- DDEV does not need to be running to commit changes.
Example First Commit
git status
git add .
git commit -m "Initial WordPress setup"
Team Workflows (Important)
When a teammate clones the repo:
git clone <repo-url>
cd my-wordpress-site
ddev start
Then they either:
- Install WordPress fresh
- OR Import the database (see next section)
Importing an Existing WordPress Site into DDEV
What You Need From the Existing Site
From the source site, obtain:
- Database dump
.sqlor.sql.gz
wp-contentfolder- Especially:
themes/plugins/uploads/
- Especially:
Set Up a DDEV Project (Empty)
Create and start the project first:
cd ~/sites
mkdir existing-site
cd existing-site
ddev config
ddev start
Use:
- Project type:
wordpress - Docroot:
web
Add WordPress Files
If WordPress is not already present:
ddev wp core download
Now copy in your existing content:
cp -r /path/to/wp-content web/
Result
web/
├── wp-content/
│ ├── themes/
│ ├── plugins/
│ └── uploads/
Import the Database
Place your database dump anywhere, for example:
~/sites/existing-site/db.sql
Then run:
ddev import-db --file=db.sql
DDEV will automatically import it into the container database.
Fix URLs (Very Common)
If the site was previously on another domain, update URLs:
ddev wp search-replace \\
'<https://old-site.com>' \\
'<https://existing-site.ddev.site>'
Flush rewrite rules:
ddev wp rewrite flush
Log In
Launch wp-admin:
ddev launch wp-admin
If needed, reset the admin password:
ddev wp user update admin --user_pass=newpassword
Common Issues When Importing
White screen / errors
- Check:
ddev logs
Missing images
- Ensure
uploads/was copied
Mixed content
- Run
search-replaceagain forhttp→https
Exporting a Site From DDEV
Use this when you want to move a local DDEV site to staging or production.
Export the Database
From the project root:
ddev export-db
This creates a database dump inside:
.ddev/db_snapshots/
You can also specify a filename:
ddev export-db --file=prod.sql
Export Files
You typically need only:
web/wp-content/
Specifically:
themes/plugins/uploads/
Zip or upload these via SFTP, rsync, or your hosting control panel.
URL Changes for Production
Before or after importing on production:
wp search-replace \\
'<https://my-site.ddev.site>' \\
'<https://example.com>'
Run this on the production server, not locally.
Troubleshooting
ddev describe
ddev logs
docker ps
Common fixes:
- Restart Docker Desktop
- Run
ddev poweroff - Ensure you are not in
/mnt/c - Ensure Docker Desktop is running