DDEV is a tool that facilitates local Web development by providing rapid access to an environment. It was created to help developers work on their projects efficiently and productively. No need to search for project information (PHP version, server used on the production environment, node version, required libraries, etc.).
DDEV is based on Docker, a container virtualization platform that enables applications to be isolated in lightweight, portable containers. This approach enables developers to work with isolated development environments, without the risk of interfering with other projects or the host computer's operating system.
Easy to install and use, all that's required is to create a YAML configuration file to define the project parameters so that the appropriate image can be downloaded. Modules and/or services can be specified and added to the environment. If required, commands can be executed after start-up.
Installation
To install DDEV, you must first install Docker. You can follow the installation instructions in the documentation. Once you've finished, run the ddev -v command to confirm that DDEV is up and running.
Procedure
To develop a site using DDEV, first generate the initial configuration by running the ddev config command.
You will then be asked to answer three questions. For each question, DDEV will propose a value according to the project. If it's correct, press the "Enter" key to validate it and move on to the next question. Otherwise, enter the desired value.
- The project name (used in the URL address of the site).
E.g.: the project named "globalia" will be accessible at the addresshttps://globalia.ddev.site - Docroot location (where the website is served).
e.g. public, web or empty - Project type: craftcms, laravel, php, wordpress (or other)
A file will be created in .ddev/config.yaml. Review the configuration in the "Set up" section of this article. Once completed, run the ddev start command to start instantiating the container. If all goes well, the site URL will be displayed and accessible in a browser. However, you'll need to perform a few additional operations before the site is up and running.
We usually use the development environment's database when we develop locally1. To connect to it, we need to keep the same default configuration files, depending on the CMS in place:
WordPress: wp-config.php
Define constants WP_HOME et WP_SITEURL for https://globalia.ddev.site
Craft 3 | Laravel: .env
Craft 2: craft/config/db.php et craft/config/general.php
We recommend that you enable the following option to prevent DDEV from constantly overwriting values in the environment configuration file (wp-config.php, .env) → disable_settings_management: true.
Warning: often, the db alias is assigned to the host. This value is already used by DDEV, which will cause connection problems. So either change the alias, or enter the internal IP address directly.
To install the front-end and back-end dependencies, we need to enter the container. To do this, run ddev ssh.
You can validate the node version with node -v. It should be the same as the one you specified in the configuration file. You can then run groots install or npm install, depending on the project, to install the front-end dependencies. Afterwards, make sure an initial gulp runs without error. Dependencies in node 6 will often cause SSL certificate problems, in which case you'll probably need to upgrade to version 10.
On the back-end, the correct versions of PHP (php -v) and composer (composer -V) will be selected. All you have to do is go to the location of the composer.json file to run composer install.
All that's left to do is test it by visiting the site. Redirects or additional instructions may be required for proper operation. See the "Server" section of this article for more details.
If all is well, you can version the configuration file in .git.
1 - This depends on the project, of course, as sometimes it's better to have your own local database (especially if you're doing a lot of testing). See the Local database section of this article for more information on this subject.
Setup
Several parameters can be configured in the config.yaml file to obtain the desired development environment. This should reflect the production environment as closely as possible.
- PHP version (from 5.6 to 8.2 - the default version is 8.0 (as of May 2023))
- Project type (WordPress, Craft, php, etc.)
- Server type (apache | nginx | php-fpm) → The vast majority of sites in production run on nginx. See the "Server" section of this article for more details.
The database to be used (SELECT @@version; under the right server to find out which version of MariaDB is being used).
We often use the development database. In this case, omit the db container and deactivate the dba container (PHPMyAdmin - it will not be accessible). Alternatively, DDEV offers an easy way of importing a local database (more details in the "Local database" section of this article).
At the time of writing, node versions 14, 16 and 18 are available. Version 16 is assigned by default to the nodejs_version option. If you wish to use another version, you must specify it in the commands that will be executed after startup. Here's an example of using version 10:
hooks:
post-start:
- exec-host: "ddev nvm install 10"
- exec-host: "ddev nvm use 10"
For compilation with front-end tools such as groots, we add the build-essential package as standard. Depending on the project, the python2, libgl1 and libxi6 packages may also be required.
It should be noted that as soon as a change is made in the config.yaml file, the ddev restart command is required for the change to take effect.
Here's a complete example of DDEV configuration (config.yaml obtained by running ddev config):
name: globalia
type: wordpress
docroot: wordpress
php_version: "7.4"
webserver_type: nginx-fpm
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
additional_hostnames: []
additional_fqdns: []
database:
type: mariadb
version: "10.3"
nfs_mount_enabled: false
mutagen_enabled: false
use_dns_when_possible: true
composer_version: "1"
web_environment: []
disable_settings_management: true
omit_containers: [db, dba, ddev-ssh-agent]
webimage_extra_packages: [build-essential, python2, libgl1, libxi6]
hooks:
post-start:
- exec-host: "ddev nvm install 10"
- exec-host: "ddev nvm use 10"
The comments at the bottom of this file indicate which parameters can be modified and how.
Local Database
Sometimes it's better to have your own local database, especially if you do a lot of testing. All you need is a database dump (file) to import with the ddev import-db command. Be sure not to omit db (and dba if you want PHPMyAdmin) from the omit_containers option. All login information (DB_NAME, DB_USER, DB_PASSWORD and DB_HOST) must be set to db. It is also possible to export the database with the ddev export-db command.
mkcert
mkcert is a simple tool for creating valid local development certificates. It requires no configuration. Here are the main features, depending on your operating system.
Windows:
Before proceeding, you need to close any code-editing software (PHPStorm, VS Code). Then run the command wsl shutdown.
You have two options:
- Copy certificate from Windows to WSL
Install Chocolatey: https://chocolatey.org/install#individual
Execute the proposed command in PowerShell as administrator:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
When finished, run :
choco install -y mkcert
mkcert -install
Inserts a WSLENV environment variable to use the certificate:
$env:CAROOT="$(mkcert -CAROOT)"; setx CAROOT $env:CAROOT; If ($Env:WSLENV -notlike "*CAROOT/up:*") { $env:WSLENV="CAROOT/up:$env:WSLENV"; setx WSLENV $Env:WSLENV }
A reboot is required to complete the installation. - Copy the WSL mkcert certificate and install it under Windows
Start powershell or cmd as administrator
wsl --list --running
```
Windows subsystem distributions for Linux :
Debian (default)
```
wsl mkcert -CAROOT
```
/home/username/.local/share/mkcert
```
certutil -addstore -f "ROOT" \wsl$\Debian\home\username\.local\share\mkcert\rootCA.pem
Note: If you are running Ubuntu, your files should be accessible from :
\wsl$\Ubuntu
Linux:
sudo apt install libnss3-tools
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert
mkcert -install
MacOS :
Just initialize it once with the following command:
mkcert -install
WordPress Multisite
A few additional steps are required to develop a WordPress site with multisite functionality enabled.
In the following explanations, the "My Site" site will be taken as an example, using the development environment database.
To indicate the access route to our new development environment, we need to redirect the site domains (from the site table) to the local machine. This is done by editing the hosts file, located here:
Windows: C:\Windows\System32\drivers\etc\hosts
Mac and Linux: /etc/hosts
You can list all sites on a single line or on several lines:
127.0.0.1 monsite.globaliadev.com soussite-monsite.globaliadev.com
They must also be added to the additional_fqdns option:
additional_fqdns: [monsite.globaliadev.com,
soussite-monsite.globaliadev.com]
Des rewrites sont également nécessaires. Si le serveur est nginx, créer le fichier wordress_multisite.conf sous .ddev/nginx :
if (!-e $request_filename) {
rewrite ^(/[^/]+)?(/wp-.*) $2 break;
rewrite ^(/[^/]+)?(/.*\.php) $2 break;
}
If the server is apache, the .htaccess to docroot should contain the necessary instructions. Here's an example:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
</IfModule>
Server
If you're working on one or more older projects, Apache may already be running on your computer. This must be stopped before ddev can be launched, as it listens on port 443 for https requests. To do this, run :
sudo systemctl stop apache2.
Additional configurations (such as rewrite) are sometimes required for sites running under nginx. DDEV automatically reads all files ending in .conf in the nginx folder (which you must create).
For example, rewrites are required for WordPress "Mon Site" multisites. Under .ddev/nginx, the file wordress_multisite.conf:
if (!-e $request_filename) {
rewrite ^(/[^/]+)?(/wp-.*) $2 break;
rewrite ^(/[^/]+)?(/.*\.php) $2 break;
}.
When development is complete, we strongly recommend that you stop the container by running ddev stop to free up resources.
Debugging
Debugging is easy with the xdebug tool. It is installed by default in the container, but for performance reasons it is disabled by default. It can be activated at startup in the configuration (config.yaml) or by executing the ddev debug command (default value on) in the terminal. To disable it, ddev xdebug off.
In PHPStorm, simply activate Run / Start Listening for PHP Debug Connections so that breakpoints are taken into account when the site is loaded. The debugging bar will appear in the bottom left-hand corner.
Integration in PHPstorm
If you're developing with PHPStorm, you'll need to install the DDEV Integration plugin will enable you to use DDEV's functionalities from within it. Among other things, you'll be able to open the DDEV container to run commands, take advantage of configuration suggestions and much more.
Emails
As far as e-mail is concerned, DDEV is ideal for development, as none leaves the container. In fact, they are intercepted by MailHog. So there's no risk of accidentally sending e-mails when testing on this environment.
To view e-mails, run ddev launch -m.
You can also find out the URL by running ddev status. A port is added to the website URL (ex. : https://globalia.ddev.site:8026).
Frequent Requests
ddev: List of available commands
ddev debug on|off: Enables or disables xdebug
ddev launch: Opens the website in a browser
ddev launch -m: Opens the mailbox in a browser
ddev list: Displays all DDEV projects and their status
ddev logs: View error history
ddev poweroff: Stops all projects and containers
ddev restart: Restarts the container (required when modifying configuration)
ddev ssh: Allows access to container
ddev status: Lists services and their status for the site where the command is executed
ddev start: Starts the container
Need a hand with this or interested in joining a team of enthusiasts? Nancy, our back-end developer and the author of this article, can help. Contact us!