Introduction
In the previous article, I showed how to build a production-ready Docker image for Laravel & Filament.
But in real-world applications, a single container is never enough.
Running a production application means dealing with multiple concerns:
- web server
- PHP runtime
- database
- cache
- background workers
- scheduled jobs
And this is where things usually start to get messy.
The problem with "simple" setups
Most Docker Compose examples look like this:
- one container
- maybe a database
- everything else mixed together
It works.
Until it doesnβt.
From my experience, this approach quickly leads to:
- poor observability
- difficult debugging
- no real scaling strategy
- fragile deployments
A simple rule I follow
Over time, I ended up following one principle:
π one container = one responsibility
It sounds simple, but it completely changes how you design your architecture.
A production-oriented architecture
Instead of one container doing everything, I split responsibilities:
-
appβ PHP-FPM runtime -
webβ reverse proxy (Nginx) -
dbβ PostgreSQL -
redisβ cache & queues -
horizonβ queue workers -
schedulerβ scheduled jobs
Each service is isolated.
Each service can scale independently.
Each service can fail independently.
π This is what makes the system predictable.
A common trap: the "public volume"
One mistake Iβve seen (and made) multiple times is how static assets are handled.
A typical setup uses:
public:/var/www/app/public
Looks fine.
But in practice:
- old assets can persist between deployments
- new builds may not be reflected
- deployments become inconsistent
π This kind of issue is subtleβ¦ and painful in production.
Another key point: bootstrap vs runtime
In many setups, migrations and initialization tasks run inside the main container.
I prefer separating concerns:
- runtime containers β long-running processes
- bootstrap β one-time tasks (migrations, setup)
π In real production systems, this is often handled in CI/CD pipelines instead.
Why this matters
This kind of architecture gives you:
- better isolation
- clearer debugging
- safer deployments
- real scalability
Itβs not the simplest setup.
But itβs much closer to what you actually need in production.
Going further
In this article, I intentionally kept things focused on concepts and architecture.
π I cover the full Docker Compose setup (with real configuration, volumes, healthchecks, and production patterns)
https://filamentmastery.com/articles/production-ready-docker-compose-for-laravel-filament/
Series
This article is part of a series on production-ready Laravel & Filament setups:
- Docker image (multi-stage build)
- Docker Compose architecture
- CI/CD pipelines
- deployment strategies
Iβll be covering each part progressively.
If youβve already built similar setups, Iβd be curious to hear how you structure your containers in production.
For further actions, you may consider blocking this person and/or reporting abuse
