Local setup¶
The recommended development setup uses DDEV
with the dns module symlinked into a Drupal sandbox via a Composer
path repository. This is the same pattern used for sister contrib
modules in the same workflow (e.g. field_ipaddress).
Layout¶
Side-by-side directories on the host:
~/src/
├── sandbox/ # any DDEV-driven Drupal site you want to test against
└── dns/ # this module's checkout
Substitute your own paths and project names below; the directory structure is what matters, not the names.
Wire dns into the sandbox¶
In the sandbox repo, add a DDEV docker-compose addon that mounts the module's host directory into the container:
# .ddev/docker-compose.dns.yaml
services:
web:
volumes:
- ../../dns:/var/www/dns
Then add a Composer path repository pointing at the in-container mount path, and require the module from it:
// composer.json
{
"repositories": [
{
"type": "path",
"url": "/var/www/dns",
"options": {
"symlink": true
}
}
// …other repos…
],
"require": {
"drupal/dns": "@dev"
// …
},
"config": {
"preferred-install": {
"drupal/dns": "source"
}
}
}
Bring it up:
ddev restart # picks up the new mount
ddev composer require drupal/dns:@dev # symlinks
ddev drush en dns -y
Verifying class autoload¶
If you add a new class and Drupal can't find it, the diagnostic that nails 90% of cases:
ddev drush php:eval '
$fqn = "Drupal\\dns\\YourNewClass";
$loader = require DRUPAL_ROOT . "/autoload.php";
echo "exists: " . (class_exists($fqn) ? "YES" : "NO") . "\n";
echo "file: " . var_export($loader->findFile($fqn), true) . "\n";
echo "psr4: " . var_export($loader->getPrefixesPsr4()["Drupal\\dns\\"] ?? "NOT REGISTERED", true) . "\n";
'
If this returns YES from CLI but the web request still says "Class does not exist," it's almost always the Drupal compiled-container cache (especially under Redis). Flush it:
ddev redis-cli FLUSHALL
ddev drush cr
Cache discipline¶
Most of the iteration headaches in development come from stale caches. Standard reset that catches everything:
ddev redis-cli FLUSHALL
ddev drush cr
This is what drush cr should do on its own, but Redis-backed
bootstrap container caches aren't always cleared by it. The
combination is reliable.
Testing the documentation site locally¶
The simplest path uses the Metadrop/ddev-mkdocs
addon to run the mkdocs server inside DDEV — no Python toolchain on
the host. From the dns module's checkout:
ddev get Metadrop/ddev-mkdocs
ddev restart
ddev mkdocs serve
DDEV prints the URL on startup (typically a *.ddev.site host).
Live-reloads on save. The addon isn't actively maintained but works
reliably for local previewing of the mkdocs site.
If you'd rather run mkdocs on the host directly:
pip install mkdocs-material
mkdocs serve
Opens at http://localhost:8000/.