Laravel — практичный PHP-фреймворк для небольших команд: маршрутизация, ORM, очереди, миграции и структура. Но между php artisan serve на ноутбуке и сайтом на VPS лежит настройка PHP-FPM, Nginx, базы, прав и деплоя.

Что понадобится

Возьмите Linux-сервер с актуальной веткой PHP, Composer 2, MySQL или PostgreSQL, Nginx и Redis для кэша. Для небольшого проекта хватит 2 ГБ RAM. Домен направьте заранее, чтобы проверить доступность.

  • PHP с расширениями pdo_mysql, mbstring, xml, curl, zip и opcache.
  • Composer 2, Git, Nginx и PHP-FPM одной версии с CLI.
  • Отдельный пользователь MySQL с правами только на базу проекта.

Установка PHP, Composer и проекта

В Debian и Ubuntu PHP ставится из штатного репозитория; более новую версию берите из репозитория производителя. После установки проверьте, что CLI и FPM видят одни и те же расширения.

sudo apt update
sudo apt install php php-fpm php-mysql php-xml php-mbstring php-curl php-zip unzip nginx composer
php -v
php -m | grep -E 'pdo_mysql|mbstring|opcache'

Создайте проект в каталоге сайта. composer create-project скачает фреймворк и зависимости; на рабочем сервере затем используйте --no-dev.

cd /var/www
sudo composer create-project laravel/laravel app
cd /var/www/app
php artisan --version
php artisan key:generate

База данных и переменные окружения

Создайте базу и отдельного пользователя. Не используйте root в .env и не выдавайте права на все базы. Пароль храните в менеджере секретов.

sudo mysql -u root -p
CREATE DATABASE app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'app'@'127.0.0.1' IDENTIFIED BY 'CHANGE_ME';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'127.0.0.1';
FLUSH PRIVILEGES;

В .env укажите production и выключите отладку. APP_DEBUG=true показывает stack trace и переменные окружения — прямой путь к утечке.

APP_NAME=Example
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=app
DB_USERNAME=app
DB_PASSWORD=CHANGE_ME

Выполните миграции и создайте ссылку на хранилище. В production запускайте их с --force, иначе Laravel спросит подтверждение.

php artisan migrate --force
php artisan storage:link
php artisan db:show
php artisan about

Маршруты, контроллер и проверка

Добавьте health-check и endpoint с валидацией, чтобы проверить не только страницу, но и базу. Валидацию держите в Form Request или контроллере.

use Illuminate\Support\Facades\Route;

Route::get('/health', fn () => response()->json(['status' => 'ok']));
Route::post('/orders', [OrderController::class, 'store'])
    ->middleware('throttle:30,1');

Модель и миграция создаются одной командой. Для денег используйте decimal, а не float; внешние ключи задавайте на уровне БД, если они не мешают шардированию.

php artisan make:model Order -m
php artisan make:controller OrderController
php artisan route:list
php artisan test

Nginx и PHP-FPM

Корень сайта должен указывать на public, а не на корень проекта: иначе .env и исходники доступны по HTTP. Конфигурация ниже использует сокет PHP-FPM; его имя зависит от версии, сверьтесь с /run/php/.

server {
    listen 80;
    server_name example.com;
    root /var/www/app/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

TLS завершайте на Nginx или балансировщике. Проверьте конфигурацию и перезагрузите службы. Если Nginx отдаёт 502, обычно виноват путь к сокету или упавший PHP-FPM; nginx -t и systemctl status покажут причину.

sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status php8.3-fpm --no-pager
curl -I http://example.com/health

Права, кэш и оптимизация

Запись нужна только в storage и bootstrap/cache. Не делайте chmod -R 777: это маскирует проблему и снижает безопасность. Владелец — пользователь PHP-FPM, обычно www-data.

sudo chown -R www-data:www-data /var/www/app/storage /var/www/app/bootstrap/cache
sudo find /var/www/app/storage -type d -exec chmod 775 {} \;
sudo find /var/www/app/storage -type f -exec chmod 664 {} \;
sudo chown www-data:www-data /var/www/app/.env
sudo chmod 640 /var/www/app/.env

В production включите кэш конфигурации, маршрутов и представлений. После деплоя его пересобирают, иначе приложение работает со старыми настройками. Для отладки есть php artisan optimize:clear.

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize

Очереди и планировщик

Долгие задачи — письма, отчёты, обработка изображений — выносите в очередь. Воркер запускайте через systemd: он перезапускается после падения и стартует с системой. Не держите его в одной сессии с деплоем.

[Unit]
Description=Laravel queue worker
After=network.target mysql.service

[Service]
User=www-data
Group=www-data
Restart=always
WorkingDirectory=/var/www/app
ExecStart=/usr/bin/php /var/www/app/artisan queue:work --sleep=1 --tries=3 --max-time=3600

[Install]
WantedBy=multi-user.target

Планировщику нужна одна cron-запись, а не десятки задач. Она запускает schedule:run каждую минуту, а фреймворк решает, что выполнять.

* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1
sudo systemctl daemon-reload
sudo systemctl enable --now laravel-worker
systemctl status laravel-worker --no-pager

Деплой без сюрпризов

Деплой — фиксированная последовательность: режим обслуживания, обновление кода, зависимости без dev-пакетов, миграции, пересборка кэша и возврат сайта. Каждый шаг должен останавливать процесс при ошибке.

cd /var/www/app
php artisan down --retry=60
git pull --ff-only
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart
php artisan up

Храните релизы в каталогах и переключайте ссылку current для отката. Для небольшого проекта достаточно git и резервной копии базы, но backup проверяйте восстановлением.

Диагностика

  • 500 после деплоя: смотрите storage/logs/laravel.log, права на storage и APP_KEY.
  • 502 от Nginx: проверьте сокет PHP-FPM, systemctl status и nginx -t.
  • Старые настройки: выполните php artisan config:clear и пересоберите кэш.
  • Очередь стоит: проверьте systemctl status laravel-worker и php artisan queue:failed.
  • 419 при отправке формы: проверьте драйвер сессий, домен и secure-cookie.
tail -n 100 /var/www/app/storage/logs/laravel.log
php artisan about
php artisan queue:failed
sudo journalctl -u php8.3-fpm -n 50 --no-pager

Чек-лист

  • APP_ENV=production и APP_DEBUG=false.
  • Корень Nginx указывает на public, доступ к .env закрыт.
  • Права на storage и bootstrap/cache минимально достаточные.
  • Очередь и планировщик запущены через systemd и cron.

Итог

Laravel удобен, когда инфраструктура настроена предсказуемо: PHP-FPM и Nginx отдают только public, база доступна отдельному пользователю, а деплой состоит из повторяемых шагов. Начните с health-check и миграций, затем добавьте очереди и кэш. Не отключайте отладку «на время», не давайте права 777 и не храните секреты в git — эти привычки закрывают большинство проблем до первого инцидента.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте