Часто новички начинают разработку с фронтенда: результат работы сразу видно в браузере, а простые изменения можно вносить прямо через встроенные инструменты разработчика (DevTools). Это удобно и создает соблазн писать всю логику приложения — не только интерфейс, но и важные вычисления — прямо в браузерном коде.

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

Чтобы работать с кодом не только удобно, но и безопасно, разработчики используют платформу Node.js. В инструкции расскажем, как создать веб-сервер на JavaScript: подключиться к удаленному серверу по SSH, сгенерировать ключи и задеплоить проект в облако, чтобы он был доступен пользователям по сети. Подробнее — под катом.  

Автор: Honey Montana, JavaScript-разработчик и автор YouTube-канала.

Почему серверная логика безопаснее

Если логика работает в браузере, пользователь может:

  • открыть DevTools (F12 в большинстве браузеров);

  • найти нужную функцию в исходном коде;

  • переписать код на лету — например, сделать шанс победы всегда равным 100%;

  • обойти проверки оплаты или получить бесплатный доступ к платным функциям.

Когда же логика выполняется на сервере, вмешаться в ее процесс напрямую невозможно. Клиент (браузер пользователя) отправляет запрос на сервер, тот выполняет вычисления в защищенной среде и отдает пользователю только готовый результат. Сам алгоритм остается полностью скрытым.

Чтобы защитить важные части приложения, нужно вынести вычисления на бэкенд. Для этого нам нужен облачный веб-сервер, который будет:

  • принимать запросы от клиента;

  • обрабатывать их внутри Node.js;

  • отправлять обратно только результат.

Node.js из коробки предоставляет все необходимое для поднятия веб-сервера: модуль http для обработки HTTP-запросов и отправки ответов, встроенные средства работы с потоками и буферами для эффективной обработки данных, а также базовый модуль fs для чтения и записи файлов на диске. Давайте разберемся, как это устроено.

Облачная инфраструктура для ваших проектов

Виртуальные машины в Москве, Санкт-Петербурге и Новосибирске с оплатой по потреблению.

Подробнее →

Создание веб-сервера в Node.js

Чтобы быстро разобраться с любой технологией, нужно попробовать ее на практике — так мы и поступим. Для демонстрации я напишу простой функционал рулетки, где будет 10% шанса на победу.

Node.js содержит встроенный модуль http, который позволяет создавать собственный сервер без дополнительных библиотек. Это значит, что мы можем сразу запустить веб-приложение и обрабатывать запросы пользователей, не устанавливая ничего лишнего.

Создайте файл server.js и добавьте следующий код:

const http = require('http');

const server = http.createServer((req, res) => {
  // Устанавливаем код ответа и заголовки
  res.writeHead(200, { 'Content-Type': 'application/json' });

  // Простая серверная логика (пример: расчёт победы)
  const win = Math.random() < 0.1; // 10% шанс победы

  const result = {
    outcome: win ? "? WIN" : "? LOSE",
    reward: win ? 100 : 0,
  };

  // Отправляем результат как JSON
  res.end(JSON.stringify(result));
});

// Сервер слушает порт 3000
server.listen(3000, () => {
  console.log("Server is running on <http://localhost:3000>");
});

Что делает команда

require('http') подключает встроенный модуль Node.js для работы с HTTP-протоколом. 

http.createServer() создает веб-сервер. В качестве аргумента принимает функцию-обработчик, которая вызывается каждый раз, когда кто-то обращается к серверу.

Параметры обработчика

  • req (request) — объект с информацией о запросе клиента: метод (GET, POST и т. д.), путь, например /api/game, заголовки, тело запроса.

  • res (response) — объект для отправки ответа клиенту.

res.writeHead(200, { ... }) устанавливает код ответа и заголовки. Первый параметр — код состояния HTTP, второй — заголовки ответа. Здесь мы указываем, что отправляем JSON.

Коды состояния HTTP — это трехзначные числа, которые сообщают клиенту о результате запроса.

  • 200 — все хорошо, запрос успешно обработан.

  • 3xx — перенаправление (например, 301 — страница переехала).

  • 4xx — ошибка клиента (404 — страница не найдена, 403 — доступ запрещен).

  • 5xx — ошибка на сервере (500 — внутренняя ошибка сервера).

Math.random() генерирует случайное число от 0 до 1. Если оно меньше 0,1 (то есть в 10% случаев), пользователь выигрывает.

res.end() завершает обработку запроса и отправляет ответ клиенту. 

JSON.stringify() преобразует JavaScript-объект в строку формата JSON.

server.listen(3000) запускает сервер на порту 3000. 

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

Локальный запуск сервера

Запустите сервер командой: 

node server.js

Вы увидите сообщение «Server is running on http://localhost:3000».

Localhost — специальный адрес, который всегда указывает на ваш собственный компьютер. Число 3000 — это порт, на котором работает сервер.

Откройте браузер и перейдите по адресу http://localhost:3000. Вы увидите JSON-ответ примерно такого вида:

{"outcome":"? LOSE","reward":0}. 

Обновите страницу несколько раз (F5) и в 10% случаев вы увидите:

{"outcome":"? WIN","reward":100}

Сейчас сервер работает только локально — доступ к нему есть лишь у вас на компьютере. Чтобы проект был доступен другим людям в интернете 24/7, его нужно развернуть на облачном сервере.

Работа с зависимостями: package.json

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

В папке с проектом выполните:

npm init -y
Что делает команда
  • npm — Node Package Manager, встроенный менеджер пакетов Node.js для установки библиотек.

  • init создает файл package.json.

  • y автоматически соглашается со всеми настройками по умолчанию.

После выполнения команды в папке появится файл package.json:

{
  "name": "node-server-demo",
  "version": "1.0.0",
  "description": "Simple Node.js web server",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "keywords": ["node", "server"],
  "author": "Your Name",
  "license": "MIT"
}
Зачем нужен package.json
  • Описывает проект и его метаданные.

  • Хранит список зависимостей (библиотек), которые нужно установить.

  • Позволяет запускать проект одной командой: npm start.

  • Помогает другим разработчикам воспроизвести окружение проекта.

Если бы мы использовали внешние библиотеки — например, Express для более удобной работы с HTTP — они бы автоматически добавились в раздел dependencies при установке через npm install.

Генерация SSH-ключа

SSH (Secure Shell) — протокол для безопасного управления удаленными машинами по зашифрованному каналу. Он позволяет:

  • подключаться к серверу без пароля через криптографические ключи;

  • выполнять команды в терминале удаленной машины, как если бы вы сидели за ней;

  • безопасно передавать файлы между компьютерами.

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

Публичный ключ — замок на двери сервера, п��иватный — ваш уникальный ключ к этому замку.

Чтобы сгенерировать SSH-ключ, выполняем команду в терминале:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  • ssh-keygen — утилита для генерации SSH-ключей.

  • -t rsa — тип алгоритма шифрования. RSA — один из самых распространенных.

  • -b 4096 — длина ключа в битах. 4096 — современный стандарт, но обычно чем больше, тем безопаснее. 

  • -C "your_email@example.com" — комментарий для идентификации ключа (обычно указывают email). 

Программа спросит, куда сохранить ключ. Нажмите Enter для сохранения в стандартное место:

Enter file in which to save the key (/Users/your_name/.ssh/id_rsa):

Затем предложит установить пароль (passphrase). Можно оставить пустым, нажав Enter дважды.

После этого появятся два файла:

  • ~/.ssh/id_rsa — приватный ключ (никому не передавать);

  • ~/.ssh/id_rsa.pub — публичный ключ (его загружаем на сервер).

Посмотрите содержимое публичного ключа:

cat ~/.ssh/id_rsa.pub

Скопируйте весь вывод — он понадобится при создании сервера.

Создание облачного сервера

Заходим в панель управления Selectel и создаем новый облачный сервер. Поскольку проект небольшой, используем минимальную конфигурацию.

  • 1 CPU, 1 ГБ RAM, 10 ГБ SSD. 

  • ОС: Ubuntu 24.04 LTS. 

  • SSH-ключ: ~/.ssh/id_rsa.pub

Ubuntu — одна из самых популярных и дружелюбных к новичкам Linux-систем. Большинство инструкций в интернете написаны именно для нее.

Запустите сервер и дождитесь, пока он получит публичный IP-адрес — например, 185.104.248.123.

После запуска получаем его публичный IP. Далее вводим в терминал:

ssh root@<IP-адрес>

При первом подключении система спросит, доверяете ли вы серверу. Напишите yes и нажмите Enter.

Если все настроено правильно, вы увидите приветствие Ubuntu и окажетесь в терминале облачного сервера. Теперь все команды будут выполняться на сервере, а не на вашем компьютере.

Деплой Node.js приложения

Установка на сервер

Устанавливаем Node.js на облачный сервер с Ubuntu. Убедитесь, что вы подключены к серверу по SSH, затем выполните:

curl -fsSL <https://deb.nodesource.com/setup\_20.x> | sudo -E bash -
sudo apt install -y nodejs
Что делает команда
  • curl — утилита для загрузки файлов из интернета.

  • setup_20.x — скрипт для добавления репозитория Node.js версии 20.

  • sudo apt install nodejs — установка Node.js и npm.

Проверьте установку:

node --version
npm --version

Вы должны увидеть номера версий — например, v20.11.0 и 10.2.4.

Публикация на GitHub

На вашем локальном компьютере, в папке с проектом, выполните:

# Инициализация Git-репозитория
git init

Команда создает пустой Git-репозиторий — систему контроля версий, которая отслеживает изменения в коде.

# Добавление файлов в репозиторий
git add .

Символ «.» позволяет добавить все файлы из текущей папки.

# Создание первого коммита
git commit -m "first commit"

Коммит — это снимок состояния проекта с описанием изменений.

Привязываем локальный репозиторий к GitHub:

# Создание главной ветки
git branch -M main

Меняем название ветки по умолчанию в main, современный стандарт вместо master.

# Привязка к GitHub
git remote add origin https://github.com/<ваш-логин>/<имя-репозитория>.git

origin — стандартное имя для удаленного репозитория.

Загружаем код на GitHub:

git push -u origin main

Теперь проект хранится в GitHub и доступен с любого компьютера или сервера.

Запуск сервера

Чтобы скопировать проект на облачный сервер, подключаемся по SSH и выполняем:

git clone <https://github.com/><ваш-логин>/<имя-репозитория>.git
cd <имя-репозитория>

git clone — скачивает проект из GitHub на сервер. 

cd — переходит в папку проекта.

После этого весь код окажется на сервере, и его можно запускать:

node server.js

Вы увидите: «Server is running on http://localhost:3000». Но есть проблема: сервер работает только пока открыт терминал. Закрыли консоль или разорвалось подключение — процесс остановился, и сайт перестал работать.

Чтобы сервер работал постоянно, используем pm2 — менеджер процессов для Node.js. Он решает сразу несколько задач:

  • поддерживает сервер постоянно запущенным, даже если вы выйдете из терминала;

  • автоматически перезапускает приложение при сбое;

  • позволяет удобно управлять проектом (старт, стоп, рестарт, просмотр логов);

  • может запускать несколько процессов для балансировки нагрузки.

«Работать постоянно» — значит, что приложение будет доступно круглосуточно, а пользователи смогут подключаться к нему в любое время. Независимо от того, открыта ли у вас консоль и случился ли на сервере сбой.

Устанавливаем и запускаем pm2. 

npm install -g pm2
pm2 start server.js

Также можно использовать автозапуск при перезагрузке сервера:

pm2 startup
pm2 save

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

Полезные команды pm2 

pm2 list          # список всех процессов

pm2 logs          # просмотр логов

pm2 restart server # перезапуск приложения

pm2 stop server   # остановка приложения

pm2 delete server # удаление процесса из PM2

Настройка файрвола и открытие портов

По умолчанию сервер слушает порт 3000, но снаружи может быть недоступен из-за настроек файрвола.

Проверьте, открыт ли порт 3000:

sudo ufw status

Если файрвол активен, откройте нужные порты:

sudo ufw allow 3000/tcp
sudo ufw allow 22/tcp   # SSH, чтобы не потерять доступ
sudo ufw enable

Важно: порт 22 нужен для SSH-подключения. Не блокируйте его, иначе не сможете подключиться к серверу.

Тестирование развернутого приложения

Ваш сервер работает в облаке — давайте проверим, все ли корректно. 

Откройте браузер и перейдите по адресу:

<http://185.104.248.123:3000>

Замените 185.104.248.123 на реальный IP-адрес вашего сервера. Вы должны увидеть JSON-ответ:

{"outcome":"? LOSE","reward":0}

Обновите страницу несколько раз — примерно в 10 % случаев появится:

{"outcome":"? WIN","reward":100}

Поздравляю! Ваш сервер работает и доступен из интернета.

Проверка с другого устройства

Откройте браузер на телефоне и перейдите по указанному адресу. Убедитесь, что устройство подключено к мобильному интернету, а не к Wi-Fi. Если настройки выполнены корректно, вы получите ответ от сервера.

curl <http://185.104.248.123:3000>

Эта команда отправит HTTP-запрос и выведет ответ сервера. При переходе в браузере вы увидите примерно это:

Страница с текстом:

{"outcome":"? LOSE","reward":0}

Это и есть JSON-ответ вашего сервера — именно так выглядит API (Application Programming Interface), к которому могут обращаться фронтенд-приложения, мобильные приложения или другие сервисы.

Заключение

В инструкции разобрали, как работает веб-сервер в Node.js, как подключиться к удаленной машине по SSH, сгенерировать ключи и задеплоить свой проект. Теперь ваша серверная логика надежно защищена — пользователи видят только результат, но не сам код. Вы развернули приложение в облаке и сделали свой проект доступным для пользователей по всему миру.

Этот материал написан по мотивам видео «Спидран по JAVASCRIPT».

Комментарии (0)