Подготовка приложения Node.js к производству в Ubuntu 16.04

Node.js – это платформа JavaScript для программирования общего назначения, которая позволяет быстро создавать сетевые приложения. Данная платформа работает в Linux, OS X, FreeBSD и Windows. Приложения Node.js можно запускать в командной строке, но данное руководство продемонстрирует, как запустить приложение в качестве сервиса (в таком случае приложение сможет автоматически перезагружаться вместе с сервером или при сбое и будет безопасно для использования в производственной среде).

Данное руководство поможет подготовить среду Node.js к производству на сервере Ubuntu 16.04. Приложение Node.js будет управляться PM2 и предоставит пользователям безопасный доступ при помощи обратного прокси-сервера Nginx. Сервер Nginx будет поддерживать трафик HTTPS с помощью бесплатного сертификата от сервиса Let’s Encrypt.

Требования

  • Сервер Ubuntu 16.04.
  • Не root пользователь с доступом к sudo.
  • Домен, направленный на внешний IP-адрес сервера.

Установка Node.js

Для начала нужно установить Node.js при помощи архива NodeSource.

Установите PPA в домашний каталог, чтобы получить доступ к его содержимому. Используйте curl, чтобы извлечь установочный скрипт необходимой версии (укажите её вместо 6.x ):

cd ~
curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh

Чтобы просмотреть содержимое скрипта, введите:

nano nodesource_setup.sh

Запустите скрипт:

sudo bash nodesource_setup.sh

Архив PPA будет добавлен в настройки. Индекс пакетов обновится автоматически. После запуска установочного сценария nodesource можно установить пакет Node.js:

sudo apt-get install nodejs

Пакет nodejs содержит бинарный файл nodejs и npm (потому вам не придётся устанавливать npm отдельно). Однако для работы некоторых компонентов npm (компилирующих исходный код и т.п.) необходим пакет build-essential:

sudo apt-get install build-essential

Примечание: При установке Node.js из архива PPA бинарный файл, как правило, называется nodejs, а не node.

Теперь можно приступать к созданию приложения.

Создание приложения Node.js

В качестве примера можно создать простое приложение Hello World; оно будет возвращать фразу Hello World на любой запрос HTTP. Такое приложение можно в дальнейшем использовать в качестве шаблона для более сложного приложения.

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

Код приложения Hello World

Создайте приложение Node.js и откройте его в текстовом редакторе (в руководстве файл называется hello.js):

cd ~
nano hello.js

Вставьте в файл следующий код. При необходимости можно заменить номер порта (он должен быть от 1024 и больше).

var http = require('http');
#!/usr/bin/env nodejs
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080, 'localhost');
console.log('Server running at http://localhost:8080/');

Сохраните и закройте файл.

Данное приложение будет слушать заданный адрес (localhost) и порт (8080) и возвращать фразу Hello World с HTTP-кодом 200. При прослушивании localhost удалённые клиенты не смогут получить доступ к приложению.

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

Чтобы протестировать приложение, создайте исполняемый файл hello.js:

chmod +x ./hello.js

Запустите его:

./hello.js
Server running at http://localhost:8080/

Примечание: Запуская Node.js таким образом, вы блокируете дополнительные команды. Команды будут доступны после остановки приложения (Ctrl-C).

Чтобы протестировать приложение, откройте новый терминал и подключитесь к localhost с помощью curl:

curl http://localhost:8080

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

Hello World

Если такой вывод не появился, убедитесь, что приложение Node.jsзапущено и правильно настроено (слушает правильный адрес и порт).

Остановите приложение, нажав Ctrl+C.

Установка PM2

Теперь нужно установить PM2. Это менеджер процессов Node.js. PM2 предоставляет простой способ управления и демонизации приложений.

Установку можно выполнить при помощи пакетного менеджера npm.

sudo npm install -g pm2

При помощи опции –g менеджер npm выполнит глобальную установку PM2.

Управление приложением с помощью PM2

Менеджер процессов PM2 очень прост в использовании. Рассмотрим основы его работы.

Запуск приложения

Для запуска приложений в фоновом режиме используется команда pm2 start:

pm2 start hello.js

Также эта команда добавит приложение в список процессов PM2, который выводится на экран при запуске каждого приложения:

[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Starting hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ memory      │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello    │ 0  │ fork │ 3524 │ online │ 0       │ 0s     │ 21.566 MB   │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app

Как видите, PM2 автоматически устанавливает App name (имя файла без расширения .js) и PM2 id. Также PM2 предоставляет другую информацию: PID процесса, текущее состояние, использование памяти.

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

Эта команда генерирует и настраивает сценарий запуска менеджера PM2 и всех его процессов вместе с загрузкой сервера. Также нужно указать платформу (в данном случае это ubuntu).

pm2 startup systemd

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

[PM2] You have to run this command as root. Execute the following command:
sudo su -c "env PATH=$PATH:/usr/bin pm2 startup systemd -u 8host --hp /home/8host"

Запустите сгенерированную команду, чтобы настроить автозапуск PM2.

sudo su -c "env PATH=$PATH:/usr/bin pm2 startup systemd -u 8host --hp /home/8host"

Эта команда создаст unit-файл для systemd, запускающий pm2 при запуске сервера. Менеджер pm2, в свою очередь, запустит приложение hello.js. Проверьте состояние юнита systemd:

systemctl status pm2

Другие функции PM2 (опционально)

PM2 предоставляет множество других функций, которые позволяют управлять или просматривать информацию о приложениях. Обратите внимание, что запуск PM2 без каких-либо аргументов отобразит страницу справкина которой можно найти подробные примеры использования PM2.

Остановить приложение можно при помощи:

pm2 stop app_name_or_id

Чтобы перезапустить приложение, введите:

pm2 restart app_name_or_id

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

pm2 list

Подробную информацию о конкретном приложении можно получить с помощью подкоманды info:

pm2 info example

Подкоманда monit показывает данные процесса PM2: состояние приложения, использование CPU и памяти:

pm2 monit

Теперь нужно настроить обратный прокси.

Nginx как обратный прокси-сервер

Итак, приложение запущено и прослушивает localhost. Теперь нужно настроить доступ к нему. Установите Nginx как обратный прокси-сервер.

Примечание: Если Nginx уже установлен, скопируйте блок location в файл виртуального хоста (убедитесь, что скопированные настройки не конфликтуют с уже существующими настройками).

Чтобы установить Nginx, введите:

sudo apt-get install nginx

Откройте стандартный блок server:

sudo nano /etc/nginx/sites-available/default

Удалите все содержимое файла и вставьте предложенные ниже настройки. Измените номер порта (8080), если приложение прослушивает другой порт.

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://localhost:8080;
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;
}
}

Теперь сервер будет отвечать на запросы к root-каталогу. К примеру, если сервер доступен по домену example.com, то приложение будет доступно по ссылке:

http://example.com/

Это отправит запрос приложению hello.js на порт 8080 localhost.

В этот файл можно добавить ещё несколько блоков location, чтобы открыть доступ к другим приложениям, размещённым на этом сервере. К примеру, если бы другое приложение использовало порт 8081, блок, открывающий доступ по ссылке http://example.com/app2, имел бы такой вид:

location /app2 {
proxy_pass http://localhost:8081;
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;
}

Сохраните и закройте файл.

Перезапустите Nginx:

sudo systemctl restart nginx

Если приложение Node.js запущено, а сервер Nginx правильно настроен, теперь вы можете получить доступ к приложению через обратный прокси-сервер Nginx.

Получив доступ к приложению, приступайте к настройке защиты приложения при помощи сертификата Let’s Encrypt.

Установка Let’s Encrypt и зависимостей

Let’s Encrypt – это новый центр сертификации, который предоставляет простой способ получить бесплатные TLS/SSL сертификаты.

Для получения такого сертификата обязательно необходим домен. Если у вас нет доменного имени, зарегистрируйте его.

Создайте запись А, которая направляет домен на IP-адрес сервера. Это необходимо для подтверждения сертификата сервисом Let’s Encrypt. В противном случае сертификат не будет подтвержден.

Установите зависимости клиента Let’s Encrypt – git и bc:

sudo apt-get -y install git bc

Затем клонируйте репозиторий letsencrypt с GitHub в каталог /opt/letsencrypt; это стандартный каталог для хранения дополнительных программ.

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Откройте каталог letsencrypt:

cd /opt/letsencrypt

Извлечение сертификата

Клиент Let’s Encrypt использует порт 80, однако данный порт уже занят веб-сервером nginx. Потому нужно временно остановить nginx.

sudo systemctl stop nginx

Запустите letsencrypt с плагином Standalone:

./letsencrypt-auto certonly --standalone

Клиент предложит ответить на ряд вопросов: указать адрес электронной почты, принять лицензию, ввести домен и т.п. В завершение на экране появится:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/your_domain_name/fullchain.pem. Your cert will expire
on 2016-08-10. To obtain a new version of the certificate in the
future, simply run Let's Encrypt again.
- If you like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
Donating to EFF:                    https://eff.org/donate-le

Обратите внимание на путь к сертификату и дату истечения срока его действия. Сертификат должен находиться в /etc/letsencrypt/your_domain_name/.

Настройка Nginx для поддержки HTTPS

Теперь нужно исправить настройки Nginx. Откройте файл /etc/nginx/sites-enabled/default в текстовом редакторе:

sudo nano /etc/nginx/sites-enabled/default

Замените его содержимое следующими настройками:

# HTTP - redirect all requests to HTTPS:
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
# HTTPS - proxy requests on to local Node.js app:
server {
listen 443;
server_name your_domain_name;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/your_domain_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain_name/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# Pass requests for / to localhost:8080:
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:8080/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}

Закройте редактор и сохраните файл. Снова запустите Nginx:

sudo systemctl start nginx

Проверьте сертификат, открыв в браузере ссылку:

http://your_domain_name/

При этом вы будете перенаправлены по ссылке:

https://your_domain_name/

На экране должна появится фраза Hello World.

Автоматическое обновление сертификата

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

Сертификат Let’s Encrypt действителен в течение 90 дней. Таким образом Let’s Encrypt минимизирует срок существования взломанных сертификатов.

Клиент Let’s Encrypt может выполнять обновление автоматически. Более подробную информацию об обновлении сертификата можно найти в этом руководстве.

Заключение

Теперь приложение Node.js запущено и использует Nginx в качестве обратного прокси на сервере Ubuntu 16.04.

Tags: , , , , ,

Добавить комментарий