Подробно рассказываем, как деплоить приложение Node.js на Railway и что для этого нужно знать.
Важное предисловие — в этом гайде рассматривается способ деплоя с помощью GitHub, поэтому у вас должен быть свой аккаунт на Railway и на GitHub. Для полноценного понимания текста вы должны уметь работать с Git и знать, как устроен Node.js. Если пока нет — вот наш большой бесплатный курс по Git и профессия Node.js-разработчик. Гайд будет полезен бэкенд и фронтенд-разработчикам — в процессе мы создадим небольшое hello-world приложение. Подробно код нашего приложения можно изучить здесь.
Создание приложения
В качестве примера создадим приложение на фреймворке Fastify. Если вы фронтенд-разработчик и не собираетесь делать бэкенд-приложение, не расстраивайтесь. Дальше я расскажу, как подключить SPA-приложение на React и правильно настроить деплой. Просто следуйте инструкциям.
Для создания приложения на Fastify используйте команду:
npm init fastify
Если утилита запрашивает установку дополнительных пакетов, согласитесь — введите y
:
Утилита сгенерирует файлы. После этого установите зависимости:
npm install
Проверьте, что приложение работает. Для этого его нужно запустить:
npm start
Перейдите по адресу сервера. В случае чего, приложение подскажет нужный адрес:
Теперь все готово для деплоя на Railway.
Первый деплой
Есть несколько способов деплоя: с помощью cli-утилиты и через GitHub. В нашем гайде я расскажу про второй способ.
Создайте репозиторий на GitHub и запушьте туда наше приложение. После этого зайдите в свой аккаунт на Railway и нажмите "Start a New Project". Дальше нужно выбрать "Deploy from Github repo".
Выберите нужный репозиторий с приложением, для этого можно воспользоваться поиском.
Нажмите "Deploy now". Через некоторое время приложение соберется и запустится, а в окне появится статус успешности деплоя.
Дальше нужно перейти на него, а после этого нажать "Deploy logs". В случае успешного выполнения вы должны увидеть логи работы приложения.
Приложение работает, но еще не доступно для внешнего мира. Нужно его привязать к определенному адресу. Закройте окно деплоя и вернитесь в проект, зайдите в настройки (1) и нажмите "Generate Domain" (2).
Появится адрес, по которому нужно будет перейти и дождаться, когда приложение запустится и выведет результат: {"root":true}
.
Поздравляю, проект задеплоен и уже можно звать гостей!
Читайте также: Разбираем Node.js. Как свойство main в package.json определяет точку входа
Деплой React-приложения
Теперь немного усложним проект, добавим в него SPA-приложение на React. Для этого в директории проекта выполните команду:
npx create-react-app my-app
Она создаст приложение на React в директории my-app
в корне нашего проекта. Имя приложения my-app
можно будет заменить на любое другое.
Проверьте, что приложение работает. Для этого перейдите в директорию и запустите React-приложение:
npm start
После старта откроется страница в браузере с адресом приложения, по умолчанию это http://localhost:3000. Проверьте, что вы остановили Fastify-проект, который мы создали ранее, чтобы он не занимал порт. Вы должны увидеть логотип React.
Приложение на React имеет особенность: его нужно собирать. Команда npm start
запускает Webpack-сервер, который предназначен для разработки, но не для полноценной работы. Об этом пишет само приложение после запуска:
Чтобы собрать приложение, выполните команду сборки в директории my-app
:
npm run build
После этого появится директория build
— это и есть наше собранное React-приложение, подготовленное для работы на проде. Билд не включает в себя вебпак-сервер, поэтому нам нужен какой-то другой сервер, который будет предоставлять клиентам веб-приложение. Этим сервером будет наше приложение на Fastify, которое мы до этого уже создали.
Нужно немного доработать наше Fastify-приложение, чтобы оно умело раздавать фронт. Перейдите в корень проекта, все команды ниже будут выполняться в этой директории.
Для работы со статикой (билдом React-приложения), установите библиотеку:
npm i @fastify/static
Отредактируйте файл app.js
. В него нужно импортировать установленную библиотеку:
const fastifyStatic = require('@fastify/static');
И добавьте внутри функции подключение нашего React-приложения:
fastify.register(fastifyStatic, {
root: `${process.cwd()}/my-app/build`,
});
Добавьте обработчик по умолчанию, чтобы он возвращал html-страницу:
fastify.setNotFoundHandler((req, res) => {
res.sendFile('index.html');
});
Это даст возможность открывать React-приложение при любых несуществующих роутах. Полный код файла должен получиться таким:
'use strict'
const path = require('path')
const AutoLoad = require('@fastify/autoload')
const fastifyStatic = require('@fastify/static');
module.exports = async function (fastify, opts) {
// Place here your custom code!
fastify.register(fastifyStatic, {
root: `${process.cwd()}/my-app/build`,
});
fastify.setNotFoundHandler((req, res) => {
res.sendFile('index.html');
});
// Do not touch the following lines
// This loads all plugins defined in plugins
// those should be support plugins that are reused
// through your application
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'plugins'),
options: Object.assign({}, opts)
});
// This loads all plugins defined in routes
// define your routes in one of these
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'routes'),
options: Object.assign({}, opts)
});
}
Код написан с использованием commonJS-модулей. Вы можете переделать код на ES-модули, либо оставить его как есть. Не переживайте, если что-то в коде не понятно. Основная работа уже позади.
Проверьте, что ваше приложение на React остановлено — оно может занимать порт, который нам еще понадобится. Запустите приложение Fastify и откройте его в браузере, добавив к адресу любой путь, например — http://localhost:3000/somepath. Если вы видите приложение на React, то все получилось.
Запушьте изменения в GitHub. На Railway сразу начнется автоматическая сборка приложения — вам нужно перейти в ваш проект и проверить его работу. Вы увидите, что приложение работает, но страница React недоступна. Так происходит, потому что директория build
не попадает в репозиторий, а Railway не выполняет билд. В сервисе выполняются стандартные команды для запуска приложения.
Если мы склонируем проект в новую директорию и выполним npm ci
, а затем npm start
, то приложение на React тоже не будет работать. Это произойдет и с Railway. Перед запуском должно собираться React-приложение. Для решения этой проблемы можно модифицировать package.json
. Нужно добавить в него установку зависимостей React-приложения, для этого добавьте в секцию scripts
еще одну команду:
"postinstall": "npm ci --prefix my-app"`
Эта команда будет устанавливать зависимости в директории my-app
при каждой установке зависимостей в корневом проекте.
Аналогично нужно добавить команду сборки фронтенд приложения:
"build": "npm run build --prefix my-app"
Либо это можно сделать через настройки проекта Railway. Не забудьте при этом нажать на кнопку (2):
Теперь Railway будет устанавливать зависимости в my-app
и делать сборку перед запуском приложения. Запушьте ваши изменения, проверьте работу, проверьте страницу на React.
Если что-то пошло не так, проверьте логи. Если вы правильно указали postinstall
, то в логах вы должны видеть запуск установки зависимостей:
Если вы только изучаете программирование и у вас на Railway есть бесплатный аккаунт, рекомендую удалять каждый деплой, чтобы ваше приложение не тратило ресурсы. Изначально вам доступно ограниченное количество ресурсов на сервисе, а если ваши приложения превысят лимит, то придется брать платный тариф или ждать начало нового месяца. То есть каждый месяц лимиты, которые тратит пользователь, сбрасываются, но в таком случае придется ждать.
Готовый проект для деплоя находится здесь.
На Хекслете запускается набор первого онлайн-буткемпа: Всю программу первого онлайн-буткемпа от Хекслета по профессии «Фронтенд-разработчик» можно посмотреть здесь