Running Claude Code against Magento safely with a Docker sandbox.
Why bother sandboxing Claude Code if I trust the model?
You're not sandboxing the model — you're sandboxing the commands the model proposes. A wrong rm -rf var/cache on your host hits a symlinked storefront. A composer require on the wrong terminal updates the live VPS. A test that runs bin/magento config:set writes into app/etc/env.php and pollutes your dev DB. The sandbox isolates blast radius. Standard setup: Docker container with the codebase mounted read-write, vendor/ mounted read-only, MySQL on a throwaway volume, and a fresh DB dump restored on every container start.
Was this helpful?
How do I configure the Bash allowlist for a Magento repo?
In .claude/settings.json, under permissions.allow. Pre-approve the read-only commands you actually use: Bash(bin/magento module:status), Bash(bin/magento config:show:*), Bash(composer show *), Bash(git status), Bash(git diff *), Bash(php -l *), Bash(vendor/bin/phpcs *), Bash(vendor/bin/phpstan *). Leave write commands unapproved (setup:upgrade, cache:clean, composer require) so they prompt — one click is fine, autopilot on writes is not. The /fewer-permission-prompts skill scans your transcripts and proposes an allowlist automatically.
Was this helpful?
Best way to make vendor/ write-protected during a Claude session?
Two options. Quick: chmod -R a-w vendor/ at session start, undo it before composer install. Robust: mount vendor/ as a read-only Docker volume in docker-compose.yml: ./vendor:/var/www/html/vendor:ro. Add a PreToolUse hook that blocks any Edit or Write with a path matching ^vendor/: returns { "decision": "block", "reason": "vendor/ is read-only" }. The hook is the belt; the chmod is the suspenders. The model will try to edit vendor on its own occasionally — especially when chasing a bug; the hook stops it cold.
Was this helpful?
Can I get setup:upgrade to run automatically after di.xml changes?
Yes — PostToolUse hook scoped to Edit and Write. In .claude/settings.json: {"PostToolUse": [{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "if echo $CLAUDE_TOOL_INPUT | grep -qE 'di\\.xml|module\\.xml|db_schema'; then docker exec magento bin/magento setup:upgrade; fi"}]}]}. Two warnings: (a) setup:upgrade is slow (~30s on a fat install) — consider running setup:di:compile alone for di.xml-only edits; (b) the hook command runs synchronously and blocks the next tool call, so a session where you're rapid-firing edits will feel like syrup. Tune the matcher tight.
Was this helpful?
How do I stop Claude from accidentally connecting to my production DB?
Don't put production credentials in app/etc/env.php on the dev box — ever. Use a separate app/etc/env.php.prod that lives only on the live VPS. In the Docker dev image, point env.php at db (the docker-compose hostname), not at the live host. Add a PreToolUse hook that greps any Bash command for production hostnames or admin URLs and blocks: echo $CLAUDE_TOOL_INPUT | grep -qE 'prod\\.example\\.com|72\\.62\\.247' && exit 2. Belt-and-suspenders again — one rule for the network layer, one rule for the agent layer.
Was this helpful?
Request a quote
I'll reply within 2-4 hours business with a written quote and timeline.