Local development
The dev stack is one Compose file — docker-compose.dev.yml — that brings up the FrankenPHP app, a local libSQL server (sqld), MinIO, Vite HMR, and Reverb. Clone, copy the env file, and up -d.
Start the stack
cp .env.docker.dev.example .env.docker.dev
# fill in APP_KEY (see the comment in the file for the one-liner)
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev up -d
The migrate sidecar runs php artisan migrate --force once before the app starts. minio-init creates the filament bucket and sets anonymous download so unsigned AWS_URL GETs load in the browser.
Ports
| Service | URL |
|---|---|
| App (artisan serve) | http://localhost:8090 |
| Admin panel | http://localhost:8090/admin/login |
| Vite HMR | http://localhost:5173 |
| libSQL / Hrana over HTTP | http://localhost:8181 |
| MinIO API (S3) | http://localhost:9000 |
| MinIO console | http://localhost:9001 |
| Reverb (websockets) | http://localhost:8081 |
Host ports come from .env.docker.dev (HTTP_PORT, VITE_PORT, DB_HOST_PORT, MINIO_API_PORT, MINIO_CONSOLE_PORT, REVERB_HOST_PORT); the values above are the defaults.
First admin user
php artisan db:seed runs RoleSeeder, which creates the super_admin and user roles and assigns super_admin to test@example.com. To mint a second admin from a shell:
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev exec app \
php artisan tinker --execute="App\Models\User::factory()->create(['name'=>'Admin','email'=>'admin@example.com','password'=>Hash::make('password123')])->assignRole('super_admin');"
Repo layout
app/ is the Laravel + Filament root — the Dockerfile, artisan, Pint, and Pest all run inside it. The three Compose files and .env.docker.*.example live at the repo root. Git and docker compose run from the repo root; PHP/Composer commands run from app/ (or via docker compose … exec app).
Tests
Tests are hermetic: sqlite :memory:, array session/cache, and Storage::fake('s3'). No live MinIO, Redis, or Reverb is required, and the suite ignores the container's env vars.
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev exec app php artisan test
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev exec app vendor/bin/pint --test
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev exec app vendor/bin/phpstan analyse
From app/, the same steps are composer test, composer lint (Pint --test), and composer analyse (Larastan level 5).
Optional Redis
Reverb defaults to in-memory fan-out. To run more than one Reverb replica, enable Redis with the redis profile and set REDIS_URL / REVERB_REDIS / REVERB_SCALING_ENABLED=true:
docker compose -f docker-compose.dev.yml --env-file .env.docker.dev --profile redis up -d
composer test never starts or requires Redis.