К основному содержимому

Symfony на VPS: деплой, конфиг Nginx и права на каталоги

PHP · 29.09.2026

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/cachewww-data775кэш контейнера и шаблонов
var/logwww-data775логи приложения
public/uploadswww-data775файлы, загруженные пользователями
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.

Чек-лист перед запуском в проде

Перед тем как переключить домен на новый релиз, пройдитесь по списку:

  1. Проверьте, что APP_ENV=prod и APP_DEBUG=0 в файле .env.local на сервере, а не только локально.
  2. Убедитесь, что OPcache включён и настроен на инвалидацию по времени, а не на каждый запрос — конфигурация описана в статье про настройку OPcache.
  3. Прогоните smoke-тест ключевых страниц сразу после деплоя, до того как на сайт зайдут реальные посетители.
← Назад в базу знаний Задать вопрос поддержке