0xdarkmatter/claude-mods/ddev-ops

Claude Code and agent skill by 0xdarkmatter/claude-mods

Trust tier 3
  • community
  • ext:[{"type":"plugin","description":"Custom plugin integration"}]
Source check pending

Checking that the SKILL.md file is still in the repository.

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.

Install

npx vskill@latest install 0xdarkmatter/claude-mods/ddev-ops

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

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

  1. Read the project before changing it: .ddev/config.yaml, any config.*.yaml,

ls -a .ddev/, then ddev describe (URLs, ports, services) and ddev version.

  1. Audit it from any directory, <skill-dir> being this skill's folder (the launcher

finds a working Python 3.8+, which matters on Windows where python3 is often a Store stub):

``bash bash "<skill-dir>/scripts/run-python.sh" "<skill-dir>/scripts/audit-ddev-config.py" /path/to/project bash "<skill-dir>/scripts/run-python.sh" "<skill-dir>/scripts/audit-ddev-config.py" /path/to/project --json | jq '.data[]' ``

Exit 10 means findings, sorted high to low (severity, check, file:line, detail); 0 means clean. --ignore <check> documents a deliberate exception.

  1. 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.

  1. 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.

  1. 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.

  1. 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".

  1. 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.

  1. Retired keys do nothing. DDEV loads config non-strictly:

mutagen_enabled: false and nfs_mount_enabled are ignored, not obeyed.

  1. `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.

  1. 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.

  1. Never hand containers your machine's credentials. Every process in them -

Composer and npm scripts included - can use what they reach.

  • No host SSH-agent forwarding: load one scoped key with ddev auth ssh -f <key>.
  • No compose mount of the Docker socket (full control of the host) or of your home

directory.

  • No agent logins or keys under .ddev/: the project, .ddev/ included, is mounted

into web.

  1. 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.

  1. 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.

  1. Review an add-on before installing it. Its Bash install actions run on your

machine. Prefer official ddev/ add-ons and pin --version.

  1. On Windows, keep projects inside the WSL2 filesystem, never under /mnt/c.
  2. Confirm with the user before destroying data. These destroy data:
  • ddev delete, ddev stop --remove-data, ddev start --reset-database;
  • ddev snapshot --cleanup, ddev clean, ddev push;
  • 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.

  1. 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

  • `ddev` is not a sandbox. Project host commands and exec-host hook tasks run on

your machine with your rights; a pre-start one runs on the first ddev start. In a repository you didn't write, audit first and show the user any host-hook or host-command finding before starting the project.

  • 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.

  • Name the container directory. ddev exec ignores the host folder you run it from;

pass --dir /var/www/html/<path>, or a plugin's suite runs against the project's config and development database.

  • Keep dumps out of your context: ask the database (ddev mysql -e '...'), never

read a dump or snapshot (database.md).

  • 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.

Details, the destroys-data table and worktree setup: automation-and-worktrees.md.

Route by task

TaskRead
Existing repo on a new machine, new project, version pinning, CI parity, Composer, what to commit, env files, upgrading DDEVconfig-and-env.md
Scripting DDEV, JSON output, commands that destroy data, several git worktrees (OAuth callbacks, webhooks), renaming or moving a project, AI agents inside DDEVautomation-and-worktrees.md
Import/export, snapshots, seed and reset, changing engine, ddev pull recipes, sanitised data, uploads from production, dumps and agentsdatabase.md
Slow project, Mutagen, upload_dirs, WSL2, choosing a Docker providerperformance.md
Add-ons (Redis, search, cron), commands, hooks, daemons, nginx/Apache config, extra services, networking between projects, PHP ini, SSH keysextending.md
Node.js version, npm/pnpm/yarn, dev-server ports and daemonsfrontend-node.md
Craft + Vite HMR not connecting (CORS, allowed hosts, the port in four places)frontend-upgrade-ops' references/craft-vite-twig.md
Xdebug, XHGui profiling, Mailpit, ddev share, hostnamesdebugging-sharing.md
Something is broken: Docker, ports, router, TLS, disk, DNS, Mutagentroubleshooting.md

Everyday commands

TaskCommand
Start, stop, restart, everything offddev start, ddev stop, ddev restart, ddev poweroff
What is running and whereddev describe (-j for JSON), ddev list, ddev launch
Shell, one-off commandddev ssh, ddev exec <cmd>
Logsddev logs, ddev logs -s db, ddev logs -f
Database in and outddev import-db --file=x.sql.gz, ddev export-db --file=x.sql.gz
Snapshot and restoreddev snapshot --name=<unique>, ddev snapshot restore --latest
Data from hostingddev pull <provider> (--skip-files, --skip-db, -y)
Xdebug, profilerddev xdebug on (off, status), ddev xhgui on, ddev xhgui launch
Mail catcherddev mailpit
Add-onsddev add-on get <owner>/<repo>, ddev add-on list --installed, ddev add-on update
Effective config, custom filesddev utility configyaml --full-yaml, ddev utility check-custom-config
Health checksddev utility diagnose, port-diagnose, tls-diagnose, mutagen-diagnose, xdebug-diagnose
Rebuild imagesddev start --no-cache, ddev utility rebuild

Scripts and assets

ResourceUse
scripts/audit-ddev-config.py [DIR] [--json] [--ignore CHECK]Read-only audit of .ddev/; details below the table
scripts/check-ddev-facts.py --offlineAfter editing facts or prose: assets/ddev-facts.json vs this skill's text
scripts/check-ddev-facts.py --liveWeekly: newest DDEV release, docs defaults, built-in commands, PHP/Node.js end-of-life floors. Exit 7 = a source was unreachable (advisory)
scripts/run-python.shLaunches either script with the first real Python 3.8+ (python3, python, py)
assets/ddev-facts.jsonThe facts both scripts share - bump values, prose and the "Versions verified" note together
assets/sanitized-pull.yaml.exampleDatabase-only provider recipe for a sanitised dump: no files stanza, no push stanzas

The auditor:

  • Checks:
  • versions: php-unpinned, php-out-of-range, php-eol, db-unpinned, node-eol,

composer-v1;

  • config: obsolete-key, unknown-key (against DDEV's own config schema),

perf-mode-committed, router-ports-committed, xdebug-committed, name-in-worktree;

  • folders and commands: upload-dir-misplaced, upload-dir-outside,

shadowed-command, crlf-command;

  • the host: host-command, host-hook, ssh-agent-forwarded,

docker-socket-mounted, home-mounted;

  • safety: provider-push, provider-files-noop, committed-secret (env, config,

compose and web-server files), credential-file, local-file-committed (reads git's index; never runs a git or fsmonitor command the audited repository supplies).

  • Exit codes: 0 clean, 10 findings, 3 no .ddev/config.yaml, 4 unreadable config,

2 usage.

  • It reads config the way DDEV does: overrides merge, lists append. It skips DDEV's

own generated recipes and never prints a secret value.

Boundaries

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
51
Repository forks
7
7-day trend score
25

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Extension points

  • pluginCustom plugin integration

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/0xdarkmatter/claude-mods/ddev-ops/badge)](https://verified-skill.com/skills/0xdarkmatter/claude-mods/ddev-ops)

Something wrong with this skill or its page? Tell us.