В отличие от «острых» дистрибутивов вроде Fedora или Arch, Ubuntu дает гарантию обновлений до 2029 года. Для проекта, который будет жить годами, это очень важно.
Первые шаги после аренды VPS
Обновление системы
sudo apt update && sudo apt upgrade -y && sudo apt autoremove —purge
Здесь важно не пропустить autoremove. Остатки старых ядер Linux съедают место на диске у проекта с высокой нагрузкой, вызывая падение сервисов.
Создание пользователя с правами sudo
Работать под root — всё равно что хранить ключи от дома в почтовом ящике.
adduser deployer
usermod -aG sudo deployer
После этого настройте SSH-ключи. Пароли для входа должны быть отключены. Если вы думаете, что «ваш пароль надежный», посмотрите на статистику brute-force атак за последние сутки в логах любого публичного сервера.
Брандмауэр — ваш первый щит
sudo ufw allow OpenSSH
sudo ufw allow ‘Nginx Full’
sudo ufw enable
Запрещайте всё, кроме необходимого. Даже если сейчас вам кажется, что порт 3306 для MySQL может пригодиться для отладки. Поверьте, доступ к базе данных по публичному IP — это билет в ад для DBA.
Установка стека
Nginx или Apache
Да, Nginx быстрее обрабатывает статику. Но разница в 5–7% в реальных сценариях Laravel часто нивелируется кешированием. Я выбираю Nginx ради его модульной архитектуры и простоты конфигурации. Например, настройка проксирования для Horizon или WebSockets требует в Apache дюжины строк, а в Nginx — трех.
PHP 8.3: баланс между новыми фичами и стабильностью
Ubuntu 24.04 поставляется с PHP 8.3 в репозиториях. Это подарок свыше: JIT-компиляция, улучшенная типизация, и самое главное — поддержка современных библиотек. Но перед установкой всегда проверяйте совместимость вашего приложения. Я столкнулся с кейсом, где кастомный пакет для работы с SOAP сломался из-за изменений в ядре PHP 8.3. Решение? Сборка контейнера с PHP 8.2 для этого проекта. Гибкость — признак зрелости инфраструктуры.
sudo apt install php8.3-fpm php8.3-mysql php8.3-redis php8.3-gd -y
Обратите внимание: я сознательно не ставлю php8.3-cli — он входит в php8.3-fpm. Избегайте дублирования пакетов, это экономит место и снижает поверхность атаки.
Composer: глобальная установка как привычка профессионала
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Глобальный Composer экономит время, но не забудьте настроить права:
sudo chown -R deployer:deployer /home/deployer/.composer
Иначе sudo при каждой установке пакетов — это риск записать файлы от root в директорию проекта.
Настройка Laravel: где рождается безопасность
.env — файл, который не должен существовать
После клонирования репозитория первое действие — создание .env из шаблона:
cp .env.example .env
php artisan key:generate —force
Но помните: на продакшене .env должен быть защищен дважды. Во-первых, запретите доступ к нему через Nginx:
location ~ /\.env {
deny all;
}
Во-вторых, установите права 600:
chmod 600 .env
Я работал с проектом, где .env был доступен по URL из-за опечатки в конфиге. Внутри были креды к AWS. Восстановление заняло три дня и $2,000 на экстренные аудиты.
Права доступа
Классическая ошибка — выставить chmod -R 777 storage. Это равносильно оставлять дверь квартиры нараспашку с табличкой «Здесь есть что украсть». Вот корректная схема:
sudo chown -R www-data:deployer /var/www/laravel-app
sudo find /var/www/laravel-app -type f -exec chmod 644 {} \;
sudo find /var/www/laravel-app -type d -exec chmod 755 {} \;
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
Группа www-data (пользователь Nginx) получает права на запись, а разработчик — возможность читать логи. Баланс, который спасёт вас от «почему Horizon не пишет логи?» в три часа ночи.
Nginx и SSL: невидимые стены доверия
Конфигурация серверного блока
Типичный конфиг для Laravel выглядит так:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/laravel-app/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Обратите внимание на строку location ~ /\.(?!well-known).*. Она блокирует доступ ко всем скрытым файлам, кроме .well-known, который нужен для Let’s Encrypt. Без этого сертификаты перестанут обновляться автоматически.
Let’s Encrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot —nginx -d example.com -d www.example.com
Но автоматика — не повод расслабляться. Раз в месяц проверяйте срок действия:
sudo certbot renew —dry-run
Оптимизация
Кеширование конфигурации и роутов
php artisan config:cache
php artisan route:cache
php artisan view:cache
Эти команды ускорят работу в 2–3 раза. Но помните: route:cache не работает с замыканиями в роутах. Если вы используете Route::get(‘/’, function() {…}), рефакторьте в контроллеры. Это не просто вопрос скорости — это дисциплина кода.
OPcache: скрытый турбо-режим PHP
В файле /etc/php/8.3/fpm/php.ini активируйте:
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
После этого перезагрузите PHP-FPM:
sudo systemctl restart php8.3-fpm
На одном из проектов это снизило время ответа API с 420ms до 110ms.
Резервные копии
Скрипт для бэкапа базы и файлов:
#!/bin/bash
DATE=$(date +%F)
mysqldump -u user -ppassword dbname | gzip > /backups/db_$DATE.sql.gz
tar -czf /backups/app_$DATE.tar.gz /var/www/laravel-app
Но важно не только создать архив. Автоматизируйте его копирование в облако (AWS S3, Yandex Object Storage) и тестируйте восстановление.








