Symfony 8 / PHP 8.5 showcase app in a devcontainer. App code lives in src/ExampleApp/
(PSR-4 namespace ExampleApp\) — standard Symfony layout, don't restructure it.
Human-facing documentation lives in docs/ (indexed from README.md) — keep it in sync
when changing services, tasks, env vars, or QA tooling.
All compose services share the app container's network namespace — connect via 127.0.0.1,
never a service hostname:
| Service | Address |
|---|---|
| PostgreSQL 18 (default DB) | 127.0.0.1:5432 (symfony/secret) |
| MySQL 8.4 | 127.0.0.1:3306 (symfony/secret) |
| Redis 8 | 127.0.0.1:6379 |
| Mailpit | SMTP 127.0.0.1:1025, web UI localhost:8025 |
Upgrading from PostgreSQL ≤17: recreate the data volume —
docker volume rm symfony-poly-stack_postgres-data(18+ images mount at/var/lib/postgresql, not/var/lib/postgresql/data).
.mise.toml holds only [tools] and [env]; all tasks are file tasks in .mise/tasks/.
Tools (bun, gh, caddy, dagger, composer via the github:composer/composer backend) are
managed by mise — they are not installed in the Dockerfile.
mise setup— install deps (composer + bun concurrently), generate secrets, create DB, migratemise dev(aliasup) — start Caddy + PHP-FPM + scheduler concurrently (.mise/tasks/dev/)mise test/mise lint [--fix]/mise analyse/mise rector [--fix]mise quality— lint + analyse + rector + test, concurrentlymise ci—dagger call quality
- PHPStan level 8, no baseline (
phpstan.dist.neon); Symfony/Doctrine extensions need a warmed dev cache (bin/console cache:warmup) — theanalysetask does this - Rector 2 with
withPhpSets()+ composer-based Symfony/Doctrine sets (rector.php); always review the dry-run diff before--fix - php-cs-fixer with the
@Symfonyruleset (.php-cs-fixer.dist.php) - PHPUnit; test env uses a
_test-suffixed database (seeconfig/packages/doctrine.yaml)
.dagger/ (TypeScript SDK) runs the quality suite in php:8.5-cli-trixie containers:
dagger call quality (or test / lint / analyse / rector-check). Requires a Docker
engine — run from the host or CI, not inside the devcontainer.
No script rewrites .env. .mise.toml [env] templates compute DEFAULT_URI and
TRUSTED_PROXIES from CODESPACE_NAME; php-fpm runs with clear_env = no so process env
beats .env. The Caddyfile forces X-Forwarded-Proto: https when CODESPACE_NAME is set.