Local Development

Docker services, Make commands, and daily development workflow

Local Development

Docker Services

docker compose up -d
ServiceContainerAccessPurpose
PHP (app)phphttp://localhostSymfony + FrankenPHP
PostgreSQLdatabaselocalhost:5432Database
Redisredislocalhost:6379Cache + message queue
Mailpitmailerhttp://localhost:8025Email testing

Make Commands

CommandDescription
make testRun all tests (unit + functional)
make test-unitRun unit tests only
make test-functionalRun functional tests only
make phpstanRun PHPStan static analysis
make csfixFix code style with PHP CS Fixer
make bashOpen a shell in the PHP container
make stripe-sync-plansSync plan config to Stripe
make generate-jwt-keysGenerate JWT key pair

Database

Run Migrations

docker compose exec php bin/console doctrine:migrations:migrate

Create a New Migration

After modifying an ORM mapping file:

docker compose exec php bin/console doctrine:migrations:diff

Reset Database

docker compose exec php bin/console doctrine:database:drop --force
docker compose exec php bin/console doctrine:database:create
docker compose exec php bin/console doctrine:migrations:migrate --no-interaction

Never use doctrine:schema:update --force. Always use migrations.

Running Tests

# All tests
make test

# Unit tests only
make test-unit

# Functional tests only
make test-functional

# Single test file
docker compose exec php vendor/bin/phpunit tests/Unit/UserManagement/SignUpHandlerTest.php

# Single test method
docker compose exec php vendor/bin/phpunit --filter testMethodName

Code Quality

# Static analysis
make phpstan

# Code style (auto-fix)
make csfix

Run both before pushing to avoid CI failures.

Viewing Emails

In development, all emails are caught by Mailpit. Open http://localhost:8025 to view sent emails — registration confirmations, password resets, etc.

Console Commands

CommandDescription
bin/console app:user:promote-admin {email}Promote a user to admin role
bin/console app:stripe:sync-plansSync plan definitions to Stripe
bin/console app:stripe:sync-plans --dry-runPreview sync without making changes
bin/console lexik:jwt:generate-keypairGenerate JWT public/private key pair
bin/console doctrine:migrations:migrateRun pending migrations

All commands should be run inside the PHP container:

docker compose exec php bin/console <command>

API Documentation

The interactive Swagger UI is available at http://localhost/api/doc during development. The raw OpenAPI spec is at http://localhost/api/doc/openapi.yaml.