# Local dev / staging stack Isolated Directus **11.17.4** with its own Postgres and volumes. Nothing is shared with the prod instance (separate containers, volumes, and port **8057**). ## Run ```bash # from the project root ./dev/sync-extension.sh # build + copy dist/package.json into dev/extension docker compose -f dev/compose.dev.yml up -d ``` Admin: `http://localhost:8057` — `admin@example.com` / `admin12345`. The extension is loaded from `dev/extension` (bind mount). Check: ```bash docker logs image-previews-dev-directus-1 | grep -i "loaded extensions" ``` ## After changing source ```bash ./dev/sync-extension.sh docker compose -f dev/compose.dev.yml restart directus ``` (`EXTENSIONS_AUTO_RELOAD` is on, but a restart is the reliable path. Never `rm -rf dev/extension` — it breaks the bind mount.) ## Smoke test ```bash BASE=http://localhost:8057 TOKEN=$(curl -s -X POST "$BASE/auth/login" -H 'Content-Type: application/json' \ -d '{"email":"admin@example.com","password":"admin12345"}' | jq -r '.data.access_token') curl -s "$BASE/image-previews/status" -H "Authorization: Bearer $TOKEN" | jq . curl -s -X POST "$BASE/files" -H "Authorization: Bearer $TOKEN" -F "file=@dev/seed/test.jpg" | jq '.data | {id,filename_disk}' docker exec image-previews-dev-directus-1 sh -c "ls -1 /directus/uploads | grep '__' | sort" ``` ## Stop / reset ```bash docker compose -f dev/compose.dev.yml down # stop, keep data docker compose -f dev/compose.dev.yml down -v # stop and wipe DB + uploads ```