Как развернуть приложения Node.js с помощью Systemd и Nginx
Введение
При развертывании веб-приложения в дроплете может возникнуть соблазн просто использовать ту же настройку, что и при разработке, т. е. запустить сервер, запустив «ruby app.rb» или «node server.js» в Терминал. Это просто и легко, при этом обеспечивая видимые журналы. Можно даже использовать экран, или tmux, или nohup, чтобы он продолжал работать даже после разрыва сеанса SSH. Это опасно: что произойдет, если сервер выйдет из строя, и никто не сможет его перезапустить?
Можно было бы использовать cgroups, и все расширенные запуски демона можно было бы получить, контролировать и настраивать унифицированным образом.
В этом руководстве используется простое приложение Node.js, но оно применимо к большинству, если не ко всем, другим (будь то Ruby, Python и т. д.). Для веб-приложений PHP вместо этого рекомендуется использовать более специализированный стек LEMP.
Команды будут предоставлены как для Fedora, так и для Arch, следите за тем, чтобы избежать неправильной настройки и/или путаницы. Если не указано, команда одинакова для обеих систем. Также рекомендуется прочитать весь учебник, прежде чем пытаться выполнить его шаг за шагом, чтобы получить представление о том, что он влечет за собой, и подходит ли он для вашей ситуации.
Предварительные сведения о системе
- Сервер с systemd. Капли Arch Linux и Fedora настроены таким образом по умолчанию.
- Nginx для использования в качестве обратного прокси-сервера http и websocket.
- Git, чтобы установить nvm и загрузить ваше приложение, если вы используете git.
- Корневой доступ. Также можно войти в систему как обычный пользователь и выполнить sudo все команды или su — или sudo su — в командной строке root.
Установить пакеты
Арка:
# pacman -Sy
# pacman -S nginx git
Федора:
# yum install nginx git
Предварительная подготовка заявки
Это настройки, которые вы можете настроить по своему вкусу, но их необходимо определить и установить перед запуском.
Пользователь
Приложение будет работать в своей отдельной учетной записи пользователя. Выберите имя, оно должно относиться к приложению, чтобы его было легко запомнить и поддерживать. Здесь используется srv-node-sample
.
# useradd -mrU srv-node-sample
Порт
Чтобы избежать конфликтов, выберите высокий порт. Здесь используется «15301».
Настройка приложения
Начните с установки того, что необходимо для запуска приложения. Для Node.js (и Ruby, Python…) есть два варианта: либо использовать среду выполнения системы, либо пользовательскую установку (например, с помощью virtualenv и т. д.).
Использование системного узла
Арка:
# pacman -S nodejs
Федора:
# yum install nodejs
Использование пользовательской установки
Это должно быть установлено в домашний каталог приложения, то есть /home/srv-node-sample
, что проще всего сделать, войдя в систему как этот пользователь:
# su srv-node-sample
$ cd
$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh
$ source ~/.nvm/nvm.sh
$ nvm install 0.10
$ nvm alias default 0.10
Затем обратите внимание, где установлен двоичный файл узла:
$ which node
/home/srv-node-sample/.nvm/v0.10.22/bin/node
Разверните свое приложение
Выполнив вход в srv-node-sample
, разверните свой код. Это только пример, ваш процесс будет отличаться.
$ git clone git@server.company.tld:user/repo.git .
$ npm install
$ grunt deploy
В этом руководстве используется следующий пример приложения:
js
var http = require('http');
http.createServer(function(req, res) {
res.end('<h1>Hello, world.</h1>');
}).listen(15301);
Затем вернитесь в корень:
$ exit
Настройка Nginx
В этом руководстве лишь кратко описана необходимая настройка, более подробное руководство по настройке Nginx см. в руководстве по nginx.
Поместите это в свой серверный блок:
location / {
proxy_pass http://localhost:15301/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Затем настройте его демон:
# systemctl enable nginx
# systemctl restart nginx
Настройка системы
Создайте служебный файл для приложения в /etc/systemd/system/node-sample.service
.
Необходимо заполнить несколько переменных:
- [двоичный файл узла] Это вывод \какой узел в качестве пользователя srv-node-sample. Либо
/usr/bin/node
, либо~/.nvm/...
указанный выше путь. - [основной файл] Это основной файл вашего приложения. Здесь ‘index.js\\».
- Не забудьте заменить
srv-node-sample
!
[Service]
ExecStart=[node binary] /home/srv-node-sample/[main file]
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node-sample
User=srv-node-sample
Group=srv-node-sample
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
Теперь запустите службу:
# systemctl enable node-sample
# systemctl start node-sample
Применение
Положение дел
# systemctl status node-sample
node-sample.service
Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
Active: active (running) since Fri 2013-11-22 01:12:15 UTC; 35s ago
Main PID: 7213 (node)
CGroup: name=systemd:/system/node-sample.service
└─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...
Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.
Журналы
# journalctl -u node-sample
-- Logs begin at Thu 2013-11-21 19:05:17 UTC, end at Fri 2013-11-22 01:12:15 UTC. --
Nov 22 01:12:15 d02 systemd[1]: Starting node-sample.service...
Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.
Nov 22 01:12:30 d02 node-sample[7213]: Sample message from application
Перезапустить, остановить и т. д.
Принудительный перезапуск:
# systemctl restart node-sample
Остановить приложение:
# systemctl stop node-sample
Приложение будет автоматически перезапущено, если оно умрет или будет убито:
# systemctl status node-sample
node-sample.service
Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
Active: active (running) since Fri 2013-11-22 01:12:15 UTC; 35s ago
Main PID: 7213 (node)
CGroup: name=systemd:/system/node-sample.service
└─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...
Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.
# kill 7213
# systemctl status node-sample
node-sample.service
Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
Active: active (running) since Fri 2013-11-22 01:54:37 UTC; 6s ago
Main PID: 7236 (node)
CGroup: name=systemd:/system/node-sample.service
└─7236 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...
Nov 22 01:54:37 d02 systemd[1]: node-sample.service holdoff time over, sch...t.
Nov 22 01:54:37 d02 systemd[1]: Stopping node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Starting node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Started node-sample.service.
PID изменился, показывая, что приложение действительно было убито и перезапущено.
Веб-сокеты
Если приложение использует веб-сокеты, в конфигурацию Nginx необходимо добавить следующие строки:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
и Nginx нужно перезагрузить:
# systemctl reload nginx