Дата публикации: 08.07.2024 в 11:59

Гайд по деплою web-приложений для новичков. Часть 2. VPS и настройка окружения

0 комментария

Привет, коллеги! 👋

Это статья - вторая часть небольшого сериала о деплое web-приложений.

Вот ссылка на первую часть - деплой проекта на Laravel на shared-хостинге с использованием GitHub. Вкратце её содержание:

  • создание приватного репозитория на GitHub и его "связь" с локальным репозиторием
  • пуш проекта на GitHub
  • клонирование репозитория с GitHub на shared-хостинг
  • настройка символических ссылок (необходимо для Laravel приложений)
  • настройка Composer
  • работа с базой данных
  • настройка .env, выполнение миграций, компиляция ассетов и рестарт очередей

Если в прошлой статье мы "ютились" в отдельном каталоге на shared-хостинге, то в этой части статьи мы будем работать на выделенном сервере (физическом или виртуальном).

Что же такое VPS? VPS (англ. virtual private server) - выделенный виртуальный сервер. Простыми словами это просто удаленный компьютер, который вам временно предоставили. Технически, каждый VPS представляет собой отдельно запущенную виртуальную машину на физическом сервере, но с точки зрения конечного пользователя, такой сервер ничем не отличается по своему функционалу и управлению от выделенного сервера.

На старте у нас будет неподготовленный сервер, и мы с нуля "накатим" операционную систему и необходимые инструменты для того, чтобы наше Laravel-приложение работало. Это называется настроить окружение.

В этой статье установим и настроим:

  1. Nginx. Бесплатный и мощный веб-сервер с открытым исходным кодом. Nginx - это приложение, которое может принимать входящие запросы от пользователей (обычно через веб-браузер) и отвечать на них, отправляя запрошенные веб-страницы или другие данные.

  2. Система управления базами данных. Будем использовать MySQL.

  3. Для работы Laravel нам нужен PHP (PHP-FPM).

  4. Далее поставим Composer.

  5. Чтобы корректно работала frontend часть нам понадобится Node/npm.

  6. Ну и 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

Запускается диалог, в котором быстро настраивается СУБД:

  1. Validate password component. Можно его не настраивать, но помним что пароль должен быть надёжным - длинный, буквы в разном регистре и т.д.

  2. Remove anonymous users? Удаляем.

  3. Disallow root login remotely? Соглашаемся - запрещаем удаленный вход в систему MySQL от имени пользователя root. Это является хорошей практикой безопасности. Пользователь root в MySQL обладает максимальными привилегиями и может выполнять любые операции с базой данных. Если злоумышленник получит доступ к учетной записи root, он может с нашей базой делать всё что захочет.

  4. Remove test database and access to it? Удаляем тестовую базу данных.

  5. 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;

База данных подготовлена.

В целях безопасности базы данных можно выполнить еще несколько настроек.

Дополнительные настройки безопасности:
  1. Отключение удалённого подключения. В файле конфигурации MySQL (обычно my.cnf или my.ini) можно указать параметр bind-address и установить его значение на localhost или 127.0.0.1. Это ограничит доступ к MySQL только с локального сервера, и удаленное подключение будет невозможно.

  2. Использование брандмауэра. Настройте брандмауэр на сервере, где установлен MySQL, чтобы блокировать входящие соединения на порт MySQL (обычно 3306) с удаленных IP-адресов.

Переходим к PHP-FPM.

Установка и настройка PHP-FPM

PHP-FPM ставим чтобы наш веб-сервер мог обрабатывать большое количество запросов одновременно.

Приложение, которое мы будем разворачивать, работает на Laravel 11 - нам понадобиться PHP 8.3 (самая свежая версия 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 минут.

Выводы

Деплой на 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.

ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай