Привет, коллеги! ?
Это статья — вторая часть небольшого сериала о деплое web-приложений.
Вот ссылка на первую часть — деплой проекта на Laravel на shared-хостинге с использованием GitHub. Вкратце содержание:
Содержание статьи
— создание приватного репозитория на GitHub и его «связь» с локальным репозиторием
— пуш проекта на GitHub
— клонирование репозитория с GitHub на shared-хостинг
— настройка символических ссылок (необходимо для Laravel приложений)
— настройка Composer
— работа с базой данных
— настройка .env, выполнение миграций, компиляция ассетов и рестарт очередей
Если в прошлой статье мы «ютились» в отдельном каталоге на shared-хостинге, то в этой части статьи мы будем работать на выделенном сервере (физическом или виртуальном).
Что же такое VPS? VPS (англ. virtual private server) — выделенный виртуальный сервер. Простыми словами это просто удаленный компьютер, который вам временно предоставили. Технически, каждый VPS представляет собой отдельно запущенную виртуальную машину на физическом сервере, но с точки зрения конечного пользователя, такой сервер ничем не отличается по своему функционалу и управлению от выделенного сервера.
На старте у нас будет сервер с операционной системой Ubuntu и мы установим и настроим необходимые инструменты для того, чтобы наше Laravel-приложение работало. Это называется настроить окружение.
В этой статье установим и настроим:
-
Nginx. Бесплатный и мощный веб-сервер с открытым исходным кодом. Nginx — это приложение, которое может принимать входящие запросы от пользователей (обычно через веб-браузер) и отвечать на них, отправляя запрошенные веб-страницы или другие данные.
-
Система управления базами данных. Будем использовать MySQL.
-
Для работы Laravel нам нужен PHP (PHP-FPM).
-
Далее поставим Composer.
-
Чтобы корректно работала frontend часть нам понадобится Node/npm.
-
Ну и Git.
Про Nginx, CGI и PHP-FPM
Nginx сам по себе не умеет обрабатывать PHP, и если вы направите его на index.php, то в респонсе получите содержимое скрипта. Nginx может обслуживать статические файлы, такие как HTML, CSS и JavaScript, а для обработки PHP-скриптов ему нужна помощь.
CGI (Common Gateway Interface) — один из первых сценариев обработки php-скриптов сервером. В этом режиме каждый php-запрос выполняется отдельным процессом. Производительность сайта невысокая, так как на обработку скриптов требуется много ресурсов. Сейчас он используется редко и считается устаревшим.
Развитием CGI стал FastCGI. Была учтена медленная скорость CGI и применили циклическую обработку нескольких запросов одним процессом. FastCGI — экономит ресурсы сервера за счет сокращения количества запущенных процессов.
PHP-FPM (FastCGI Process Manager), «Менеджер процессов FastCGI». Это уже не протокол или интерфейс, а исполняемая программа, Linux пакет. Это компонент, который реализует протокол FastCGI и соединяет Nginx с нашим Laravel приложением.
По сути, PHP-FPM это балансировщик нагрузки, распределяющий работу между множеством интрефейсов (FastCGI).
Что у нас есть на старте
Кроме непреодолимого желания, у нас есть выделенный сервер и доступы к нему:
-
ip-адрес
-
логин (в моём случае
root) -
пароль
Проект для разворачивания как и в предыдущей статье — демо админ-панели для проектов на Laravel — MoonShine.
Git репозитории: локальный и удаленный (приватный) на GitHub уже настроены и связаны (как это делали).
Установка операционной системы
Смотрим, есть ли операционная система на сервере. В моём случае это Ubuntu 20.04.
У моего провайдера есть возможность выбрать операционную систему через панель управления, возможно у вашего провайдера придется ставить операционную систему самостоятельно или брать дополнительную услугу.
Можно приступать! Копируем папку с проектом на сервер (шутка).
Открываем терминал и подключаемся к серверу. Вводим:
ssh имя_пользователя@ваш_ip_адрес
Вводим пароль. Видим, что приглашение для ввода поменялось — мы авторизованы.

Создаём отдельного пользователя под проект
Хорошей практикой с точки зрения безопасности и управления доступом будет создание отдельного пользователя для каждого проекта что обеспечит изоляцию проектов на одном сервере.
Создадим пользователя localadmin и настроим ему директорию:
useradd -G root -u 1000 -d /home/localadmin -m -k /etc/skel localadmin
Установим пароль для пользователя localadmin:
passwd localadmin
Создадим для пользователя директорию .ssh и файл authorized_keys:
mkdir -p /home/localadmin/.ssh touch /home/localadmin/.ssh/authorized_keys
Настроим владельца директорий и файлов (папку с проектом создадим позднее, тогда и установим права на неё):
chown -R localadmin:localadmin /home/localadmin
Настроим права доступа:
chmod 700 /home/localadmin/.ssh chmod 644 /home/localadmin/.ssh/authorized_keys
Чтобы Linux не запрашивал каждый раз пароль при выполнении команд от имени суперпользователя (sudo), выполним команду:
echo "localadmin ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/localadmin
Входим в систему под созданным пользователем:
su - localadmin
Настройка подключения по SSH
Более удобно в дальнейшем подключаться к серверу по SSH:
1. Создадим SSH ключи на локальной машине:
-
выполните команду
ssh-keygenв терминале -
следуйте инструкциям для создания новой пары ключей (публичного и приватного)
-
по умолчанию ключи будут сохранены в директории:
Windows — С://Users/username/.ssh/id_rsa (или другой диск, на котором установлена Windows)
Linux — /home/username/.ssh/id_rsa
MacOS — /Users/username/.ssh/id_rsa

2. Добавим публичный ключ (*.pub) на сервер:
-
отобразите содержимое публичного ключа на локальном рабочем месте:
cat ~/.ssh/id_rsa.pub
-
скопируйте содержимое публичного ключа
-
на сервере откройте файл
~/.ssh/authorized_keysс помощью текстового редактора -
вставьте скопированный публичный ключ в конец файла
authorized_keys. Убедитесь, что каждый ключ находится на новой строке.
Также можно отключить вход на сервер по паролю и разрешить только аутентификацию через SSH. Для этого нужно отредактировать файл конфигурации SSH на сервере:
sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
Продолжаем. На старте у нас чистая система и нужно все установить и настроить окружение с нуля.
Обновим все пакеты в системе. Нужно держать в актуальном состоянии компоненты операционной системы, чтобы её работа была безопасной и стабильной. Сначала обновляем список доступных пакетов:
sudo apt update

Затем можно обновить до последней версии все пакеты в системе:
sudo apt full-upgrade

Nginx
Теперь можно переходить к установке веб-сервера Nginx:
sudo apt install nginx

Проверим, правильно ли установлен Nginx — перейдём в браузере на ip адрес сервера:

Отлично, появилась стандартная страница Nginx. Чуть позднее разберемся как это работает.
Устанавливаем MySQL
Выполняем команду:
sudo apt install mysql-server

Видим, что MySQL 8 версии установлен.
MySQL поставляется с скриптом mysql_secure_installation, который помогает установить некоторые настройки безопасности по умолчанию: установку пароля root, удаление анонимных пользователей, удаление тестовой базы данных и т.д.:
sudo mysql_secure_installation
Запускается диалог, в котором быстро настраивается СУБД:
-
Validate password component. Можно его не настраивать, но помним что пароль должен быть надёжным — длинный, буквы в разном регистре и т.д.
-
Remove anonymous users? Удаляем.
-
Disallow root login remotely? Соглашаемся — запрещаем удаленный вход в систему MySQL от имени пользователя root. Это является хорошей практикой безопасности. Пользователь root в MySQL обладает максимальными привилегиями и может выполнять любые операции с базой данных. Если злоумышленник получит доступ к учетной записи root, он может с нашей базой делать всё что захочет.
-
Remove test database and access to it? Удаляем тестовую базу данных.
-
Reload privilege tables now? Перезагружаем чтобы изменения применились

Создадим нового пользователя для базы данных проекта. В целях безопасности всегда нужно создавать отдельного пользователя для базы данных каждого проекта. Заходим в MySQL под root:
sudo mysql -u root -p
и вводим пароль текущего пользователя системы. Вошли, проверяем, что приглашение изменилось на mysql>.

Создаём пользователя:
CREATE USER 'имя_пользователя'@'localhost' IDENTIFIED WITH mysql_native_password BY 'пароль';
имя_пользователяипарольустанавливаем свои!
Проверим, создан ли пользователь:
SELECT host, user FROM mysql.user\G;

Теперь создаем базу данных для проекта:
CREATE DATABASE имя_базы;

И даём пользователю доступ к базе:
GRANT ALL PRIVILEGES ON имя_базы.* TO 'имя_пользователя'@'localhost';

Заканчивая работу по настройке MySQL, необходимо перезагрузить привилегии, чтобы все сделанные изменения вступили в силу. Не забывайте каждый раз перезагружать привилегии после внесения изменений:
FLUSH PRIVILEGES;

База данных подготовлена.
В целях безопасности базы данных можно выполнить еще несколько настроек.
Дополнительные настройки безопасности:
-
Отключение удалённого подключения. В файле конфигурации MySQL (обычно my.cnf или my.ini) можно указать параметр bind-address и установить его значение на localhost или 127.0.0.1. Это ограничит доступ к MySQL только с локального сервера, и удаленное подключение будет невозможно.
-
Использование брандмауэра. Настройте брандмауэр на сервере, где установлен MySQL, чтобы блокировать входящие соединения на порт MySQL (обычно 3306) с удаленных IP-адресов.
Переходим к PHP-FPM.
Установка и настройка PHP-FPM
PHP-FPM ставим чтобы наш веб-сервер мог обрабатывать большое количество запросов одновременно.
Приложение, которое мы будем разворачивать, работает на Laravel 11 — нам понадобиться PHP 8.3 (самая свежая версия PHP на момент публикации статьи, или другую версию, в зависимости от вашего проекта).
Популярный репозиторий с последними версиями PHP от Ondřej Surý недавно стал недоступен — автор включил геоблокировку на своём сервере для IP-адресов из России. Но можно настроить зеркало этого репозитория от Яндекса. Делаем.
Добавляем GPG-ключ репозитория для PHP Ondřej Surý в систему. GPG-ключ используется для проверки подлинности пакетов, чтобы убедиться, что они не были изменены или подделаны:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C

Добавляем зеркало Yandex репозитория Ondřej Surý для PHP в список источников пакетов системы. Команда запишет строку с URL репозитория в файл /etc/apt/sources.list.d/ondrej-php.list, который APT будет использовать для поиска пакетов:
echo "deb https://mirror.yandex.ru/mirrors/launchpad/ondrej/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/ondrej-php.list

Теперь можно установить PHP-FPM. Устанавливая PHP-FPM, также установим и PHP:
sudo apt install php8.3-fpm

Проверьте установленную версию PHP:
php -v
В ответ вы должны увидеть информацию о версии PHP

И статус службы PHP-FPM:
sudo service php8.3-fpm status

Служба должна быть активной (запущенной)
Установка Git
Переходим к Git:
sudo apt install git

Проверяем:
git –version

Видим версию git.
C git всё достаточно легко, не так ли?
Установка Composer
Выполняем команду для загрузки установочного скрипта Composer:
curl -sS https://getcomposer.org/installer -o composer-setup.php

Проверяем что установщик не поврежден и не модифицирован всякими безобразниками:
HASH=$(curl -sS https://composer.github.io/installer.sig) php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

Если всё ок и хэш совпал с эталонным, то появится сообщение — Installer verified, значит, установочный файл можно использовать. Устанавливаем Composer:
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

Проверим:
composer --version

Удаляем файл composer-setup.php :
php -r "unlink('composer-setup.php');"
Устанавливаем Node.js и npm
Выполняем:
curl -sL https://deb.nodesource.com/setup_current.x | sudo -E bash -

sudo apt install -y nodejs

Проверяем:
node -v npm -v

Ставим расширения для PHP
Для каждого проекта ставится свой набор расширений для PHP.
Вот самые популярные:
php-mysql — позволяет PHP взаимодействовать с базами данных MySQL. Предоставляет функции и классы для подключения к MySQL, выполнения запросов и обработки результатов.
php-curl — обеспечивает интеграцию с библиотекой cURL. cURL (Client URL) — это инструмент для работы с URL-адресами, который позволяет выполнять HTTP-запросы, обращаться к веб-серверам, загружать файлы и многое другое. Модуль php-curl позволяет PHP-скриптам использовать функциональность cURL для взаимодействия с внешними ресурсами, такими как API, веб-сервисы и другие серверы.
php-dom — позволяет взаимодействовать с XML-документами через DOM API. Оно предоставляет функции и классы для работы с иерархической структурой дерева узлов.
php-zip — позволяет читать/записывать сжатые ZIP-архивы и файлы внутри них.
php-intl— предоставляет поддержку интернационализации (i18n) и локализации (l10n). Это расширение включает в себя библиотеку ICU (International Components for Unicode), которая обеспечивает мощные инструменты для работы с различными языками, региональными настройками и кодировками.
php-mbstring — предоставляет поддержку многобайтовых строк (multibyte strings). Многобайтовые строки используются для представления символов, которые не могут быть закодированы в одном байте, таких как символы азбуки Морзе, китайские иероглифы, японские каны и многие другие.
php-soap — обеспечивает поддержку для работы с SOAP (Simple Object Access Protocol). SOAP — это протокол для обмена структурированными информационными сообщениями в распределенной среде, использующий XML в качестве формата сообщений.
php-bcmath — для произведения арифметических операций с произвольной точностью. Laravel использует эту библиотеку для генерации и проверки CSRF-токенов, а также для работы с денежными и другими числовыми значениями.
php-cli — предоставляет возможность запускать PHP скрипты из командной строки. В контексте Laravel, может использоваться для выполнения команд Laravel Artisan.
php-common — является одним из основных пакетов расширений PHP, который включает в себя общие и основные функции и библиотеки, необходимые для работы с PHP.
php-fpm — альтернативный способ запуска PHP скриптов на веб-сервере, является отдельным процессом, который управляет выполнением PHP скриптов и обеспечивает более эффективное управление процессами PHP на сервере.
php-gd — (Graphics Draw) для работы с изображениями. Позволяет создавать, редактировать и обрабатывать изображения в различных форматах, таких как JPEG, PNG, GIF и другие.
php-opcache — для улучшения производительности PHP приложений путем кэширования скомпилированного PHP кода в памяти сервера. Это позволяет уменьшить время выполнения PHP скриптов, так как PHP код не нужно компилировать заново при каждом запросе.
php-readline — делает работу с командной строкой более удобной и эффективной (автодополнение и история команд, перемещение курсора и т.д.)
php-xml — для работы с XML (Extensible Markup Language) — создание XML документов, их парсинг, преобразование в другие форматы данных и т.д.
Я установил следующие:
sudo apt install php-mysql php-curl php-dom php-zip php-intl php-mbstring php-soap php-opcache
В вашем случае список модулей может отличаться. Если вы не уверены, какие модули уже установлены, выполнить команду php -m .
Расширения для PHP будут установлены для той версии, которая используется на вашем сервере
Каталог проекта и настройка прав доступа
Давайте создадим директорию для проекта который будем деплоить:
sudo mkdir /var/www/moonshinedemo

Для того чтобы веб-сервер Nginx мог корректно работать с файлами и директориями нашего проекта на Laravel, он должен иметь правильные права доступа, чтобы обеспечить как безопасность, так и работоспособность приложения. При установке Nginx создаётся пользователь www-data или nginx (проверить можно в файле с конфигурацией /etc/nginx/nginx.conf, директива user). В моём случае пользователь Nginx — www-data.
Общий подход настройки прав доступа для директории проекта заключается в том, чтобы установить владельца (пользователя и группу localadmin) для полного контроля и дать права Nginx на чтение.
Делаем localadminвладельцем директории проекта:
sudo chown -R localadmin:localadmin /var/www/moonshinedemo
Теперь настроим для Nginx. Владельца оставляем localadmin, а группу установим www-data:
sudo chown -R localadmin:www-data /var/www/moonshinedemo
Установим права на директорию проекта:
-
для директорий: 755 (чтение и выполнение для всех, запись для владельца)
-
для файлов: 644 (чтение и запись для владельца, чтение для остальных)
sudo find /var/www/moonshinedemo -type d -exec chmod 755 {} + sudo find /var/www/moonshinedemo -type f -exec chmod 644 {} +
Наконец, отдельно для директорий storage и bootstrap/cache устанавливаем права доступа:
-
для директорий: 775 (чтение и выполнение для всех, запись для членов группы владельца)
-
для файлов: 664 (чтение и запись для членов группы владельца, чтение для остальных)
sudo find /var/www/moonshinedemo/storage -type d -exec chmod 775 {} + sudo find /var/www/moonshinedemo/bootstrap/cache -type d -exec chmod 775 {} + sudo find /var/www/moonshinedemo/storage -type f -exec chmod 664 {} + sudo find /var/www/moonshinedemo/bootstrap/cache -type f -exec chmod 664 {} +
Теперь у Nginx есть право записывать данные в эти директории, что необходимо для кэширования и логирования.
Настройка Nginx
Если вы не знаете как работает Nginx, то предлагаю краткий экскурс.
Nginx сейчас выводит свою дефолтную страницу, давайте научимся влиять на поведение Nginx!
Nginx у нас «живет» в каталоге ../etc/nginx :
sudo nano /etc/nginx/sites-available/default
Его конфиг по умолчанию находится в /sites-available. Объясню отдельные строки конфига:
listen 80 default_server # web-сервер работает на 80 порту сервера root /var/www/html # директория проекта index index.html index.htm index.nginx-debian.html # варианты названий файлов-стартовых точек из директории проекта

Создадим в каталоге проекта /var/www/moonshinedemo файл для тестирования — index.php:
touch /var/www/moonshinedemo/index.php

Теперь откроем этот файл с помощью редактора nano:
nano /var/www/moonshinedemo/index.php
Давайте что-нибудь оригинальное тут изобразим. Пусть будет
<?php echo "Hello, поклонники Laravel!""; ?>

Жмем ctrl+s (сохраняет файл) и ctrl+x (закрыть редактор nano).
Теперь надо указать Nginx чтобы он искал проект в папке moonshinedemo. Внесем изменения в конфиг:
sudo nano /etc/nginx/sites-available/default
Редактируем следующие строки:
root /var/www/moonshinedemo index index.php
«Учим» Nginx как работать с php файлами. Раскомментируем строки:
location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; }

Чтобы изменения в конфигурацию применились, надо Nginx перезапустить:
sudo systemctl reload nginx
И проверяем работу, вводим ip-адрес:

Всё работает, файл index.php в /var/www/moonshinedemo можно удалить.
rm /var/www/moonshinedemo/index.php
Клонируем проект из GitHub
Напоминаю, что мы работаем с приватным проектом, который настраивали в прошлой статье, для работы с ним нужно сгенерировать SSH-ключи на сервере и на локальном компьютере и указать публичные ключи в настройках GitHub репозитория. Если не знаете, как это делать, посмотрите в первой части статьи.
Переходим в каталог /var/www/ и клонируем проект из GitHub репозитория в каталог moonshinedemo:
cd /var/www/moonshinedemo

git clone git@github.com:CutCodes/CutCodeDeploy.git .
Проверим:
ls -la

Всё ок, мы склонировали проект на сервер.
Остальные телодвижения
Обновляем зависимости:
composer install

Создаём .env из шаблона:
cp .env.example .env
Генерируем APP_KEY, вносим настройки для работы с базой данных, переводим в прод, указываем APP_URL , (смотрим как это делать в первой статье). После запускаем миграции:
php artisan migrate

Пересобираем ассеты:
npm install npm run build
Создаем символическую ссылку для папки хранилища в публичной директории вашего проекта Laravel. Это позволяет обращаться к файлам, хранящимся в хранилище, через URL-адреса:
php artisan storage:link

После того, как символическая ссылка создана, она не требует обновления при каждом деплое. Заново создать символическую ссылку нужно только если произошли изменения в структуре файлов или директорий, связанных с хранением файлов (например, изменение пути к директории
storage).
В настройках Nginx указываем параметры из документации Laravel (Тейлор всё протестировал). Не забудьте поменять путь к проекту (root):
server { listen 80; listen [::]:80; server_name example.com; root /var/www/moonshinedemo/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; 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; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; fastcgi_hide_header X-Powered-By; } location ~ /\.(?!well-known).* { deny all; } }
Инструкция
location /с директивойtry_files $uri $uri/ /index.php?query_string;в конфигурации Nginx для приложения на Laravel используется для обработки маршрутов и перенаправления всех запросов наindex.php, где происходит дальнейшая обработка маршрутов приложения Laravel.Эта конфигурация позволяет обеспечить правильную маршрутизацию запросов в приложении Laravel, так как все запросы будут направлены на точку входа —
index.php, где фреймворк Laravel может обработать их и вернуть соответствующий ответ.
Перезагружаем Nginx:
sudo systemctl reload nginx
Готово. Можно проверять!

Дополнительные работы по Supervisor и Cron
Для продвинутых пользователей добавил информацию по установке и настройке Supervisor и Cron на ваш сервер. Полезные инструменты!
Supervisor
Зачем нам нужен Supervisor?
Очереди — неотъемлемая часть любого Laravel приложения. Не будем затрагивать тему как они работают, все это есть в документации. А Supervisor я добавил в статью при деплой потому, что если мы без него будем использовать queue:work (обработчик очередей, который обрабатывает задачи, помещенные в очередь), то при перезапуске или сбое приложения обработчик перестанет работать! Тут нам и поможет Supervisor, это менеджер процессов, который работает в фоновом режиме (демон) и управляет другими процессами, такими как queue:work. Supervisor который контролирует рабочие процессы и их количество, а также перезапустит процессы в случае сбоя.
Давайте установим Supervisor:
sudo apt install supervisor
Для настройки Supervisor необходимо создать конфигурационный файл для каждого процесса, которым вы хотите управлять. Перейдем в директорию Supervisor (обычно это /etc/supervisor/conf.d/) и создадим конфигурационный файл для обработчика очередей Laravel — laravel-worker.conf :
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /путь-к-вашему-проекту/artisan queue:work --sleep=3 --tries=3 autostart=true autorestart=true user=www-data numprocs=8 redirect_stderr=true stdout_logfile=/путь/к/лог-файлу/worker.log
Обновите Supervisor, чтобы он прочитал новый конфигурационный файл:
sudo supervisorctl reread sudo supervisorctl update
Запустите обработчика очередей с помощью Supervisor:
sudo supervisorctl start laravel-worker
Теперь Supervisor будет управлять процессом обработки очередей Laravel и обеспечивать его непрерывную работу.
Сron
Cron — это стандартный инструмент в операционных системах Unix, который позволяет запускать задачи по расписанию. Эти задачи могут выполняться автоматически в определенное время или с определенной периодичностью.
В Laravel есть мощный функционал для планирования задач по расписанию, который называется scheduler. Также не буду перегружать статью про то как он работает, всё хорошо описано в документации.
Мы же с помощью Cron настроим чтобы каждую минуту выполнялась консольная команда Laravel schedule:run, которая под капотом будет искать задачи, которые нужно выполнить прямо сейчас. Создаётся команда так:
php artisan make:command ResetCommand
При этом создается файл команды — app/Console/Commands/ResetCommand.php
Давайте разберем пример. На демо-проекте админки MoonShine — работает команда, которая ресетит базу данных и чистит пользовательские файлы чтобы они не копились. Демо проект размещен чтобы любой желающий мог попробовать MoonShine в деле и в том числе добавить свои пользовательские данные (создать статьи, добавить изображения и т.д.). Чтобы база данных не разрасталась, сделана команда по очистке:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; class ResetCommand extends Command { protected $signature = 'app:reset-console'; public function handle(): int //откатываем все миграции и наполяем БД исходными данными { $this->call('migrate:fresh', [ '--force' => true, '--seed' => true ]); File::cleanDirectory(storage_path('app/public')); //очищаем временные файлы return self::SUCCESS; //возвращаем что команда выполнена } }
Чтобы команда выполнялась её нужно добавить в файле routes/console.php с указанием периодичности выполнения. Приготовлены такие функции, как ->daily(), ->hourly(), ->everyFifteenMinutes() и т. д.:
<?php use Illuminate\Support\Facades\Schedule; Schedule::command('ResetCommand:cron')->everyFifteenMinutes();
Переходим на сервер. На Ubuntu 20.04 Сron обычно уже предустановлен по умолчанию. Вы можете проверить, установлен ли cron, с помощью следующих команд:
sudo dpkg -l | grep cron
Если Cron не установлен выполняем команду:
sudo apt install cron
После установки Cron будет автоматически запущен. Проверяем его статус с помощью команды:
sudo systemctl status cron
Настроим автозапуск Crone при загрузке системы:
sudo systemctl enable cron
Добавляем планировщика задач Laravel в Cron. Выполните команду crontab -e, которая откроет файл редактирования текущих задач:
* * * * * cd /путь_к_вашему_проекту & php artisan schedule:run >> /dev/null 2>&1
Готово. Теперь Cron будет следить что планировщик задач Laravel (scheduler) запускается каждую минуту. А планировщик, в свою очередь, запускает команду для очистки базы данных каждые 15 минут.
Настройка SSL
Для настройки HTTPS на сервере нам понадобится Certbot. Установим его с плагином для интеграции с веб-сервером Nginx:
sudo apt install certbot python3-certbot-nginx

Запускаем Certbot для получения и установки SSL-сертификата:
sudo certbot --nginx

Certbot попросит вас подтвердить домен и может предложить включить перенаправление HTTP на HTTPS.
Certbot автоматически настроит Nginx для использования SSL, добавит необходимые настройки конфигурации:

Также Certbot создаст задачу cron для периодического обновления сертификатов. Убедитесь, что задача выполняется:
sudo systemctl status certbot.timer

Чтобы протестировать процесс процесса автоматического обновления SSL сертификата, выданного Let’s Encrypt, выполним команду:
sudo certbot renew --dry-run

Если ошибок нет, все нормально. Certbot будет продлевать ваши сертификаты, когда это потребуется, и перезагружать Nginx для активации изменений.
Выводы
Деплой на VPS сервер выполнен! Этот процесс не сложнее деплоя на shared-хостинг, если делать всё пошагово, то проблем обычно не возникает. В среднем процесс создания окружения занимает минут 40-50. Сам в работе использую только VPS серверы, разной конфигурации, в зависимости от решаемых задач.
Для вашего комфорта подготовил шпаргалку с командами по настройке окружения, чтобы ничего не забыть, и не листать статью в поисках нужной строчки.
Настройка окружения на сервере
#Обновляем все пакеты в системе sudo apt update sudo apt full-upgrade #Nginx sudo apt install nginx #MySQL sudo apt install mysql-server sudo mysql_secure_installation sudo mysql -u root –p CREATE USER 'имя_пользователя'@'localhost' IDENTIFIED WITH mysql_native_password BY 'пароль'; SELECT host, user FROM mysql.user\G; CREATE DATABASE имя_базы; GRANT ALL PRIVILEGES ON имя_базы.* TO 'имя_пользователя'@'localhost'; FLUSH PRIVILEGES; #PHP FPM sudo add-apt-repository ppa:ondrej/php sudo apt install php8.3-fpm #Git sudo apt install git #Composer curl -sS https://getcomposer.org/installer -o composer-setup.php php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer php -r "unlink('composer-setup.php');" #Node.js и npm curl -sL https://deb.nodesource.com/setup_current.x | sudo -E bash - sudo apt install -y nodejs #Расширения для PHP sudo apt install php-mysql php-curl php-dom php-zip php-intl php-mbstring php-soap php-opcache ----------- #Настройка Nginx Редактируем настройки sudo nano /etc/nginx/sites-available/default #Настройки Nginx для Laravel server { listen 80; listen [::]:80; server_name example.com; root /var/www/директория/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; 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; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; fastcgi_hide_header X-Powered-By; } location ~ /\.(?!well-known).* { deny all; } } #Перезагрузка Nginx sudo systemctl reload nginx ----------- #Создаём директорию для проекта sudo mkdir /var/www/директория #Устанавливаем на директорию текущему пользователю и Nginx sudo chown -R имя_пользователя:имя_пользователя /var/www/moonshinedemo sudo chown -R имя_пользователя:www-data /var/www/moonshinedemo sudo find /var/www/директория -type d -exec chmod 755 {} + sudo find /var/www/директория -type f -exec chmod 644 {} + sudo find /var/www/директория/storage -type d -exec chmod 775 {} + sudo find /var/www/директория/bootstrap/cache -type d -exec chmod 775 {} + sudo find /var/www/директория/storage -type f -exec chmod 664 {} + sudo find /var/www/директория/bootstrap/cache -type f -exec chmod 664 {} + ----------- #Деплой приложения #Копируем проект: git clone git@github.com:ссылка_на_проект.git . #Обновляем зависимости: composer install #Создаём .env из шаблона: cp .env.example .env #Генерируем APP_KEY: php artisan key:generate #Вносим информацию в файл .env (база данных, прод, APP_URL) #Запускаем миграции: php artisan migrate #Пересобираем ассеты: npm install npm run build
Что дальше?
Варианты деплоя на самые популярные виды хостинга мы рассмотрели. В следующей статье будем разбираться, как можно (и нужно) автоматизировать деплой. Подписывайтесь на мой блог, чтобы не пропустить!
К первой части статьи было достаточно много комментариев, в том числе по дополнению статьи, так что жду активную обратную связь и в этот раз.
Данил Щуцкий, автор проекта CutCode.
ссылка на оригинал статьи https://habr.com/ru/articles/824438/
Добавить комментарий