Тема
Docker
Laravel 13: PHP 8.3–8.5 (минимум 8.3), рекомендуемый образ
php:8.4-fpmКонтекст «почему»: best/infrastructure-performance (тюнинг стека, бюджет памяти)
Стандартная конфигурация
Сервисы
| Сервис | Образ | Назначение |
|---|---|---|
| app | php:8.4-fpm + расширения (мин. 8.3 для Laravel 13) | PHP-FPM application |
| nginx | nginx:alpine | Web-сервер, проксирование |
| mysql | mysql:8 | База данных |
| redis | redis:7-alpine | Кеш, сессии, очередь |
| queue | тот же что app | php artisan queue:work |
| scheduler | тот же что app | php artisan schedule:work |
Структура файлов
project/
├── docker/
│ ├── app/Dockerfile
│ ├── nginx/default.conf
│ └── scheduler/entrypoint.sh
├── docker-compose.yml
├── docker-compose.dev.yml
└── src/ — Laravel rootPHP расширения (обязательные)
pdo_mysql, redis, gd, exif, zip, bcmath, intl, opcache
Команды
Жизненный цикл
| Команда | Действие |
|---|---|
docker compose up -d | Запуск всех сервисов |
docker compose down | Остановка |
docker compose restart app | Перезапуск PHP |
docker compose logs -f app | Логи приложения |
docker compose logs -f queue | Логи очереди |
Artisan / Composer
ВСЕГДА через docker exec:
| Команда | Действие |
|---|---|
docker exec {container} php artisan migrate | Миграции |
docker exec {container} php artisan db:seed | Сидеры |
docker exec {container} php artisan cache:clear | Очистка кеша |
docker exec {container} php artisan queue:restart | Перезапуск воркеров |
docker exec {container} composer install | Установка зависимостей |
docker exec {container} composer require pkg | Добавление пакета |
docker exec -it {container} bash | Shell в контейнер |
Никогда не запускать artisan/composer на хосте — версии PHP/расширений могут отличаться.
Environment (.env)
Обязательные переменные для Docker
| Переменная | Значение в Docker |
|---|---|
DB_HOST | mysql (имя сервиса) |
REDIS_HOST | redis (имя сервиса) |
CACHE_STORE | redis (с Laravel 11 переменная называется CACHE_STORE, не CACHE_DRIVER) |
SESSION_DRIVER | redis |
QUEUE_CONNECTION | redis |
CACHE_PREFIX | {project}_cache_ — задавать ЯВНО |
REDIS_PREFIX | {project}_database_ — задавать ЯВНО |
SESSION_COOKIE | {project}_session — задавать ЯВНО |
Почему префиксы явно (Laravel 13): фреймворк сменил формат авто-генерируемых префиксов (подчёркивания → дефисы). Если полагаться на дефолты, после апгрейда «протухнут» кеш и сессии. На сервере с общим Redis отсутствие префиксов = коллизии ключей между проектами.
Версии зависимостей для Laravel 13
composer.json: laravel/framework ^13.0, laravel/tinker ^3.0, laravel/boost ^2.0 (dev), phpunit/phpunit ^12.0 / pestphp/pest ^4.0.
Правила
.env— НИКОГДА в git (.gitignore).env.example— шаблон с пустыми значениями, ВСЕГДА в git- Секреты (API-ключи, токены) — только в
.env, доступ черезconfig() - Для каждого окружения (dev/staging/prod) — свой
.env
Dev vs Production
Development (docker-compose.dev.yml)
- Xdebug включён
- Volume монтирование
src/для hot reload - Ports exposed на localhost
APP_DEBUG=true
Production
- opcache включён с preloading
- Nginx: gzip, кеш статики, security headers
- MySQL: bind только к internal network
- Redis:
maxmemory-policy allkeys-lru - Volumes:
storage/,bootstrap/cache/, MySQL data, Redis data APP_DEBUG=false— без исключений- HTTPS — обязателен (Let's Encrypt / Caddy)
Anti-patterns
| Паттерн | Проблема | Решение |
|---|---|---|
| artisan/composer на хосте | Версия PHP/расширений отличается | docker exec |
.env в git | Утечка секретов | .gitignore + .env.example |
APP_DEBUG=true в production | Stack traces видны пользователям | false |
| MySQL port exposed в production | Доступ извне | Только internal network |
| Нет volume для MySQL data | Потеря данных при docker compose down | Named volume |
| Один docker-compose для dev и prod | Конфликт настроек | Отдельный .dev.yml override |
| Нет queue/scheduler сервисов | Jobs не обрабатываются, cron не работает | Отдельные контейнеры |
Docker и PATH (Ubuntu)
Docker установлен нативно и доступен в Bash просто как docker — правки PATH не нужны. Если docker: command not found — проверить установку: which docker, systemctl status docker. (Раздел про C:\Program Files\... и Git Bash относился к старому Windows-серверу и удалён.)
Контейнеры проекта referendum (пример)
| Роль | Имя контейнера |
|---|---|
| App (PHP + Node) | referendum |
| PostgreSQL | referendum-postgres |
| Redis | referendum-redis |
Типичные команды
bash
docker exec referendum php artisan migrate
docker exec referendum php artisan db:seed
docker exec referendum npm run build
docker exec -it referendum bashПочему npm run build запускать в контейнере, а не на хосте
Хостовый Node.js может быть несовместимой версии (напр. v20.10.0 < требуемой v20.19+). Контейнер содержит нужную версию Node. Всегда используй docker exec {app} npm run build.