The twelve-factor app methodology was written with platforms like Heroku in mind, but the principles apply to any modern web application. Symfony already handles most of them well — if you let it.
What Symfony Gives You for Free
I. Codebase — One repo, tracked in Git. Symfony projects follow this naturally.
III. Config — Symfony's environment variables and .env files are twelve-factor by design. %env(DATABASE_URL)% in your service configuration means config lives in the environment, not in code.
IV. Backing Services — Doctrine DSNs, Messenger transport DSNs, Mailer DSNs — Symfony treats all of these as attached resources configured via URL strings.
X. Dev/Prod Parity — Symfony Flex and Docker Compose make it straightforward to run the same stack locally and in production.
What Needs Deliberate Attention
V. Build, Release, Run
Symfony apps need a build step: clearing caches, warming up containers, compiling assets. Don't do this at runtime.
RUN php bin/console cache:warmup --env=prod
RUN php bin/console asset-map:compile
Your container image should be ready to serve requests the moment it starts.
VI. Processes
Stateless processes mean no local file storage for uploads, no in-memory session state. Use Flysystem for file storage and Redis or database sessions.
framework:
session:
handler_id: '%env(REDIS_URL)%'
VIII. Concurrency
Scale by running more processes — web workers, queue consumers, schedulers — not by threading within a single process. Messenger workers are a natural fit here.
# Scale consumers independently
supervisor: messenger:consume async --limit=100
XI. Logs
Symfony's Monolog should write to stderr, not to files. Let the platform aggregate logs.
monolog:
handlers:
main:
type: stream
path: "php://stderr"
level: info
XII. Admin Processes
Symfony Console commands are perfect for one-off admin tasks. Run them as separate processes against the same release.
The Takeaway
Most Symfony apps are 80% twelve-factor already. The remaining 20% — build steps, stateless processes, log routing — is where teams often cut corners and pay for it later.