Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Use when a project has a .ddev/ folder or needs one: DDEV setup on a new machine, version pinning, config.local.yaml and .ddev/.env files, database import, snapshots, ddev pull and sanitised data, slow Mutagen or WSL2 sites, add-ons (Redis, Solr, cron), commands and hooks, Vite ports, Xdebug, ddev share, port conflicts, several git worktrees at once, script…
Independent GitHub snapshot · Automated classification · Original documentation governs
name: ddev-ops
description: "Use when a project has a .ddev/ folder or needs one: DDEV setup on a new machine, version pinning, config.local.yaml and .ddev/.env files, database import, snapshots, ddev pull and sanitised data, slow Mutagen or WSL2 sites, add-ons (Redis, Solr, cron), commands and hooks, Vite ports, Xdebug, ddev share, port conflicts, several git worktrees at once, scripting DDEV (describe -j), disk cleanup, upgrades and troubleshooting. Audits .ddev/ for team-breaking mistakes."
license: MIT
allowed-tools: "Read Edit Write Bash Glob Grep"
metadata:
author: claude-mods
related-skills: "craftcms-ops, security-ops, frontend-upgrade-ops, docker-ops, web-perf-ops, package-manager-ops"
DDEV Operations
Why: DDEV is the local stack behind most PHP agency sites, and it fails quietly: a
default that moved under an unpinned project, a key it silently ignores, one developer's
setting committed for the whole team.
Versions verified 2026-10-05 against DDEV v1.25.4. Fast-moving facts (defaults, PHP and
Node.js end-of-life floors, built-in command names) live once in
assets/ddev-facts.json; scripts/check-ddev-facts.py --offline fails if this skill's
prose and that file disagree, and --live (weekly) fails when DDEV moves.
Start here
Read the project before changing it:.ddev/config.yaml, any config.*.yaml,
ls -a .ddev/, then ddev describe (URLs, ports, services) and ddev version.
Audit it. From the skill folder (the launcher finds a working Python 3.8+, which
matters on Windows where python3 is often a Store stub):
Exit 10 means findings, sorted high to low (severity, check, file, detail); 0 means
clean. --ignore <check> documents a deliberate exception.
Run everything through DDEV - ddev composer, ddev php, ddev npm,
ddev exec - so commands use the container's PHP and Node, not the host's.
Snapshot before anything risky, with a unique name:
ddev snapshot --name=before-<task>-$(date +%Y%m%d%H%M%S). A reused name saves
nothing and still exits 0.
Ask before destroying data (Hard rule 11).
Hard rules
Rules 2, 3, 4, 6, 8 and 12 were each seen in a 2026-10-05 read of 36 DDEV-based agency
repositories; the rest are quiet failures DDEV's own docs and source describe.
Pin php_version and database to production. Unpinned projects follow DDEV's
defaults, which move: v1.25.0 switched PHP 8.3 to 8.4 and MariaDB 10.11 to 11.8.
Also pin nodejs_version and composer_version: "2".
Per-developer settings never go in config.yaml.
That means performance_mode, router_http_port/router_https_port,
xdebug_enabled: true, bind_all_interfaces and host_db_port.
They belong in .ddev/config.local.yaml or ddev config global.
Project values beat global ones, so a committed value pins every teammate.
Git ignores the .local files only after DDEV has run in that checkout, because
its .ddev/.gitignore isn't committed. Add .ddev/config*.local.y*ml and
.ddev/.env*.local to the project root's .gitignore.
Retired keys do nothing. DDEV loads config non-strictly:
mutagen_enabled: false and nfs_mount_enabled are ignored, not obeyed.
upload_dirs resolve from the docroot. With docroot: web, storage means
web/storage; folders beside the docroot are ../storage and ../node_modules.
Setting the list replaces the type's defaults; override files append to it.
No secrets in committed .ddev/.env* files. Use the .local twin
(.ddev/.env.web.local, v1.25.4+), kept out of git as rule 2 says. Commit a
.example with git add -f, since DDEV's .gitignore hides *.example.
Never forward the host SSH agent into containers. Every process in them -
Composer and npm scripts included - could sign with every key the agent holds. Load
one scoped key with ddev auth ssh -f <key>.
Pull sanitised data; never push to production.
Anonymise where the data lives and pull the result. No raw production personal data
on laptops.
Delete db_push_command/files_push_command from your own recipes that can reach
production.
A files_pull_command that fetches nothing makes ddev pull empty the upload
directory, and the pull still exits 0. Omit the stanza instead.
Don't keep project copies of DDEV's built-in commands (craft, npm,
artisan, wp...). A project command shadows the built-in and freezes an old
version. Command files must have LF endings: DDEV skips CRLF ones with only a warning.
Review an add-on before installing it. Its Bash install actions run on your
machine. Prefer official ddev/ add-ons and pin --version.
On Windows, keep projects inside the WSL2 filesystem, never under /mnt/c.
Confirm with the user before destroying data. These destroy data:
ddev import-db and ddev import-files, which empty their target first;
docker volume prune -a, which deletes stopped projects' databases.
ddev poweroff stops everyone's projects.
Several checkouts need distinct project names. A committed name: makes every git
worktree claim the same project. Omit it, or override it in config.local.yaml.
Driving DDEV from a script or agent
Never run bare ddev (it opens a dashboard) or flagless ddev config (it asks
questions). Pass --file/--source to imports and -y to anything that prompts.
Read state as JSON:ddev describe -j | jq -r '.raw.primary_url' (also
.raw.status, .raw.dbinfo.published_port); ddev list -j;
ddev launch --print-url.
Single-quote ddev exec commands that contain $, pipes or redirects, so they
expand inside the container.
Exit 0 isn't always success: a duplicate ddev snapshot name and
ddev add-on remove leaving files behind both exit 0.
folders and commands: upload-dir-misplaced, upload-dir-outside,
shadowed-command, crlf-command;
safety: ssh-agent-forwarded, provider-push, provider-files-noop,
committed-secret, local-file-committed (reads git's index; never runs a git or
fsmonitor command the audited repository supplies).
Install commands, lockfiles, .nvmrc/engines agreeing with DDEV's Node and PHP
package-manager-ops
Compose syntax for a hand-written extra service; Dockerfiles generally
docker-ops
Page speed of the site itself
web-perf-ops
Never write a real-looking project hostname in examples: say "the project URL from
ddev describe".
Sources
DDEV docs: docs.ddev.com, source docs/content/users/ at tag v1.25.4.
DDEV release notes: v1.25.0-v1.25.4.
DDEV source:pkg/ddevapp/ (config.go, provider.go, ddevapp.go,
upload_dirs.go, craftcms.go), pkg/settings/viper.go and
cmd/ddev/cmd/commands.go.
Also: the add-on registry (addons.ddev.com) and endoflife.date.
Read 2026-10-05 and re-checked by an independent accuracy review on 2026-10-06. What
the references mark "Observed" was reproduced that day in throwaway projects on DDEV
v1.25.4 (Docker Desktop, WSL2). DDEV
publishes no agent skill for its users; its own repository's AGENTS.md and .claude/
serve people contributing to DDEV.