How-To: Local development with DDEV
Audience: developers working in the monorepo Last reviewed: 2026-06-17
Goal
Get a working Drupal 11 Mandala site running locally under DDEV, and know how to rebuild it from a clean state.
Prerequisites
- DDEV and Docker installed.
- Run all commands from the repo root. DDEV is configured here
(
.ddev/config.yaml): projectmandala,drupal11, docrootdrupal/web, composer rootdrupal, PHP 8.3, MariaDB 10.11.
First-time setup
- Start the environment. On first start, a post-start hook runs
composer installautomatically ifdrupal/vendoris missing:ddev start - Install a fresh Drupal site and import the committed config:
ddev drush site:install --yes ddev drush config:import --yes ddev drush cache:rebuild - Open the site. DDEV chooses an appropriate URL/port and prints it — use the
Primary URLfromddev describe(or the URL echoed byddev start) rather than assuming a fixed address. It's typically something likehttps://mandala.ddev.site:8443(the host is stable; the HTTPS port is often8443when443is already in use):ddev launch # opens the primary URL in your browser # or: ddev describe # lists the project URL(s) and ports
!!! note "First-visit SSL warning" The first time you open the HTTPS URL, your browser will likely show a security/"not private" warning. DDEV serves over HTTPS with a locally generated certificate that your system doesn't trust by default. In practice most of us just accept the exception ("Proceed anyway") — the browser then ignores it for the rest of the session. That's perfectly fine for local dev.
If you'd rather silence the warning permanently, install the
[mkcert](https://github.com/FiloSottile/mkcert) root CA once:
```bash
mkcert -install # installs the local CA into your system trust store
ddev restart # re-issue certs trusted by your browser
```
Or just use the plain `http://` URL from `ddev describe`.
Full rebuild (clean slate)
When you want to drop the database and reinstall from committed config, use the helper script — it installs with admin/admin credentials, imports config, and rebuilds caches:
./scripts/rebuild.sh
⚠️ This drops and reinstalls the database. Anything not exported to
drupal/config/sync/is lost. Export first if you have config changes you want to keep (see below).
Common Drush commands
ddev drush cr # cache rebuild
ddev drush cim # config import (config/sync → DB)
ddev drush cex # config export (DB → config/sync)
ddev drush updb # run pending DB updates
ddev drush en <module> # enable a module
ddev drush pmu <module> # uninstall a module
Config workflow
Drupal config is tracked in git under drupal/config/sync/. The loop is:
- Make changes in the admin UI (or via Drush).
- Export them:
ddev drush cex. - Review and commit the resulting diff in
drupal/config/sync/. - Teammates pull and run
ddev drush cimto apply.
Verify
ddev describeshows the project running and lists itsPrimary URL.- That URL loads the site in a browser (
ddev launch). ddev drush statusreports Drupal bootstrapped and DB connected.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
composer deps missing after start |
post-start hook only runs when drupal/vendor is absent |
ddev composer install --prefer-dist |
| Config import does nothing / errors | local DB drifted from config/sync |
./scripts/rebuild.sh for a clean slate |
| Site URL won't resolve | DDEV/router not up | ddev restart, then ddev describe |