mididigi · local dev guide

DDEV
Local Development
Done Right

A Docker-powered local environment for PHP projects — Drupal, WordPress, Laravel and more — without the config headaches.

🟢 What is DDEV?

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.

Fast setup

A new project is ready in minutes — not an afternoon of config.

🧩 CMS-aware

Built-in support for Drupal, WordPress, Laravel, Craft, and more.

🔀 Multiple projects

Switch between projects effortlessly. Each is fully isolated.

🔒 HTTPS by default

Auto-generated local TLS certificates. No more browser warnings.

📦 Portable

Team members on Linux, Mac or Windows all get the same environment.

🛠️ Extensible

Add services like Redis, Solr, or Mailpit with a single config line.

🏗️ How it Works

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.

You ddev start · ddev drush · ddev launch
DDEV CLI reads .ddev/config.yaml · manages containers
Docker & Docker Compose container runtime · networking · volumes
Containers web (Apache/nginx + PHP) · db (MySQL/MariaDB) · ddev-router
💡

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.

⚙️ Installation on Linux

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:

bash — install DDEV via official script
# 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

Set up HTTPS certificates (mkcert)

DDEV uses mkcert to generate trusted local TLS certificates. Run this once after installing:

bash — mkcert setup
# 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.

🆕 Setting Up a Project

Navigate to your project's root directory (where your web or docroot folder lives) and initialise DDEV:

Drupal (Composer-based)

bash — configure DDEV for a Drupal project
# 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.

Database credentials inside DDEV

Add these to your settings.php (or settings.local.php) — DDEV uses these internally:

settings.php — DDEV database credentials
$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.

🔄 Daily Workflow

01
ddev start
Boot containers
02
ddev launch
Open in browser
03
...work...
Edit files normally
04
ddev stop
Free resources
CommandWhat it does
ddev startStart the project's containers
ddev stopStop containers (data is preserved)
ddev restartStop then start — useful after config changes
ddev launchOpen the project in your default browser
ddev describeShow project status, URLs, and service ports
ddev listList all DDEV projects on this machine
ddev sshOpen a shell inside the web container
ddev logsView web server and PHP logs
ddev poweroffStop 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.

🔵 Drupal & Drush Commands

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.

CommandWhat it does
ddev drush crClear all Drupal caches
ddev drush uliGenerate a one-time admin login link
ddev drush config:import -yImport configuration from /config/sync
ddev drush config:export -yExport configuration to /config/sync
ddev drush updatedb -yRun pending database updates
ddev drush watchdog:showShow 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.sqlExport the database to a file
ddev composer require <package>Add a Composer dependency
ddev composer installInstall all Composer dependencies

Full update sequence

After pulling code from Git, run these in order:

bash — post-pull update routine
$ 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

🗄️ Database Management

CommandWhat it does
ddev import-db --file=~/dump.sqlImport a SQL file into the project database
ddev drush sql:dump > ~/dump.sqlExport (dump) the database to a file
ddev mysqlOpen an interactive MySQL CLI prompt
ddev import-db --file=dump.sql.gzImport a gzipped SQL dump directly

Importing a database

bash — import a database dump
# 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.

📂 Running Multiple Projects

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.

bash — working with multiple projects
# 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.

🔧 Common Problems & Fixes

Permission denied on Docker socket

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

DDEV won't start / can't connect to database

bash
# Start Docker first if it's not running
$ sudo systemctl start docker

# Then start DDEV
$ ddev start

# Check full status
$ ddev describe

Drush can't connect to database (getaddrinfo for db failed)

bash
# You ran drush directly — always use the ddev prefix:
$ ddev drush cr        ✓ correct
# NOT:  drush cr                ✗
# NOT:  ./vendor/bin/drush cr   ✗

Blank page or theme not rendering

bash
$ ddev drush cr
# Then hard-refresh in your browser: Ctrl+Shift+R

Site shows a fresh Drupal install (no content)

bash
# The database hasn't been imported yet
$ ddev import-db --file=~/your-database-dump.sql
$ ddev drush cr

SSH key issues with deploy scripts

bash
# If deploy scripts lose SSH access to your server
$ ddev auth ssh
# This loads your SSH keys into the DDEV container

Nuclear reset — delete and start fresh

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