Heroku был одним из хостинг-провайдеров для большинства наших серверных проектов, но, поскольку в 2022 году они прекратили использование бесплатного уровня, большинство людей ищут альтернативные способы развертывания своих серверных проектов. Хотя существует множество бесплатных хостинг-провайдеров, я недавно наткнулся на Железную дорогу, когда мне пришлось развернуть одно из моих приложений на базе Node-Express-MySQL. Одна вещь, которая мне понравилась в Railway (и я уверен, что большинству из вас она тоже понравится), это то, что вам даже не нужно сохранять данные своей кредитной/дебетовой карты, когда вы начинаете с их бесплатного уровня. Конечно, вам придется использовать некоторые способы оплаты, когда ваше приложение разрастется и ваш пробный период закончится, но для большинства из нас мы не хотим сохранять наши карты для наших хобби-проектов, к которым мы не очень серьезно относимся.

С учетом сказанного, в этой статье мы поговорим о том, как мы можем бесплатно развернуть приложение на основе Node-Express-MySQL на Railway без кредитной карты.

Большинство шагов развертывания должны оставаться одинаковыми, независимо от того, какой технологический стек вы выберете.

Обзор проекта

Прежде чем мы приступим к настройке, давайте разберемся, что именно мы собираемся построить. Мы создадим очень простой API на основе узла для нашего списка покупок, где API будет возвращать идентификатор элемента, имя элемента и количество элемента.

Эта статья не о создании API с помощью NodeJS, поэтому я не буду вдаваться в подробности, но все же попытаюсь объяснить вам большинство шагов, которые нужно выполнить.

Предпосылки

Чтобы работать, у вас должен быть установлен git и настроена учетная запись GitHub, так как Railway использует вашу учетную запись Github для непрерывного развертывания.

Если вы хотите следить за развитием, я предполагаю, что у вас уже установлен node-js.

Создайте базовый сервер Node.

Первым шагом к нашему проекту является создание очень минималистского сервера узлов, который мы можем запустить на нашей локальной машине.

Начнем с создания нового каталога:

mkdir node-mysql-app

Теперь перейдите внутрь проекта, чтобы инициализировать базовый файл package.json и установить несколько зависимостей и зависимостей разработчика, необходимых для создания нашего приложения.

npm init -y
npm install express mysql2 cors
npm install -D nodemon

Для запуска любого приложения Node нам обычно нужен файл точки входа, который является корневым файлом, который передается на сервер, в нашем случае файл точки входа будет называться app.js (очень распространенное имя файла точки входа для большинства приложений узла).

Откройте файл package.json и создайте сценарий start, этот сценарий будет использоваться для запуска нашего сервера разработки и обслуживания нашего файла точки входа.

// node-mysql-app/package.json

{
  "name": "mysql-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    // Create a start script
    "start": "nodemon app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "mysql2": "^3.4.3"
  },
  "devDependencies": {
    "nodemon": "^2.0.22"
  }
}

Теперь, когда у нас есть все необходимое для создания нашего базового сервера узлов, давайте создадим новый файл с именем app.js со следующим кодом:

// node-mysql-app/app.js

const express = require("express");

const app = express();

app.get("/", (req, res) => {
  res.send("Hello world");
});

// Server will listen to port 8080
app.listen(8080, 
    () => console.log(`Server is listening on port ${8080}`)
);

Запустите npm start, чтобы запустить сервер разработки.

Теперь у нас есть очень простой сервер узлов, который возвращает "Hello world" при переходе к localhost:8080.

Хостинг БД MySQL на железной дороге

Если все прошло хорошо, и вы видите желаемый ответ на своем локальном хосте, перейдите на https://railway.app/, чтобы создать новую учетную запись Railway (войдите, если она у вас уже есть).

После того, как вы вошли в свою учетную запись Railway, вы должны увидеть панель управления, подобную этой:

Нажмите на опцию "Новый проект", чтобы создать новый проект, и выберите "MySQL" из предложенных вариантов.

Через пару секунд новый экземпляр базы данных MySQL должен быть размещен на вашей панели инструментов.

Откройте только что созданный экземпляр базы данных MySQL, и вы должны увидеть панель, подобную следующей:

Здесь, как видите, у нас есть два варианта создания новой таблицы в нашей базе данных. Вы можете либо использовать их графический интерфейс для создания новой таблицы, нажав кнопку Создать таблицу, либо запустить собственный SQL-запрос для создания таблицы. Я выполню пользовательский запрос, но не стесняйтесь использовать графический интерфейс, если хотите.

Итак, чтобы создать новую таблицу, я выполню следующий SQL-запрос на вкладке «Запрос»:

CREATE TABLE shopping_list (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    quantity VARCHAR(255),
    PRIMARY KEY (id)
);

Это создаст новую таблицу с именем shopping_list, в которой будут столбцы id, name и quantity.

Давайте теперь добавим некоторые фиктивные данные в нашу только что созданную таблицу, чтобы мы могли проверить, все ли работает нормально, когда мы завершим наш проект. Чтобы добавить некоторые данные в таблицу, мы выполним следующий запрос:

INSERT INTO shopping_list (name, quantity)
VALUES
    ('Bananas', '3'),
    ('Milk', '1 liter'),
    ('Eggs', '1 dozen');

После того, как мы добавили некоторые фиктивные данные в нашу таблицу, теперь мы готовы подключить наше приложение Node к нашей базе данных MySQL, размещенной на Railway.

Подключение приложения Node к базе данных MySQL

Чтобы подключить наше приложение Node к базе данных MySQL, вернитесь в редактор кода и создайте новый файл — db.js и добавьте следующий код:

// node-mysql-app/db.js

const mysql = require("mysql2");

connection = mysql.createConnection({
  host: // <MYSQL host>,
  port: // <MYSQL port>,
  user: // <MYSQL username>,
  password: // <MYSQL password>,
  database: // <MYSQL database name>,
});
connection.connect((err) => {
  if (err) {
    console.error("CONNECT FAILED", err.code);
  } else console.log("CONNECTED");
});

module.exports = { connection };

Замените комментарии реальными переменными конфигурации MySQL.

В приведенном выше коде вам нужно заменить закомментированные значения вашими переменными конфигурации MySQL, которые вы можете найти на вкладке «Подключение» в приложении Railway внутри вашего экземпляра БД MySQL. У меня конфиг выглядит так:

Хотя этого достаточно для подключения к базе данных MySQL, есть одна проблема с текущей настройкой.

Предоставление секретных значений, таких как имя пользователя и пароль БД, не является хорошей практикой. Чтобы избежать этого, мы обычно создаем файл .env и сохраняем в нем переменные, а затем считываем значения из файла .env вместо того, чтобы жестко кодировать их.

Итак, давайте создадим файл .env в корне нашего приложения со следующими переменными среды в нем и заменим закомментированный код вашими фактическими значениями конфигурации БД:

MYSQL_HOST=// <MYSQL host>
MYSQL_PORT=// <MYSQL port>
MYSQL_USER=// <MYSQL user>
MYSQL_PASSWORD=// <MYSQL password>
MYSQL_DB=// <MYSQL DB name>

Теперь, чтобы прочитать переменные среды из нашего Javascript, нам нужно установить пакет dotenv.

npm install dotenv

Наконец, вернитесь к файлу db.js и внесите следующие изменения:

const mysql = require("mysql2");
// Config dotnev
require("dotenv").config();

// Replace the hard-coded values with the env variables
connection = mysql.createConnection({
  host: process.env.MYSQL_HOST,
  port: process.env.MYSQL_PORT,
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
  database: process.env.MYSQL_DB,
});
connection.connect((err) => {
  if (err) {
    console.error("CONNECT FAILED", err.code);
  } else console.log("CONNECTED");
});

module.exports = { connection };

Теперь мы сможем успешно подключиться к нашей базе данных MySQL. Давайте перейдем к файлу app.js и создадим запрос GET, который возьмет все элементы из таблицы shopping_list и вернет JSON с этими значениями.

// node-mysql-app/app.js

const express = require("express");
const { connection } = require("./db");

const app = express();

app.get("/api/shopping-list", (req, res) => {
  connection.query("SELECT * FROM shopping_list", (err, data) => {
    if (err) return callback(err, null);
    res.status(200).json({
      status: "success",
      length: data.length,
      data,
    });
  });
});

app.listen(8080, () => console.log(`Server is listening on port ${8080}`));

Теперь снова запустите сервер, используя npm start, и перейдите к localhost:8080/api/shopping-list, и вы должны увидеть JSON, возвращенный с элементами из таблицы shopping_list.

Ура! 🎉
Теперь, когда наше приложение отлично работает локально, пришло время развернуть наш сервер Node на Railway.

Развертывание Node-сервера на железной дороге

Чтобы развернуть приложение на Railway, нам сначала нужно отправить код на GitHub. Я предполагаю, что вы уже знаете, как отправить код на GitHub, поэтому я не буду рассказывать об этом в этой статье, но убедитесь, что вы добавили файл .env и node_modules в .gitignore, чтобы случайно не отправить эти два файла на GitHub.

Подробнее о файле .gitignore можно прочитать здесь.

После того, как вы отправили код на GitHub, давайте вернемся к панели управления Railway и создадим новый проект, на этот раз выбрав «Развернуть из репозитория Github» из предложенных вариантов.

Вам нужно будет подключить свою учетную запись GitHub к приложению Railway для непрерывного развертывания проекта.

Выберите проект, который вы хотите развернуть, из всех проектов в вашей учетной записи GitHub, а затем нажмите Развернуть сейчас.

Вот и все! Ваше приложение готово к развертыванию, и теперь все, что вам нужно сделать, это добавить переменные среды, необходимые для запуска приложения.

Перейдите на вкладку Переменные, чтобы добавить переменные среды, где вы получите два варианта. Вы можете либо добавлять переменные по одной, либо добавлять сразу несколько переменных с помощью редактора Raw.

Обязательно замените закомментированные значения фактическими значениями переменных конфигурации MySQL.

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

Перейдите на вкладку Настройки и в разделе «Домены» вы должны увидеть две опции: я не хочу использовать личный домен, поэтому я выберу Создать домен, чтобы сгенерировать случайное доменное имя.

Мы все сделали. 😮‍💨

Теперь перейдите к вашему <domain-name/api/shopping-list>, и вы должны увидеть, как ваше приложение работает на сервере Railway.

Заключительные примечания

Хотя Железная дорога очень хорошо подходила для моих требований, и она может соответствовать и вашим требованиям, я новичок в ней и, возможно, не очень хорошо осведомлен о ее недостатках или о том, насколько она совместима с крупномасштабными приложениями. Я буду держать этот блог в курсе, если найду что-нибудь об этом.

Также, если вам понравилась эта статья, пожалуйста, проявите к ней любовь и подпишитесь на меня в Твиттере, где я делюсь большим количеством материалов о программной инженерии и веб-разработке.

Спасибо, что дочитали до конца, увидимся в следующей статье. 👋

Первоначально опубликовано на https://vedanshmehra.hashnode.dev.