Symfony по умолчанию рассчитан на структуру, где точка входа лежит в
каталоге public/, а всё остальное — исходники, кэш, логи —
недоступно веб-серверу напрямую. Ошибки в конфиге Nginx или в правах на
каталоги — самая частая причина белого экрана и 502 после первого деплоя.
Структура каталогов проекта
Веб-сервер должен смотреть строго в public/, а не в корень
проекта — иначе через браузер будут доступны .env,
composer.json и содержимое var/. Каталог
var/cache и var/log должен быть доступен на запись
пользователю PHP-FPM, а vendor/ собирается через Composer уже
на сервере или заливается вместе с релизом. Про сам менеджер зависимостей —
в статье про установку и
настройку Composer.
Конфиг Nginx для Symfony
Ключевая часть — правило try_files, которое отдаёт все
запросы, кроме реальных файлов, через index.php:
server {
listen 80;
server_name example.com;
root /var/www/example/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
internal;
}
location ~ \.php$ {
return 404;
}
}
Строка internal; запрещает открывать /index.php
напрямую по URL — только через try_files. Настройки самого пула PHP-FPM,
включая лимиты воркеров, разобраны в статье
про пулы и оптимизацию
PHP-FPM.
Права на каталоги var/cache и var/log
Symfony пишет кэш контейнера сервисов, скомпилированные шаблоны и логи в
var/. Если пользователь PHP-FPM не может писать в эти папки,
приложение падает с ошибкой доступа при первом же запросе после деплоя.
| Каталог | Владелец | Права | Назначение |
|---|---|---|---|
| var/cache | www-data | 775 | кэш контейнера и шаблонов |
| var/log | www-data | 775 | логи приложения |
| public/uploads | www-data | 775 | файлы, загруженные пользователями |
| config, src | деплой-пользователь | 755 | исходники, только чтение для веба |
Порядок деплоя релиза
Обновление кода без прогрева кэша ведёт к тому, что первый посетитель после релиза ждёт компиляцию контейнера сервисов несколько секунд. Порядок команд на сервере такой:
composer install --no-dev --optimize-autoloader— ставит зависимости без dev-пакетов и строит оптимизированный автозагрузчик.php bin/console cache:clear --env=prod— очищает старый кэш перед пересборкой.php bin/console cache:warmup --env=prod— прогревает кэш заранее, до прихода первого запроса.php bin/console doctrine:migrations:migrate --no-interaction— применяет миграции базы данных, если они есть в релизе.
composer install --no-dev --optimize-autoloader
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod
php bin/console doctrine:migrations:migrate --no-interaction
Типовые ошибки 502 и белый экран
После первого деплоя чаще всего встречаются такие проблемы:
502 Bad Gateway обычно означает, что Nginx не может достучаться до
сокета PHP-FPM — либо путь в fastcgi_pass не совпадает с
реальным сокетом, либо сам пул упал из-за нехватки памяти. Белый экран без
текста ошибки означает, что APP_DEBUG=0 и Symfony скрывает
подробности — временно включите отображение через
var/log/prod.log, не через браузер. Автозагрузка PSR-4 связана
с оптимизацией автозагрузчика Composer — детали в статье
про оптимизацию
Composer autoloader.
Чек-лист перед запуском в проде
Перед тем как переключить домен на новый релиз, пройдитесь по списку:
- Проверьте, что
APP_ENV=prodиAPP_DEBUG=0в файле.env.localна сервере, а не только локально. - Убедитесь, что OPcache включён и настроен на инвалидацию по времени, а не на каждый запрос — конфигурация описана в статье про настройку OPcache.
- Прогоните smoke-тест ключевых страниц сразу после деплоя, до того как на сайт зайдут реальные посетители.