Настройка NGINX + NodeJS на Ubuntu Server

Обновлено Обновлено: Опубликовано Опубликовано:

Используемые термины: NGINX, NodeJS.

Приложение NodeJS может запускаться в качестве веб-сервера и самостоятельно отвечать на http-запросы. Но в связки с NGINX его работу можно сделать быстрее и надежнее. Мы рассмотрим установку всех необходимых компонентов, настройку запуска приложения NodeJS в качестве сервиса systemd, а также приведем пример развертывания типового приложения. В инструкции используются:

  • NodeJS.
  • Веб-сервер NGINX.
  • Операционная система Ubuntu Server.

Все действия будут пошаговыми — сначала мы развернем сервис на NodeJS, затем подключим NGINX и, на конец, рассмотрим установку веб-приложения.

Установка NodeJS

Установка может быть выполнена из штатного репозитория или из репозитория NodeJS. Второй вариант требует дополнительной настройки, но позволяет установить самую свежую версию пакета.

Нативная версия

Мы можем посмотреть, какая будет установлена версия следующей командой:

apt search --names-only '^nodejs$'

Мы можем увидеть что-то на подобие:

nodejs/jammy 12.22.9~dfsg-1ubuntu3 amd64
  evented I/O for V8 javascript - runtime executable

* в данном примере будет устанавливаться версия 12.

Если версия из репозитория нас устраивает, то выполняем установку:

apt install nodejs

Репозиторий NodeJS

Однако, во встроенном репозитории версия NodeJS может быть очень старой, и наше приложение может работать неправильно. Для продуктивной среды необходимо уточнить у разработчика, какая версия нужна и установить ее.

Чтобы получить другую версию NodeJS, установим curl:

apt install curl

На сайте NodeJS изучим доступные версии. Предположим, нам нужна LTS версии 20. Для удобства, создадим переменную с этим значением:

export NODE_VER=20

Теперь настроим репозиторий:

curl -sL https://deb.nodesource.com/setup_${NODE_VER}.x | sudo bash -

* в данном примере мы настроим репозиторий для 20-й версии приложения.

Теперь можно установить пакет nodejs нужной нам версии:

apt install nodejs

А для установки конкретной версии, просто указываем ее в названии пакета, например:

apt install nodejs-20.11.1

Установка завершена. Проверить запуск и посмотреть версию можно командой:

node -v

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

Запуск тестового приложения NodeJS

Для примера мы напишем маленькое веб-приложение, которое будет запускаться на порту 3000 и выводить на экран «Hello, world!».

Создаем каталог, где предполагаем хранить файлы нашего приложения:

mkdir -p /var/www/app01

Создадим файл:

vi /var/www/app01/server.js

const http = require('http');
const server = http.createServer((req, res) => {
 
  res.writeHead(200, {
    'Content-Type': 'text/plain; charset=UTF-8'
  });
  res.end('Hello, world!');
});
 
server.listen(3000, '0.0.0.0', () => {
  console.log('Start NodeJS Server on http://0.0.0.0:3000/');
});

Если в нашей системе используется брандмауэр, откроем порт 3000:

iptables -I INPUT -p tcp --dport 3000 -j ACCEPT

Запустим приложение:

node /var/www/app01/server.js

На экране должно появиться:

Start NodeJS Server on http://0.0.0.0:3000/

Открываем браузер на любом компьютере в сети и переходим по адресу http://<IP-адрес сервер>:3000 — мы должны увидеть:

Hello World

Наше приложение работает. Идем дальше.

Настройка автозапуска

Мы запустили вручную наше приложение. Давайте теперь настроим его автозапуск. Рассмотрим два варианта — с помощью pm2 и systemd.

pm2

Устанавливаем pm2:

npm install -g pm2

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

cd /var/www/app01

pm2 server.js

systemd

Если нам не подходит pm2 для управления запуском приложений nodejs, можно использовать systemd. Для этого мы создадим юнит с @ — это позволит передавать имя приложения и папку при запуске.

И так, прерываем работу нашего приложения, которое мы запустили на предыдущем шаге (CTRL + C) и создаем файл:

vi /etc/systemd/system/node@.service

[Unit]
Description=NodeJS Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/node ./server.js
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
WorkingDirectory=/var/www/%i

[Install]
WantedBy=multi-user.target

* обратите внимание на %i — это переменная, которой мы будем передавать имя нашего приложения, которое соответствует названию каталога, где оно лежит.

Перечитываем конфигурацию systemd:

systemctl daemon-reload

Разрешаем и запускаем наше приложение:

systemctl enable node@app01 --now

* снова повторимся. app01 — имя приложения в нашем примере и ему соответствует каталог /var/www/app01.

Посмотреть состояние службы можно командой:

systemctl status node@app01

Переходим по адресу http://<IP-адрес сервер>:3000 — мы, снова, должны увидеть:

Hello World

Наше приложение запускается как сервис.

Установка и настройка NGINX

Приступим к добавлению веб-сервера nginx. Его можно установить из репозитория командой:

apt install nginx

Сразу разрешим автозапуск:

systemctl enable nginx

Разрешим 80 порт в брандмауэре (если в нашей системе он используется):

iptables -I INPUT -p tcp --dport 80 -j ACCEPT

В продуктивной среде также нужно открыть и использвать https:

iptables -I INPUT -p tcp --dport 443 -j ACCEPT

Для сохранения правил лучше всего использовать iptables-persistent:

apt install iptables-persistent

netfilter-persistent save

Переходим по адресу http://<IP-адрес сервер> (без указания порта) — мы увидим приветствие от веб-сервера:

Приветствие Nginx

Открываем файл:

vi /etc/nginx/sites-enabled/default

В разделе location внесем изменения, приведя его к виду:

        ...
        location / {
                proxy_pass http://127.0.0.1:3000;
                proxy_set_header Host $host;
        }
        ...

* в нашем примере мы упростили настройку, чтобы сосредоточиться на связке NGINX + NodeJS. В продуктивной среде стоит использовать виртуальные домены. Подробнее про настройку полноценного веб-сервера можно почитать в инструкции Как настроить полноценный веб-сервер на Ubuntu.

Проверяем корректность настройки nginx:

nginx -t

Мы должны получить что-то на подобие:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Перезапускаем веб-сервер:

systemctl reload nginx

Переходим по адресу http://<IP-адрес сервер> (без порта 3000) и видим:

Hello World

Наше приложение открывается через nginx.

Удаляем лишнее

1. Так как мы настроили запросы через nginx, нужно поменять некоторые настройки. Открываем файл:

vi /var/www/app01/server.js

Находим строки:

server.listen(3000, '0.0.0.0', () => {
  console.log('Start NodeJS Server on http://0.0.0.0:3000/');
});

И меняем их на:

server.listen(3000, '127.0.0.1', () => {
  console.log('Start NodeJS Server on http://127.0.0.1:3000/');
});

* мы поменяли 0.0.0.0 на 127.0.0.1, чтобы наш сервер не слушал на всех интерфейсах — нам достаточно только локальной петли. Это более безопасный вариант работы.

Перезапустим наше приложение node:

systemctl restart node@app01

Проверим, что наше приложение слушает на порту 3000 и уже на адресе 127.0.0.1:

ss -tunlp | grep :3000

Мы должны увидеть:

tcp   LISTEN  0       128     127.0.0.1:3000     0.0.0.0:*    users:(("node",pid=2503,fd=10))

2. Теперь удалим лишнее правило в брандмауэре (открытый порт 3000, если мы его создавали). Смотрим список добавленных правил:

iptables -L --line-numbers

Находим правило с открытым портом 3000:

2    ACCEPT     tcp  --  anywhere     anywhere     tcp dpt:3000

* в данном примере оно имеет порядковый номер 2.

Удалим его:

iptables -D INPUT 2

Сохраним правила:

apt install iptables-persistent

netfilter-persistent save

Установка приложения

В установке приложений есть множество нюансов, но мы опишем типовой подход.

Нам нужен будет менеджер пакетов node. Ставим его командой:

apt install npm

Получаем проект от разработчика и копируем его в наш каталог app01. После переходим в каталог:

cd /var/www/app01/

Как правило, разработчик поставляет приложение с файлом package.json. В этом файле описаны пакеты, необходимые для работы приложения. Установим их:

npm install

npm прочитает файл package.json и выполнит установку — после в нашем каталоге с приложением появятся папка node_modules и файл package-lock.json.

Также обратите внимание, что файл для запуска сервиса node может иметь другое имя. Уточните это у разработчика и, при необходимости, отредактируйте systemd.

Готово. Наше приложение должно работать.

# DevOps # NGINX # Ubuntu # Интернет # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет