A Docker-powered local environment for PHP projects — Drupal, WordPress, Laravel and more — without the config headaches.
DDEV is an open-source tool that gives you a consistent, fully-configured local development environment for PHP-based web projects. It wraps Docker containers in a friendly command-line interface so you don't have to think about container configuration.
Instead of manually installing and managing Apache, PHP, MySQL, and a dozen config files on your laptop, DDEV handles all of that inside isolated containers — and you interact with it through simple commands like ddev start and ddev drush cr.
A new project is ready in minutes — not an afternoon of config.
Built-in support for Drupal, WordPress, Laravel, Craft, and more.
Switch between projects effortlessly. Each is fully isolated.
Auto-generated local TLS certificates. No more browser warnings.
Team members on Linux, Mac or Windows all get the same environment.
Add services like Redis, Solr, or Mailpit with a single config line.
DDEV sits between you and Docker. When you run ddev start, it reads your project's .ddev/config.yaml and launches a set of pre-configured containers. Your project files are mounted into the container so changes are instant.
Your site files live on your laptop and are volume-mounted into the web container. Edits in your code editor are reflected immediately — no sync step needed.
DDEV requires Docker CE to be installed first. If you haven't done that yet, see the Docker on Linux guide. Then install DDEV itself:
# Add DDEV's GPG key and apt repository $ curl -fsSL https://pkg.ddev.com/apt/gpg.key \ | gpg --dearmor | sudo tee /etc/apt/keyrings/ddev.gpg > /dev/null $ echo "deb [signed-by=/etc/apt/keyrings/ddev.gpg] https://pkg.ddev.com/apt/ * *" \ | sudo tee /etc/apt/sources.list.d/ddev.list $ sudo apt update && sudo apt install -y ddev # Verify installation $ ddev --version → DDEV version v1.25.x
DDEV uses mkcert to generate trusted local TLS certificates. Run this once after installing:
# Install libnss3-tools so browsers trust the certs $ sudo apt install -y libnss3-tools # Generate and trust the local CA $ mkcert -install → Created a new local CA at ~/.local/share/mkcert
After mkcert -install, your browser will trust HTTPS on all *.ddev.site URLs without warnings. You only need to do this once per machine.
Navigate to your project's root directory (where your web or docroot folder lives) and initialise DDEV:
# Move into your project folder $ cd ~/Sites/myproject # Configure DDEV (adjust project-name and docroot to match your project) $ ddev config \ --project-type=drupal \ --docroot=web \ --project-name=myproject # Start the containers $ ddev start # Open the site in your browser $ ddev launch → Opens https://myproject.ddev.site
DDEV creates a .ddev/ folder in your project root containing config.yaml. Commit this folder to Git so your team gets the same environment automatically.
Add these to your settings.php (or settings.local.php) — DDEV uses these internally:
$databases['default']['default'] = [ 'driver' => 'mysql', 'database' => 'db', 'username' => 'db', 'password' => 'db', 'host' => 'db', 'port' => '3306', ];
Make sure settings*.php is listed in your .gitignore. These local credentials should never be committed to Git or end up on staging/production.
| Command | What it does |
|---|---|
| ddev start | Start the project's containers |
| ddev stop | Stop containers (data is preserved) |
| ddev restart | Stop then start — useful after config changes |
| ddev launch | Open the project in your default browser |
| ddev describe | Show project status, URLs, and service ports |
| ddev list | List all DDEV projects on this machine |
| ddev ssh | Open a shell inside the web container |
| ddev logs | View web server and PHP logs |
| ddev poweroff | Stop all running DDEV projects at once |
Your site URL is always https://<project-name>.ddev.site. Run ddev describe to see it along with database connection details and any extra services.
All Drush commands must be prefixed with ddev. Running drush directly won't work — it can't find the database because it's running inside DDEV's container, not on your host machine.
Always use ddev drush <command> — never drush or ./vendor/bin/drush on its own. The same rule applies to ddev composer.
| Command | What it does |
|---|---|
| ddev drush cr | Clear all Drupal caches |
| ddev drush uli | Generate a one-time admin login link |
| ddev drush config:import -y | Import configuration from /config/sync |
| ddev drush config:export -y | Export configuration to /config/sync |
| ddev drush updatedb -y | Run pending database updates |
| ddev drush watchdog:show | Show recent log entries and errors |
| ddev drush pm:install <module> | Enable a module |
| ddev drush pm:uninstall <module> | Disable and uninstall a module |
| ddev drush sql:dump > ~/dump.sql | Export the database to a file |
| ddev composer require <package> | Add a Composer dependency |
| ddev composer install | Install all Composer dependencies |
After pulling code from Git, run these in order:
$ ddev composer install # install any new dependencies $ ddev drush updatedb -y # run database updates $ ddev drush config:import -y # import config changes $ ddev drush cr # clear caches
| Command | What it does |
|---|---|
| ddev import-db --file=~/dump.sql | Import a SQL file into the project database |
| ddev drush sql:dump > ~/dump.sql | Export (dump) the database to a file |
| ddev mysql | Open an interactive MySQL CLI prompt |
| ddev import-db --file=dump.sql.gz | Import a gzipped SQL dump directly |
# Make sure DDEV is running first $ ddev start # Import your SQL dump $ ddev import-db --file=~/backup.sql # Clear caches after import $ ddev drush cr # Get a login link if you're locked out $ ddev drush uli
After importing a database from staging or production, always run ddev drush uli to get a one-time login link. The admin password from the live site won't work locally until you use it.
You can have as many DDEV projects as you like on one machine. Each lives in its own directory and runs as a completely separate environment. They can even run simultaneously.
# List all projects and their status $ ddev list NAME TYPE LOCATION URL STATUS rochdaletraining drupal ~/Sites/rochdale... https://rochdaletraining... running openintranet drupal ~/Sites/openintranet https://openintranet... stopped # Switch to a different project — just cd into its folder $ cd ~/Sites/openintranet $ ddev start # Stop ALL running DDEV projects in one go $ ddev poweroff
DDEV commands always apply to the project in your current directory. Make sure you've cd'd into the right project folder before running any ddev commands.
# Error: permission denied while trying to connect to the Docker daemon socket # Quick fix for current terminal session: $ newgrp docker # Permanent fix: log out and back in
# Start Docker first if it's not running $ sudo systemctl start docker # Then start DDEV $ ddev start # Check full status $ ddev describe
# You ran drush directly — always use the ddev prefix: $ ddev drush cr ✓ correct # NOT: drush cr ✗ # NOT: ./vendor/bin/drush cr ✗
$ ddev drush cr # Then hard-refresh in your browser: Ctrl+Shift+R
# The database hasn't been imported yet $ ddev import-db --file=~/your-database-dump.sql $ ddev drush cr
# If deploy scripts lose SSH access to your server $ ddev auth ssh # This loads your SSH keys into the DDEV container
# Delete the DDEV project (keeps your files, removes containers + DB) $ ddev delete -O # -O omits the database dump prompt # Reconfigure and restart from scratch $ ddev config --project-type=drupal --docroot=web $ ddev start $ ddev import-db --file=~/backup.sql