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

> Symfony на VPS: структура каталогів, конфіг Nginx для public/index.php, права на var/cache і типові помилки 502.

Symfony за замовчуванням розрахований на структуру, де точка входу лежить у каталозі `public/`, а все інше — вихідний код, кеш, логи — недоступне вебсерверу напряму. Помилки в конфігу Nginx або в правах на каталоги — найчастіша причина білого екрана і 502 після першого деплою.

## Структура каталогів проєкту

Вебсервер має дивитися строго в `public/`, а не в корінь проєкту — інакше через браузер будуть доступні `.env`, `composer.json` і вміст `var/`. Каталог `var/cache` і `var/log` має бути доступний на запис користувачу PHP-FPM, а `vendor/` збирається через Composer уже на сервері або заливається разом із релізом. Про сам менеджер залежностей — у статті [про встановлення і налаштування Composer](https://www.zevshost.net/uk/kb/composer-ustanovka-nastroika/).

## Конфіг 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](https://www.zevshost.net/uk/kb/php-fpm-nastroika-optimizatsiya/).

## Права на каталоги 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](https://www.zevshost.net/uk/kb/php-composer-autoload-optimizatsiya/).

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

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

1. Перевірте, що `APP_ENV=prod` і `APP_DEBUG=0` у файлі `.env.local` на сервері, а не лише локально.
2. Переконайтеся, що OPcache увімкнено і налаштовано на інвалідацію за часом, а не на кожен запит — конфігурацію описано в статті [про налаштування OPcache](https://www.zevshost.net/uk/kb/php-opcache-nastroika-linux/).
3. Прожене smoke-тест ключових сторінок одразу після деплою, до того як на сайт зайдуть реальні відвідувачі.

---

Джерело: https://www.zevshost.net/uk/kb/symfony-nastroika-vps/
