В этой статье я покажу вам, как правильно развернуть проект Laravel на Railway — инфраструктурной платформе, которая выполняет за вас все задачи по системному администрированию и DevOps.
Заставить Laravel работать на Railway достаточно просто, но есть несколько подводных камней, которые заслуживают подробного объяснения. Если только вы не хотите провести целый день в интернете, как я, в поисках несуществующих объяснений — преимущества раннего внедрения!
Одна из особенностей Railway заключается в том, что каждый раз, когда происходит развертывание, сервер вашего проекта перестраивается с вашим новым кодом, что означает, что все, что хранится в файловой системе, стирается.
Если вы не знакомы с развертыванием PHP на горизонтально масштабируемой архитектуре или сине-зеленым развертыванием, мы расскажем обо всех настройках конфигурации, которые необходимо сделать, чтобы ваш проект Laravel работал правильно.
1. Первое развертывание
Развертывание Railway основано на Nixpacks, инструменте с открытым исходным кодом (разработанным командой Railway), который считывает исходный код вашего проекта и создает совместимый образ, на котором он может быть запущен.
На стандартном проекте Laravel Nixpacks установит nginx для обработки запросов, PHP с необходимой версией вашего проекта, NodeJS с вашим любимым менеджером пакетов Yarn, pnpm или npm.
Создать проект очень просто, достаточно зайти на Railway.app/new, настроить учетную запись и выбрать репозиторий для развертывания.
Если вы предоставили Railway доступ к репозиторию GitHub, вы автоматически настроили push-to-deploy, что довольно приятно.
Теперь ваш проект развертывается, шаг сборки должен работать нормально, но вы не сможете посетить свою целевую страницу, потому что для работы Laravel необходимо несколько переменных окружения.
Вы можете вставить содержимое вашего файла .env
в редактор raw со значениями, которые вы хотели бы получить для производства.
Мы также можем указать Nixpacks добавить несколько зависимостей при сборке нашего проекта с помощью переменной окружения NIXPACKS_PKGS
, например, PHP Redis для связи с сервером Redis и PHP GD для работы с файлами изображений.
Вы можете поискать доступные пакеты здесь, чтобы убедиться в правильности синтаксиса.
При новом развертывании ваш проект автоматически начнет перестраиваться с учетом предоставленных переменных окружения.
По умолчанию ваш проект не будет общедоступен, вы можете перейти в панель настроек и создать поддомен Railway с SSL или следовать инструкциям, чтобы использовать свой собственный домен.
2. Создание базы данных
Поскольку файловая система сбрасывается при каждом развертывании, использование локальной базы данных типа SQLite невозможно. Не беспокойтесь, Railway предлагает MySQL, PostgreSQL, MongoDB и Redis.
В своем проекте Railway нажмите на кнопку new и выберите вашу любимую систему управления базами данных.
После создания вы сможете получить учетные данные в панели переменных.
Вы можете скопировать эти значения в переменную окружения вашего проекта Laravel, чтобы предоставить вашему коду доступ к базе данных.
При новом развертывании ваш проект будет автоматически перестроен с учетом предоставленных переменных окружения и предоставит вашему коду доступ к базе данных. Имейте в виду, что база данных еще не содержит ни одной таблицы, поскольку мы не запустили миграцию Laravel.
3. Redis
Отсутствие постоянной файловой системы означает, что стандартные драйверы Laravel для кэша, очереди и сессии не будут работать должным образом, отключая наших пользователей при каждом развертывании.
Чтобы исправить это, нам нужен Redis, его можно создать так же, как и базу данных MySQL/PostgreSQL.
Опять же, вам нужно будет скопировать учетные данные, найденные в панели Variables, в файл .env
, и настроить сессию, кэш и очередь Laravel на использование драйвера Redis.
4. Настройка этапа сборки
Во время развертывания Nixpack установит зависимости вашего проекта и выполнит команду сборки вашего package.json
для создания активов:
- composer require
- [yarn|npm|pnpm] install
- [yarn|npm|pnpm] run build
Это хорошо, если вы обслуживаете простой статический сайт, но здесь не хватает некоторых шагов, специфичных для Laravel.
Лучший способ сделать это — установить переменную окружения NIXPACKS_BUILD_CMD
для выполнения следующих команд:
- [yarn|npm|pnpm] run build
- php artisan optimize
- php artisan migrate —force
Обратите внимание, что нам нужно включить шаг сборки активов, поскольку в противном случае он будет заменен нашими новыми командами.
Я иллюстрирую здесь простой подход, запуская каждую команду в цепочке с &&
, но вы можете поместить все это в сценарий composer, сценарий bash или Makefile.
5. Создание рабочего сервера
Railway разрешает только один процесс на сервере, сейчас у вас есть веб-процесс, запускающий nginx и обслуживающий ваш PHP-код.
Что если вам нужен еще один процесс для запуска очереди заданий в вашем приложении?
Тогда мы просто создадим новый сервер, который будет служить именно этой цели!
В своем проекте Railway нажмите на кнопку new и снова выберите репозиторий кода, чтобы создать второй сервер.
Скопируйте все переменные окружения, чтобы убедиться, что оба экземпляра кода работают с одинаковой конфигурацией, и переопределите переменную NIXPACKS_START_CMD
, чтобы запустить Laravel queue worker вместо веб-сервера.
Теперь ваш рабочий должен обрабатывать задания очереди. Вы можете создать столько рабочих, сколько захотите, с различной конфигурацией, чтобы удовлетворить потребности вашего проекта.
6. Заставьте подписанный маршрут работать
Возможно, вы уже сталкивались с проблемами подписанных маршрутов, если раньше работали с балансировщиком нагрузки.
При настройке проекта Railway будет получать запрос и проксировать его на ваш сервер с помощью протокола HTTP.
Request -https-> Railway -http-> Server
При генерации подписанного маршрута Laravel создаст хэш-значение полного URL (который будет https), но когда пользователь нажмет на ссылку, ваш код проверит хэш подписи с URL, начинающимся с http
вместо https, что сделает подпись недействительной.
Есть две вещи, которые вы можете добавить в свой код, чтобы предотвратить это. Во-первых, заставьте все URL генерироваться с протоколом https
. Это можно сделать в методе загрузки AppServiceProvider
:
public function boot()
{
if ($this->app->environment('production')) {
URL::forceScheme('https');
}
}
Затем нам нужно доверять Railway proxy для обслуживания https
, это можно настроить в промежуточном ПО TrustProxies
, установив свойство proxies
на подстановочный символ *
:
<?php
namespace AppHttpMiddleware;
use IlluminateHttpMiddlewareTrustProxies as Middleware;
use IlluminateHttpRequest;
class TrustProxies extends Middleware
{
protected $proxies = '*';
...
}
Использование подстановочного знака, возможно, не является лучшей практикой, но я не смог найти список IP-адресов железных дорог, дайте мне знать, если вы его найдете!
7. Сине-зеленое развертывание
Наконец, нам нужно сделать развертывание с нулевым временем простоя. Для этого нам нужно убедиться, что когда новое развертывание создает новый сервер, Railway может убедиться, что наш код работает правильно, прежде чем переключить трафик пользователей на новый сервер и выключить предыдущий.
Railway предлагает проверки здоровья, которые делают именно это, вы можете выбрать маршрут, который будет запрошен, и когда он вернет код успеха (2xx), Railway будет знать, что ваш сервер готов принимать запросы.
Заключение
Я давно искал «Vercel для PHP», Railway все еще молодой сервис, которому не хватает некоторой гибкости, но опыт разработчиков компенсирует это. Мне не терпится увидеть, как он будет развиваться в последующие годы!
Тем не менее, я по-прежнему использую такие сервисы, как Laravel Vapor или Laravel forge, которые дороже, но предлагают лучшую производительность, гибкость, конфигурацию и остаются моими платформами для серьезных профессиональных проектов.