Installation
See the installation instructions for details, but it's easy:
- macOS: brew install ddev/ddev/ddev or just brew upgrade ddev.
- Linux: Use sudo apt-get update && sudo apt-get install ddev, see apt/yum installation
- Windows and WSL2: Download the Windows Installer; you can run it for install or upgrade.
⚠️ Traditional Windows users (not WSL2): If needed, the installer will prompt you to uninstall the previous system-wide installation to avoid conflicts with the new per-user installation.
- Consider ddev delete images or ddev delete images --all after upgrading to free up disk space used by previous Docker image versions. This does no harm.
- Consider ddev config --auto to update your projects to current configuration.
Highlights
Blog announcement: https://ddev.com/blog/release-v1-25-3/
- New Docker Compose library: Improved UX during ddev start and ddev stop; the separate ~/.ddev/bin/docker-compose binary is no longer needed and can be removed
- Faster ddev start: Reduced startup time by running post-healthcheck tasks concurrently, thanks to @jonesrussell
- Faster ddev stop: Fixed a bug in the webserver startup script that added an unnecessary ~10-second delay
- MariaDB 12.3 LTS support
- Podman and Docker rootless are no longer experimental: Both are now stable and ready for general use:
- macOS (Podman rootless)
- Linux/WSL2 (Docker rootless)
- Linux/WSL2 (Podman rootless)
Breaking Changes
- Remove support for XDG_CONFIG_HOME, replaced by DDEV_XDG_CONFIG_HOME. Support for ~/.config/ddev on Linux is unchanged. This change was needed because some IDEs, such as PhpStorm, don't always see XDG_CONFIG_HOME set in the terminal (see this issue), which caused the IDE to recreate the ~/.ddev directory repeatedly
- Use stricter permissions for world-writable directories inside ddev-webserver. If you had post-start hooks that wrote to /usr/local/bin, update them to use ~/.local/bin instead, thanks to @AkibaAT
- Move N_PREFIX from /usr/local to /usr/local/n. This shouldn't affect most people, unless you referenced a full path such as /usr/local/bin/npm - the new location is /usr/local/n/bin/npm, or simply use npm without a full path
- Remove the ddev dr alias for ddev drush, since dr is now a built-in command for Drupal 11.4+
Features
- Node.js improvements: preserve nodejs_version in .ddev/config.yaml, and install several Node.js versions with n install inside the web container
- Docker rootless on Linux no longer requires no-bind-mounts; disable it with ddev config global --no-bind-mounts=false
- Support the gvisor-tap-vsock network driver in Docker rootless
- Add new ddev dr command for Drupal 11.4+
- Allow using Mutagen together with ddev config global --use-hardened-images=true
- ddev version and ddev config now work even when Docker isn't running or is broken, and ddev poweroff shows progress output instead of appearing to hang
- Improve ddev list and ddev describe layout on narrow terminals
- Add OSC 8 terminal hyperlink support to ddev list, ddev describe, ddev add-on list, and ddev add-on search
- Show human-readable output when checking available disk space, thanks to @wolcen
- Always pull images when using ddev start --no-cache
- Respect the COMPOSER_NO_BLOCKING environment variable from the host in ddev composer
- Add ddev config global --docker-buildx-version to specify which Docker Buildx version to use (advanced use only)
- Respect docker-buildx installed via snap on Linux
- Support Debian, Kali, and eLxr WSL2 distros in the Windows installer, and avoid installing docker-ce over an existing Docker Desktop docker binary
- Add ddev utility addon-update-checker command for add-on maintainers
- Add #ddev-interactive option for add-on actions, thanks to @AkibaAT
- Add x-ddev.omit-ddev-labels extension to skip com.ddev.* label injection for specific services
- Support the Flatpak user binary for DBeaver on Linux, thanks to @nickchomey
- Add a quickstart for Drupal 12 (HEAD), thanks to @rpkoller
- Add troubleshooting for Let's Encrypt certificate failures, thanks to @jonpugh
- Add TYPO3 special handling for ddev share
Bug Fixes
- Windows installer: fix installation on WSL2 Ubuntu 26.04, which previously failed due to the deprecated wslu package
- Suppress 404 logs for favicon.ico and robots.txt; in some cases these caused Nginx to run a PHP script twice
- Prevent recursion in global web command wrappers
- Use the correct settings.ddev.php for each Drupal version
- Fix a bug where .ddev/apache/apache-site.conf went missing when using a custom Nginx config
- Detect a missing docker CLI, which is required when using Mutagen
- Limit the ENV HOME="" workaround for MySQL 8.x to the database context only
- Podman and macOS: restrict the keep-id userns setting to Linux only
- Use the nodejs_version set during the ddev-webserver image build; if you installed global npm packages in post-start hooks, move them to extra Dockerfiles instead
- Use wrapper scripts in ddev-dbserver to avoid mysql deprecation warnings with MariaDB 11.x+
- Warn when the CAROOT environment variable is set but the mkcert CA files (needed for HTTPS in your browser) are inaccessible
- Normalize OSTYPE detection on Linux, thanks to @Mikee-3000
- Avoid double-sourcing bashrc configuration in ddev ssh
- Skip OS-generated metadata files (.DS_Store, Thumbs.db, desktop.ini) during custom-config detection and in .ddev/.gitignore
- Restore path autocompletion for ddev add-on get
- Don't prompt to run ddev poweroff after updating ddev-ssh-agent
- Fix a case typo in ddev sequelace so Sequel Ace is detected on case-sensitive macOS filesystems, thanks to @mficzel
Internal Changes
- Migrate DDEV documentation from Material for MkDocs to Zensical
- Upgrade Bubble Tea (ddev tui) to v2
- Add light/dark/system preference variants for the brand logo
- Remove automated testing on macOS Intel; macOS amd64 binaries are still built and distributed, only CI testing on Intel hardware is removed
- Add automated testing for macOS Podman rootless
- Improve the test embargo system for Go, Bats, and CI workflows; tests can now be skipped when needed
- Add custom GitHub workflows to run tests on branches without opening a PR
- Rework local HTTP test helpers for clearer failure output
- Remove the build step for the Docker image used in ddev auth ssh
- Bump all Go dependencies
Minor Updates
- PHP 8.4.22 and 8.5.7
What's Changed
- test: Reenable Drupal 12 bats test (#8346) [skip ci] by @rpkoller in #8346
- chore(claude): fix PreToolUse hook matcher for git commit static analysis (#8345) [skip ci] by @stasadev in #8345
- docs(add-ons): Minor updates to creating-add-ons.md by @rfay in #8347
- perf: combined startup time optimizations, for #8096 by @jonesrussell in #8145
- fix(windows): remove wslu from installer, fixes #8326 by @stasadev in #8351
- fix(webserver): replace phar.io/filippo.io links with GitHub releases, improve Dockerfile, for #8012 by @stasadev in #8352
- docs(quickstart): add a quickstart for Drupal 12 (#8357) [skip ci] by @rpkoller in #8357
- feat(docker): always pull images with --no-cache by @stasadev in #8363
- fix(download-images): pull webserver image, for #8304 by @stasadev in #8358
- fix(start): use image digest for rebuild detection, fix rand and ssh-agent data races, for #8145 by @stasadev in #8359
- fix(test): skip TestCheckLiveConnectivityWithProject on Rancher/Colima/Lima, fix misleading WSL2 labels by @rfay in #8365
- docs(windows): add WSL2 installation step to Docker docs by @stasadev in #8355
- chore: fix claude hooks and update agent docs [skip ci] by @rfay in #8370
- chore: remove macOS amd64 CI testing (#8372) [skip ci] by @rfay in #8372
- fix(drupal): use configured project type for settings.php version selection by @rfay in #8366
- ci: run golangci-lint by @stasadev in #8375
- docs(mutagen): explain how to reset to the default mode, fixes #8367 by @silverham in #8368
- docs(configuration): Add ddev config --database=: example command (#8387) [skip ci] by @silverham in #8387
- build: bump fuxingloh/multi-labeler from 4 to 5 (#8385) [skip ci] by @dependabot[bot] in #8385
- docs: clarify --cleanup --name for single snapshot deletion (#8384) [skip ci] by @CallMeLeon167 in #8384
- docs(add-ons): add real example for bats testing (#8377) [skip ci] by @stasadev in #8377
- fix(commands): normalize $OSTYPE detection for linux, fixes #8382 by @Mikee-3000 in #8383
- docs: Add Xcode iOS simulator info (#8371) [skip ci] by @jamesmacwhite in #8371
- feat(utility): add ddev utility addon-update-checker command by @stasadev in #8373
- fix(add-ons): autocomplete for path by @stasadev in #8376
- test(wsl2): fix TestHostDBPort by @stasadev in #8391
- test(windows): fix TestUtilityAddonUpdateCheckerCmd, for #8373 by @stasadev in #8394
- docs(quickstart): Add description to Drupal Git clone example by @gitressa in #8395
- fix(ddev-webserver): ddev stop takes 10s due to bash deferring SIGTERM during foreground cat, fixes #8295 by @rfay in #8396
- docs: unify homeadditions path resolution and Composer auth.json handling by @eiriksm in #8400
- docs(providers): align --environment examples and flags, fixes #8402 by @stasadev in #8403
- test(share): improve cloudflared debug output on unmarshal errors by @rfay in #8398
- ci(github): reorganize test jobs, add custom workflow_dispatch, remove unused workflows by @stasadev in #8401
- feat(add-on): add #ddev-interactive option for actions, fixes #8155 by @AkibaAT in #8381
- refactor(tui): upgrade bubbletea/bubbles/lipgloss to v2 by @stasadev in #8404
- ci: add DDEV_EMBARGO_PHP_VERSIONS to skip specific PHP versions in TestPHPConfig [skip ci] by @rfay in #8407
- feat: use docker-compose library, optionally download docker-buildx, fixes #7915, for #8295 by @stasadev in #8234
- ci(docs): add stable docs branch workflow, fixes #7862 by @stasadev in #8408
- ci(forks): fetch variables from public-variables branch by @stasadev in #8410