Вступление
Node.js - это среда выполнения JavaScript с открытым исходным кодом для создания серверных и сетевых приложений. Платформа работает на Linux, macOS, FreeBSD и Windows. Хотя вы можете запускать приложения Node.js из командной строки, этот учебник будет посвящен запуску их как службы. Это означает, что они будут перезагружены при перезагрузке или сбое и безопасны для использования в производственной среде.
В этом руководстве вы настроите готовую к работе среду Node.js на одном сервере Ubuntu 18.04. Этот сервер будет запускать приложение Node.js, управляемоеPM2, и предоставлять пользователям безопасный доступ к приложению через обратный прокси-сервер Nginx. Сервер Nginx будет предлагать HTTPS с использованием бесплатного сертификата, предоставленногоLet’s Encrypt.
Предпосылки
В этом руководстве предполагается, что у вас есть следующее:
-
Настройка сервера Ubuntu 18.04, как описано вinitial server setup guide for Ubuntu 18.04. У вас должен быть пользователь без полномочий root с правами sudo и активным брандмауэром.
-
Adomain name pointed at your server’s public IP. В этом руководстве будет использоваться доменное имяexample.com.
-
Установлен Nginx, как описано вHow To Install Nginx on Ubuntu 18.04.
-
Nginx настроен с использованием SSL с использованием сертификатов Let Encrypt. How To Secure Nginx with Let’s Encrypt on Ubuntu 18.04 проведет вас через процесс.
Когда вы выполните предварительные требования, у вас будет сервер, обслуживающий страницу-заполнитель по умолчанию для вашего домена наhttps://example.com/
.
[[step-1 -—- install-node-js]] == Шаг 1. Установка Node.js
Начнем с установки последней версии LTS Node.js, используя архивы пакетовNodeSource.
Сначала установите NodeSource PPA, чтобы получить доступ к его содержимому. Убедитесь, что вы находитесь в своем домашнем каталоге, и используйтеcurl
для получения сценария установки для архивов Node.js 8.x:
cd ~
curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
Вы можете проверить содержимое этого скрипта с помощьюnano
или другого текстового редактора:
nano nodesource_setup.sh
Когда вы закончите проверку скрипта, запустите его подsudo
:
sudo bash nodesource_setup.sh
PPA будет добавлен в вашу конфигурацию, и ваш локальный кеш пакетов будет обновлен автоматически. После запуска сценария установки из Nodesource вы можете установить пакет Node.js:
sudo apt install nodejs
Чтобы проверить, какую версию Node.js вы установили после этих начальных шагов, введите:
nodejs -v
Outputv8.11.3
[.note] #Note: При установке из NodeSource PPA исполняемый файл Node.js называетсяnodejs
, а неnode
.
#
Пакетnodejs
содержит двоичный файлnodejs
, а такжеnpm
, менеджер пакетов для модулей Node, поэтому вам не нужно устанавливатьnpm
отдельно.
npm
использует файл конфигурации в вашем домашнем каталоге для отслеживания обновлений. Он будет создан при первом запускеnpm
. Выполните эту команду, чтобы убедиться, чтоnpm
установлен, и создать файл конфигурации:
npm -v
Output5.6.0
Чтобы некоторые пакетыnpm
работали (например, те, которые требуют компиляции кода из исходного кода), вам необходимо установить пакетbuild-essential
:
sudo apt install build-essential
Теперь у вас есть необходимые инструменты для работы с пакетамиnpm
, которые требуют компиляции кода из исходного кода.
Установив среду выполнения Node.js, давайте перейдем к написанию приложения Node.js.
[[step-2 -—- created-a-node-js-application]] == Шаг 2 - Создание приложения Node.js
Давайте напишем приложениеHello World, которое будет возвращать «Hello World» на любые HTTP-запросы. Этот пример приложения поможет вам настроить Node.js. Вы можете заменить его своим собственным приложением - просто убедитесь, что вы изменили свое приложение для прослушивания соответствующих IP-адресов и портов.
Во-первых, давайте создадим образец приложения под названиемhello.js
:
cd ~
nano hello.js
Вставьте следующий код в файл:
~/hello.js
const http = require('http');
const hostname = 'localhost';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Сохраните файл и выйдите из редактора.
Это приложение Node.js прослушивает указанный адрес (localhost
) и порт (3000
) и возвращает «Hello World!» с кодом успеха HTTP200
. Поскольку мы слушаемlocalhost
, удаленные клиенты не смогут подключиться к нашему приложению.
Чтобы протестировать ваше приложение, введите:
node hello.js
Вы увидите следующий вывод:
OutputServer running at http://localhost:3000/
[.note] #Note: Запуск приложения Node.js таким образом заблокирует дополнительные команды до тех пор, пока приложение не будет убито нажатиемCTRL+C
.
#
Чтобы протестировать приложение, откройте другой сеанс терминала на вашем сервере и подключитесь кlocalhost
с помощьюcurl
:
curl http://localhost:3000
Если вы видите следующий вывод, приложение работает правильно и прослушивает правильный адрес и порт:
OutputHello World!
Если вы не видите ожидаемого вывода, убедитесь, что ваше приложение Node.js запущено и настроено на прослушивание по правильному адресу и порту.
Убедившись, что оно работает, закройте приложение (если вы еще этого не сделали), нажавCTRL+C
.
[[step-3 -—- install-pm2]] == Шаг 3 - Установка PM2
Теперь давайте установим PM2, менеджер процессов для приложений Node.js. PM2 позволяет демонизировать приложения, чтобы они работали в фоновом режиме как служба.
Используйтеnpm
, чтобы установить последнюю версию PM2 на ваш сервер:
sudo npm install pm2@latest -g
Параметр-g
указываетnpm
установить модульglobally, чтобы он был доступен для всей системы.
Давайте сначала воспользуемся командойpm2 start
для запуска вашего приложенияhello.js
в фоновом режиме:
pm2 start hello.js
Это также добавляет ваше приложение в список процессов PM2, который выводится при каждом запуске приложения:
Output[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤
│ hello │ 0 │ fork │ 1338 │ online │ 0 │ 0s │ 0% │ 23.0 MB │ sammy │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘
Use `pm2 show ` to get more details about an app
Как видите, PM2 автоматически назначаетApp name
(на основе имени файла, без расширения.js
) и PM2id
. PM2 также поддерживает другую информацию, такую какPID
процесса, его текущий статус и использование памяти.
Приложения, работающие под управлением PM2, будут перезапущены автоматически, если приложение выйдет из строя или будет убито, но мы можем предпринять дополнительный шаг, чтобы приложение запускалось при запуске системы, используя подкомандуstartup
. Эта подкоманда генерирует и настраивает скрипт запуска для запуска PM2 и его управляемых процессов при загрузке сервера:
pm2 startup systemd
Последняя строка полученного результата будет включать команду для запуска с привилегиями суперпользователя, чтобы настроить PM2 для запуска при загрузке:
Output[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Выполните команду из вывода с вашим именем пользователя вместоsammy
:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
В качестве дополнительного шага мы можем сохранить список процессов PM2 и соответствующие среды:
pm2 save
Теперь вы создали systemdunit, которая запускаетpm2
для вашего пользователя при загрузке. Этот экземплярpm2
, в свою очередь, запускаетhello.js
.
Запустите службу сsystemctl
:
sudo systemctl start pm2-sammy
Проверьте состояние системного блока:
systemctl status pm2-sammy
Подробный обзор systemd см. ВSystemd Essentials: Working with Services, Units, and the Journal.
В дополнение к тем, которые мы рассмотрели, PM2 предоставляет множество подкоманд, которые позволяют вам управлять информацией о ваших приложениях или просматривать ее.
Остановите приложение с помощью этой команды (укажите PM2App name
илиid
):
pm2 stop app_name_or_id
Перезапустите приложение:
pm2 restart app_name_or_id
Перечислите приложения, в настоящее время управляемые PM2:
pm2 list
Получите информацию о конкретном приложении, используя егоApp name
:
pm2 info app_name
Монитор процесса PM2 можно вызвать с помощью подкомандыmonit
. Это отображает статус приложения, процессор и использование памяти:
pm2 monit
Обратите внимание, что запускpm2
без аргументов также отобразит страницу справки с примером использования.
Теперь, когда ваше приложение Node.js запущено и управляется PM2, давайте настроим обратный прокси-сервер.
[[step-4 -—- setting-up-nginx-as-a-reverse-proxy-server]] == Шаг 4 - Настройка Nginx в качестве обратного прокси-сервера
Ваше приложение работает и прослушиваетlocalhost
, но вам необходимо настроить способ доступа пользователей к нему. Для этой цели мы настроим веб-сервер Nginx в качестве обратного прокси-сервера.
В предварительном руководстве вы настроили конфигурацию Nginx в файле/etc/nginx/sites-available/example.com
. Откройте этот файл для редактирования:
sudo nano /etc/nginx/sites-available/example.com
Внутри блокаserver
должен быть существующий блокlocation /
. Замените содержимое этого блока следующей конфигурацией. Если ваше приложение настроено на прослушивание другого порта, обновите выделенную часть на правильный номер порта:
/etc/nginx/sites-available/example.com
server {
...
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}
Это настраивает сервер для ответа на запросы в его корне. Предполагая, что наш сервер доступен наexample.com
, доступ кhttps://example.com/
через веб-браузер отправит запрос наhello.js
, прослушивая порт3000
наlocalhost
.
Вы можете добавить дополнительные блокиlocation
к тому же блоку сервера, чтобы обеспечить доступ другим приложениям на том же сервере. Например, если вы также запускаете другое приложение Node.js на порту3001
, вы можете добавить этот блок местоположения, чтобы разрешить доступ к нему черезhttps://example.com/app2
:
/etc/nginx/sites-available/example.com — Optional
server {
...
location /app2 {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}
Как только вы закончите добавлять блоки местоположения для ваших приложений, сохраните файл и выйдите из редактора.
Убедитесь, что вы не вводили никаких синтаксических ошибок, набрав:
sudo nginx -t
Перезапустите Nginx:
sudo systemctl restart nginx
Предполагая, что ваше приложение Node.js запущено, а настройки вашего приложения и Nginx верны, вы теперь сможете получить доступ к своему приложению через обратный прокси-сервер Nginx. Попробуйте, перейдя по URL вашего сервера (его общедоступный IP-адрес или доменное имя).
Заключение
Поздравляем! Теперь у вас есть приложение Node.js, работающее за обратным прокси-сервером Nginx на сервере Ubuntu 18.04. Эта настройка обратного прокси-сервера достаточно гибкая, чтобы предоставить вашим пользователям доступ к другим приложениям или статическому веб-контенту, которым вы хотите поделиться.