Laravel-застосунок - це не лише вебсервер. У продакшені працює кілька процесів, і в Docker кожен зазвичай отримує свій контейнер:
services:
app: # вебзапити: PHP-FPM (+ Nginx) або FrankenPHP
image: myapp:1.4.0
queue: # воркер черги
image: myapp:1.4.0
command: php artisan queue:work --tries=3 --max-jobs=1000
scheduler: # планувальник задач
image: myapp:1.4.0
command: php artisan schedule:work
db:
image: postgres:18
redis:
image: redis:8-alpine
Ролі контейнерів:
| Контейнер | Що робить |
|---|---|
| вебсервер + PHP | обробляє HTTP-запити. Класична пара - Nginx і PHP-FPM (два контейнери чи один), сучасна - FrankenPHP чи Octane |
| воркер черги | виконує задачі з черги: листи, обробку файлів, сповіщення |
| планувальник | щохвилини запускає schedule:run (чи працює постійно через schedule:work) |
| база даних | PostgreSQL чи MySQL з томом для даних |
| Redis | кеш, сесії, черги, блокування |
| опційно | Horizon замість простого воркера, Reverb для вебсокетів, Meilisearch для пошуку |
Ключова ідея - один образ, різні команди. Веб, воркер і планувальник використовують той самий образ застосунку з тим самим кодом і залежностями - відрізняється лише команда запуску. Це гарантує, що воркер виконує задачі тим самим кодом, що й веб, який їх поставив.
Що зазвичай не в контейнерах у продакшені:
- база даних часто винесена в керований сервіс (RDS, Cloud SQL) - бекапи, реплікація й оновлення стають чужою турботою;
- файли користувачів - в об'єктному сховищі (S3, R2), а не на диску контейнера.
Локально все це збирає Laravel Sail чи власний compose.yaml, а в продакшені - Compose на одному сервері, Docker Swarm, Kubernetes чи платформи на кшталт Laravel Cloud, Dokploy, Coolify.