В нашей новой статье — подробная инструкция по развёртыванию Laravel-приложения на VPS с Ubuntu 24.04: установка и настройка веб-стека, перенос кода из Git, настройка окружения, безопасных прав доступа и проверка работоспособности.
Введение
В статье — инструкция по подготовке свежего сервера Ubuntu 24.04 и развёртыванию на нём Laravel-приложения. Мы установим и настроим стек (Nginx, PHP 8.3-FPM), развернём код из Git, настроим окружение, обеспечим безопасные права доступа, запустим приложение и проверим его работоспособность.
Подготовка сервера Ubuntu 24.04
Первым делом обновим систему, выполните:
sudo apt update && sudo apt upgrade -y
Далее установим обязательные утилиты:
sudo apt install -y git unzip software-properties-common
git понадобится для клонирования репозитория, unzip — для работы Composer с архивами, а software-properties-common добавляет команду add-apt-repository для подключения внешних репозиториев (например, NodeSource).
Для корректной работы планировщика и логов настроим часовой пояс:
sudo timedatectl set-timezone Europe/Moscow # укажите свой регион
Неверное время сервера вызывает проблемы в кешировании, cron-заданиях и анализе логов. Проверить текущие настройки можно через timedatectl status, список доступных зон — через timedatectl list-timezones.
Создайте отдельного пользователя для приложения:
sudo adduser deployer
Запуск от root недопустим из-за рисков компрометации сервера. Для управления сервисами добавьте пользователя в sudo:
sudo usermod -aG sudo deployer
Если админские права не нужны, но требуется доступ к файлам веб-сервера, добавьте в группу www-data:
sudo adduser deployer www-data
Это обеспечит изоляцию процессов и упростит контроль прав.
Установка веб-стека Nginx+PHP 8.3-FPM
Начнём с установки Nginx, этот веб-сервер станет фронтендом приложения, обрабатывая HTTP-запросы и передавая PHP-скрипты через FastCGI:
sudo apt install -y nginx
Далее устанавливаем PHP 8.3 FPM и обязательные расширения одной командой:
sudo apt install -y php8.3-fpm php8.3-common php8.3-mysql php8.3-mbstring php8.3-xml php8.3-zip php8.3-bcmath php8.3-curl php8.3-gd php8.3-intl php8.3-redis php8.3-sqlite3
Каждый модуль решает конкретную задачу в Laravel:
- mysql — PDO-драйвер для работы с MySQL/MariaDB;
- mbstring, xml — базовая поддержка строк и XML (обязательна для ядра Laravel);
- zip — работа с архивами (требуется для Composer);
- bcmath — точные математические операции (критично для шифрования и хеширования);
- curl — HTTP-запросы к внешним сервисам;
- gd — обработка изображений;
- intl — интернационализация и локализация;
- redis — поддержка Redis для кеша, сессий и очередей;
- sqlite3 — работа с SQLite (удобно для тестирования).
После установки убедимся, что сервисы запущены:
sudo systemctl status nginx php8.3-fpm
В выводе должны присутствовать статусы active (running) для обеих служб. Если какой-то сервис не запустился автоматически, выполните:
sudo systemctl start <имя_сервиса>
Перейдём к настройке PHP-FPM. Откройте конфигурационный файл пула:
sudo nano /etc/php/8.3/fpm/pool.d/www.conf
Обратите внимание на следующие параметры:
- режим управления процессами:
- pm = dynamic — автоматическая регулировка числа worker-процессов в зависимости от нагрузки;
- параметры масштабирования:
- pm.max_children = 50 — максимальное число одновременных PHP-процессов (настраивается под ресурсы сервера);
- pm.start_servers = 4 — число процессов при старте FPM;
- pm.min_spare_servers = 2 — минимальное число простаивающих процессов;
- pm.max_spare_servers = 8 — максимальное число простаивающих процессов;
- стабильность работы:
- pm.max_requests = 500 — лимит запросов на процесс перед перезапуском (предотвращает утечки памяти);
- системные пути:
- env[PATH] = /usr/local/bin:/usr/bin:/bin — гарантирует, что PHP сможет находить системные бинарники при таких вызовах как exec() или shell_exec().
После внесения изменений сохраните файл и перезапустите PHP-FPM:
sudo systemctl restart php8.3-fpm
Новые настройки применятся без паузы в работе веб-сервера.
Установка Composer и Node.js (для фронтенд-сборки)
Composer, как менеджер пакетов PHP, обязателен для установки компонентов фреймворка и сторонних библиотек; а для проектов, использующих фронтенд-сборку через Laravel Mix или Vite, потребуется Node.js с npm — они отвечают за компиляцию CSS/JavaScript, оптимизацию ассетов и работу современных инструментов разработки.
Скачаем установщик Composer с официального сайта:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
Эта команда использует встроенную PHP-функцию copy() для загрузки скрипта установки в текущую директорию.
Перед запуском скрипта сверим его SHA-384 хеш с официальным значением с сайта getcomposer.org/download/ (вставьте актуальный хеш в команду):
php -r "if (hash_file('sha384', 'composer-setup.php') === 'актуальный_хеш') {
echo 'Installer verified';
} else {
echo 'Installer corrupt';
unlink('composer-setup.php');
} echo PHP_EOL;"
Если вывод показывает «Installer corrupt», прервите установку, так как файл мог быть подменён.
После успешной верификации выполним:
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
Здесь --install-dir=/usr/local/bin поместит исполняемый файл в системную директорию, доступную всем пользователям, а --filename=composer задаст имя команды.
Очистите временные файлы, чтобы удалить установочный скрипт:
php -r "unlink('composer-setup.php');"
Проверка установки:
composer --version
Вывод должен отобразить текущую версию Composer (например, Composer version 2.7.1).
Установим Node.js (LTS версию 20.x). Добавление репозитория NodeSource:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
Флаг -E у sudo сохраняет текущие переменные окружения.
Следующая команда установит сразу две компоненты: сам Node.js и менеджер пакетов npm (они поставляются вместе):
sudo apt install -y nodejs
Проверка установки:
node --version
npm --version
Клонирование проекта и установка зависимостей
На этом этапе перенесём актуальную версию приложения на сервер и подготовим его к запуску.
Перейдите в директорию для веб-приложений:
cd /var/www
Если эта директория отсутствует, создайте её заранее, установив правильные права:
sudo mkdir -p /var/www && sudo chown deployer:www-data /var/www
Теперь клонируем репозиторий от имени пользователя приложения (в нашем случае deployer) — это критически важно для сохранения корректных прав доступа:
sudo -u deployer git clone https://github.com/ваш-пользователь/ваш-проект.git project-name
Замените URL на адрес вашего репозитория (используйте HTTPS или SSH в зависимости от настроек доступа). Последний аргумент (project-name) задаёт имя целевой директории на сервере.
После клонирования перейдите в директорию проекта, где будут выполняться все последующие операции:
cd project-name
Теперь установим PHP-зависимости. Запустите Composer с параметрами, оптимизированными для продакшена:
sudo -u deployer composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
Разберём ключевые флаги:
- --no-interaction автоматически подтверждает все запросы (критично для автоматизированных сценариев);
- --prefer-dist устанавливает стабильные дистрибутивы вместо исходных кодов;
- --optimize-autoloader ускоряет загрузку классов;
- --no-dev исключает пакеты для разработки.
Для проектов с фронтенд-сборкой — если приложение использует Vite или Laravel Mix — сначала установите зависимости. Команда npm ci предпочтительнее npm install, так как строго соблюдает версии из package-lock.json:
sudo -u deployer npm ci
Затем выполните сборку ассетов:
sudo -u deployer npm run build # Для Vite
Или:
sudo -u deployer npm run production # Для Laravel Mix
Этот процесс минифицирует CSS/JavaScript, добавляет хеши к именам файлов для инвалидации кеша и оптимизирует все ресурсы для продакшена.
Важно:
- Все команды выполняются через sudo -u deployer для сохранения правильного владельца файлов.
- При клонировании по SSH убедитесь, что пользователь deployer имеет доступ к приватному ключу.
- Если Composer завершается с ошибкой нехватки памяти, добавьте временный swap-файл:
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
Теперь в директории /var/www/project-name находится полная копия вашего Laravel-приложения с установленными зависимостями. Технически приложение уже готово к запуску, но оно требует финальной настройки окружения и корректировки прав доступа к файлам.
Настройка окружения Laravel (.env) и прав доступа
Файл .env содержит критически важные данные Laravel-приложения: ключи шифрования, доступы к базе данных, API-ключи внешних сервисов. Неправильная настройка этого файла или прав доступа к нему может привести как к неработоспособности приложения, так и к серьёзным уязвимостям безопасности.
Начнём с создания файла окружения. Скопируйте шаблон .env.example в рабочий .env от имени пользователя приложения, чтобы он стал владельцем нового файла:
sudo -u deployer cp .env.example .env
Этот шаблон содержит все необходимые переменные, но без реальных значений.
Следующее действие — генерация уникального ключа приложения (APP_KEY), который используется для шифрования cookies и сессий. Без этого ключа приложение не сможет работать корректно:
sudo -u deployer php artisan key:generate
Команда автоматически сгенерирует криптографически безопасный ключ и запишет его в .env. Никогда не оставляйте приложение без установленного APP_KEY в продакшене!
Теперь отредактируем .env, заполнив реальные значения для вашего окружения:
sudo -u deployer nano .env
Важные параметры:
- APP_ENV=production — режим продакшена (включает оптимизации и скрывает ошибки);
- APP_DEBUG=false — отключает показ детальных ошибок (критично для безопасности!);
- APP_URL=https://ваш-домен — полный URL приложения;
- DB_* параметры — корректные данные для подключения к базе данных;
- REDIS_* — настройки Redis (если используется для кеша/очередей);
- MAIL_* — конфигурация почтового сервера;
- QUEUE_CONNECTION — драйвер для обработки очередей (database, redis, sync).
Настройка безопасных прав доступа — самый важный этап для защиты сервера, выполняйте её в строгой последовательности:
- Установите рекурсивного владельца для всей директории проекта:
sudo chown -R deployer:www-data /var/www/project-name
Теперь пользователь deployer владеет файлами, а группа www-data (к которой принадлежат процессы Nginx и PHP-FPM) получает доступ.
- Настройте безопасные права для директорий:
sudo find /var/www/project-name -type d -exec chmod 750 {} \;
Это позволяет владельцу полноценно работать с файлами, веб-серверу — читать и исполнять скрипты, а всем остальным пользователям — запрещает доступ.
- Настройте права для файлов:
sudo find /var/www/project-name -type f -exec chmod 640 {} \;
Обратите внимание, что запись в файлы разрешена только владельцу. Это защищает .env и другие конфиги от модификации через уязвимости в веб-приложении.
Исключение — директории storage и bootstrap/cache, они требуют права на запись для веб-сервера (чтобы приложение могло писать логи, кеш, сессии и т.д.):
sudo chmod -R ug+w /var/www/project-name/storage /var/www/project-name/bootstrap/cache
Флаг ug+w добавляет право записи для владельца (u) и группы (g), не затрагивая остальных пользователей.
С такими правилами в случае компрометации веб-приложения возможности злоумышленников будут ограничены. Они смогут читать файлы только через процессы веб-сервера (группа www-data), модифицировать только содержимое storage/ и bootstrap/cache/ и не смогут перезаписать .env, PHP-скрипты или конфиги.
Настройка Nginx
Для доступа пользователей к приложению необходимо настроить веб-сервер. Создадим новый файл конфигурации для домена:
sudo nano /etc/nginx/sites-available/project-name
Замените project-name на идентификатор вашего приложения (обычно совпадает с именем домена).
Следующий шаг — конфигурация виртуального хоста. Пример ниже содержит все необходимые элементы для безопасной и эффективной работы Laravel, вставьте его в файл, указав актуальные значения:
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;
root /var/www/project-name/public; # Корневая директория public
# Безопасные HTTP-заголовки
add_header X-Frame-Options "SAMEORIGIN"; # Защита от clickjacking
add_header X-Content-Type-Options "nosniff"; # Предотвращение MIME-sniffing
add_header Referrer-Policy "strict-origin-when-cross-origin"; # Контроль реферера
index index.php;
charset utf-8;
# Обработка основного маршрутизатора Laravel
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Игнорирование системных файлов
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
# Перенаправление ошибок на контроллер
error_page 404 /index.php;
# Обработка PHP через FPM Unix Socket
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock; # Путь к сокету PHP 8.3
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param HTTP_PROXY ""; # Защита от заголовка Proxy
fastcgi_buffers 16 16k; # Буферы для обработки запросов
fastcgi_buffer_size 32k; # Размер буфера
fastcgi_read_timeout 300; # Таймаут для долгих операций
internal; # Важно для безопасности
}
# Запрет доступа к скрытым файлам
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
# Длительное кеширование статических ресурсов
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|webp|woff2?|ttf|eot|otf)$ {
expires 1y;
access_log off;
add_header Cache-Control "public, immutable";
}
location ~* \.(?:css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "public, immutable";
}
}
Ключевые элементы конфигурации:
- X-Frame-Options, X-Content-Type-Options, Referrer-Policy — современные защитные HTTP-заголовки;
- internal в PHP location — предотвращает прямой доступ к PHP-файлам кроме как через index.php;
- запрет доступа ко всем скрытым файлам, кроме .well-known (нужен для Let's Encrypt);
- сброс HTTP_PROXY — защита от HTTPOxy уязвимости;
- fastcgi_buffers и buffer_size — оптимизация обработки больших запросов;
- длительное кеширование статики (1 год) с immutable;
- access_log off для статики — снижение нагрузки на диск;
- root /var/www/project-name/public — корневая директория должна указывать на public/;
- try_files $uri $uri/ /index.php?$query_string — правильное перенаправление на фронт-контроллер;
- указание пути к сокету PHP-FPM (unix:/run/php/php8.3-fpm.sock).
Создадим симлинк для активации виртуального хоста:
sudo ln -s /etc/nginx/sites-available/project-name /etc/nginx/sites-enabled/
Прежде чем применять конфигурацию, проверим синтаксис:
sudo nginx -t
Успешный вывод:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Применим изменения без простоя:
sudo systemctl reload nginx
Проверка работоспособности
Выполните финальный перезапуск сервисов:
sudo systemctl restart nginx php8.3-fpm
Откройте домен в браузере — должна загрузиться главная страница Laravel или вашего приложения. Если возникли ошибки, проверьте логи:
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/www/project-name/storage/logs/laravel.log
Для теста работы с базой данных выполните:
sudo -u deployer php artisan tinker
>>> \DB::connection()->getPdo()
В ответе должна быть строка PDO Object — это подтверждает корректное подключение к БД. Теперь ваше Laravel-приложение полностью развёрнуто и готово принимать пользователей!
Читайте в блоге:
- Настраиваем nftables для защиты веб-сервера на Ubuntu 24.04
- Как обновить ядро Linux на Ubuntu 24.04 и откатить изменения при ошибках
- Как перенести Ubuntu 24.04 на новый сервер без переустановки