Как запустить приложение node.js в качестве фоновой службы?
Поскольку этот пост привлек много внимания на протяжении многих лет, я перечислил лучшие решения для каждой платформы в нижней части этого поста.
Исходное сообщение:
Я хочу, чтобы мой сервер node.js работал в фоновом режиме, то есть: когда я закрываю свой терминал, я хочу, чтобы мой сервер продолжал работать. Я гуглил это и придумал этот урок, однако он не работает как задумано. Поэтому вместо того, чтобы использовать этот демон-сценарий, я подумал, что просто использовал перенаправление вывода (2>&1 >> file
часть), но это тоже не выходит - я получаю пустую строку в моем терминале, как будто он ожидает вывода / ошибок.
Я также пытался перевести процесс в фоновый режим, но как только я закрываю свой терминал, процесс также прекращается.
Так, как я могу оставить это работающим, когда я выключаю свой локальный компьютер?
Лучшие решения:
32 ответа
Копирование моего собственного ответа из Как я могу запустить приложение Node.js как его собственный процесс?
Ответ 2015 года: почти каждый дистрибутив Linux поставляется с systemd, что означает, что навсегда, monit и т. Д. Больше не нужны - ваша ОС уже выполняет эти задачи.
Делать myapp.service
file (заменив 'myapp' на имя вашего приложения, очевидно):
[Unit]
Description=My app
[Service]
ExecStart=/var/www/myapp/app.js
Restart=always
User=nobody
# Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody'
Group=nogroup
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp
[Install]
WantedBy=multi-user.target
Обратите внимание, если вы новичок в Unix: /var/www/myapp/app.js
должен иметь #!/usr/bin/env node
на самой первой линии.
Скопируйте файл службы в /etc/systemd/system
,
Начни с systemctl start myapp
,
Включить его при загрузке с systemctl enable myapp
,
Смотрите логи с journalctl -u myapp
Это взято из того, как мы разворачиваем приложения для узлов в Linux, выпуск 2018, который также включает команды для генерации AWS/DigitalOcean/Azure CloudConfig для построения серверов Linux/ узлов (включая .service
файл).
ОБНОВЛЕНИЕ - Как упоминалось в одном из ответов ниже, в PM2 есть действительно хорошая функциональность, которой не хватает навсегда. Подумайте об этом.
Оригинальный ответ
Используйте nohup:
nohup node server.js &
РЕДАКТИРОВАТЬ Я хотел бы добавить, что принятый ответ действительно путь. Я навсегда использую случаи, когда нужно не ложиться спать. я люблю делать npm install -g forever
так что это в пути узла, а затем просто сделать forever start server.js
Вы можете использовать Forever, простой инструмент CLI для обеспечения непрерывной работы данного скрипта узла (т. Е. Навсегда): https://www.npmjs.org/package/forever
Это может быть неприемлемым способом, но я делаю это с экраном, особенно в процессе разработки, потому что я могу восстановить его и, если необходимо, обмануть.
screen
node myserver.js
>>CTRL-A then hit D
Экран отсоединится и выживет после выхода из системы. Затем вы можете вернуть его обратно с помощью screen -r. Нажмите на руководство по экрану для более подробной информации. Вы можете назвать экраны и еще много чего, если хотите.
Обновление 2016 года: в серии node-windows/mac/linux используется общий API для всех операционных систем, поэтому это абсолютно актуальное решение. Тем не мение; node-linux создает системные файлы инициализации. По мере того как популярность systemd продолжает расти, это действительно лучший вариант для Linux. PR приветствуется, если кто-то хочет добавить поддержку systemd в node-linux:-)
Оригинальная тема:
Сейчас это довольно старый поток, но ноды-окна предоставляют еще один способ создания фоновых сервисов в Windows. Это свободно основано на nssm
Концепция использования exe
Обертка вокруг вашего узла скрипта. Тем не мение; оно использует winsw.exe
вместо этого и предоставляет настраиваемую оболочку узла для более детального контроля над тем, как процесс запускается / останавливается при сбоях. Эти процессы доступны как любой другой сервис:
Модуль также запекает в некоторых журналах событий:
Демонизация вашего скрипта осуществляется с помощью кода. Например:
var Service = require('node-windows').Service;
// Create a new service object
var svc = new Service({
name:'Hello World',
description: 'The nodejs.org example web server.',
script: 'C:\\path\\to\\my\\node\\script.js'
});
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
// Listen for the "start" event and let us know when the
// process has actually started working.
svc.on('start',function(){
console.log(svc.name+' started!\nVisit http://127.0.0.1:3000 to see it in action.');
});
// Install the script as a service.
svc.install();
Модуль поддерживает такие вещи, как закрытие перезапусков (чтобы плохие скрипты не мешали вашему серверу) и увеличение временных интервалов между перезапусками.
Поскольку службы узлов Windows работают, как и любые другие, можно управлять / контролировать службу с помощью любого программного обеспечения, которое вы уже используете.
Наконец, нет make
зависимостей. Другими словами, просто npm install -g node-windows
буду работать. Вам не нужна Visual Studio, .NET или магия нод-гипса, чтобы установить это. Кроме того, это MIT и BSD лицензированы.
В полном раскрытии я являюсь автором этого модуля. Он был разработан для облегчения боли, которую испытал ОП, но с более тесной интеграцией в функциональность, которую уже обеспечивает операционная система. Я надеюсь, что будущие зрители с таким же вопросом найдут его полезным.
Если вы просто хотите запустить скрипт без перерыва до его завершения, вы можете использовать nohop
как уже упоминалось в ответах здесь. Однако ни один из ответов не предоставляет полную команду, которая также регистрирует stdin
а также stdout
,
nohup node index.js >> app.log 2>&1 &
>>
значит добавить кapp.log
,2>&1
гарантирует, что ошибки также отправляютсяstdout
и добавил кapp.log
,- Концовка
&
убедитесь, что ваш текущий терминал отключен от команды, чтобы вы могли продолжить работу.
Если вы хотите запустить сервер узла (или что-то, что должно запуститься при перезагрузке сервера), вы должны использовать systemd / systemctl.
ОБНОВЛЕНИЕ: я обновил, чтобы включить последние от pm2:
во многих случаях использование службы systemd является самым простым и наиболее подходящим способом управления процессом узла. для тех, кто выполняет многочисленные процессы узлов или независимо запускает микросервисы узлов в одной среде, pm2 является более полнофункциональным инструментом.
https://github.com/unitech/pm2
- он имеет действительно полезную функцию мониторинга -> симпатичный графический интерфейс для мониторинга нескольких процессов с помощью командной строки
pm2 monit
или список процессов сpm2 list
- организованный журнал управления ->
pm2 logs
- другие вещи:
- Конфигурация поведения
- Поддержка исходной карты
- PaaS совместимый
- Смотреть и Перезагрузить
- Модульная система
- Макс перезагрузка памяти
- Кластерный режим
- Горячая перезагрузка
- Рабочий процесс разработки
- Скрипты запуска
- Авто завершение
- Рабочий процесс развертывания
- Мониторинг ключевых показателей
- API
Попробуйте запустить эту команду, если вы используете nohup -
nohup npm start 2>/dev/null 1>/dev/null&
Вы также можете использовать навсегда, чтобы запустить сервер
forever start -c "npm start" ./
Если вы работаете с OSX, то самый простой способ создать настоящий системный процесс - это использовать launchd
запустить его.
Создайте список, подобный этому, и поместите его в /Library/LaunchDaemons с именем top-level-domain.your-domain.application.plist
(вам нужно быть пользователем root при размещении):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>top-level-domain.your-domain.application</string>
<key>WorkingDirectory</key>
<string>/your/preferred/workingdirectory</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>your-script-file</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Когда закончите, выпустите это (как root):
launchctl load /Library/LaunchDaemons/top-level-domain.your-domain.application.plist
launchctl start top-level-domain.your-domain.application
и ты бежишь.
И вы все равно будете работать после перезагрузки.
Для других вариантов в листе списка просмотрите man-страницу здесь: https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html
Я просто использую модуль демона npm:
var daemon = require('daemon');
daemon.daemonize({
stdout: './log.log'
, stderr: './log.error.log'
}
, './node.pid'
, function (err, pid) {
if (err) {
console.log('Error starting daemon: \n', err);
return process.exit(-1);
}
console.log('Daemonized successfully with pid: ' + pid);
// Your Application Code goes here
});
В последнее время я также использую mon(1) от TJ Holowaychuk для запуска и управления простыми приложениями для узлов.
Я использую Supervisor для разработки. Это просто работает. Когда вы вносите изменения в файл.js, Supervisor автоматически перезапускает ваше приложение с этими загруженными изменениями.
Вот ссылка на его страницу Github
Установить:
sudo npm установить супервизор -g
Вы можете легко заставить его смотреть другие расширения с -e. Другая команда, которую я часто использую, это -i, чтобы игнорировать определенные папки.
Вы можете использовать nohup и supervisor, чтобы приложение вашего узла работало в фоновом режиме даже после выхода из системы.
руководитель sudo nohup myapp.js &
Node.js в качестве фонового сервиса в Windows XP
- Слава Hacksparrow: http://www.hacksparrow.com/install-node-js-and-npm-on-windows.html для учебника по установке Node.js + npm для Windows.
- Престижность идет к Тэтхэму Одди по адресу: http://blog.tatham.oddie.com.au/2011/03/16/node-js-on-windows/ для реализации nnsm.exe.
Монтаж:
- Установите WGET http://gnuwin32.sourceforge.net/packages/wget.htm через исполняемый файл установщика
- Установите GIT http://code.google.com/p/msysgit/downloads/list через исполняемый файл установщика
- Установите NSSM http://nssm.cc/download/?page=download скопировав nnsm.exe в папку%windir%/system32
Создайте c:\node\helloworld.js
// http://howtonode.org/hello-node var http = require('http'); var server = http.createServer(function (request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end("Hello World\n"); }); server.listen(8000); console.log("Server running at http://127.0.0.1:8000/");
Откройте командную консоль и введите следующее (setx, только если установлен Resource Kit)
C:\node> set path=%PATH%;%CD% C:\node> setx path "%PATH%" C:\node> set NODE_PATH="C:\Program Files\nodejs\node_modules" C:\node> git config --system http.sslcainfo /bin/curl-ca-bundle.crt C:\node> git clone --recursive git://github.com/isaacs/npm.git C:\node> cd npm C:\node\npm> node cli.js install npm -gf C:\node> cd .. C:\node> nssm.exe install node-helloworld "C:\Program Files\nodejs\node.exe" c:\node\helloworld.js C:\node> net start node-helloworld
Отличный пакетный вкус - создать c:\node\ServiceMe.cmd
@echo off nssm.exe install node-%~n1 "C:\Program Files\nodejs\node.exe" %~s1 net start node-%~n1 pause
Управление сервисом:
- Сами службы теперь доступны через Пуск-> Выполнить-> services.msc или через Пуск-> Выполнить-> MSCONFIG-> Службы (и отметьте "Скрыть все службы Microsoft").
- Сценарий будет префикс каждого узла, созданного с помощью пакетного сценария, с помощью 'node-'.
- Также их можно найти в реестре: "HKLM \ SYSTEM \ CurrentControlSet \ Services \ node-xxxx"
Принятый ответ, вероятно, является лучшим производственным ответом, но для быстрого взлома, выполняя работу разработчика, я нашел это:
nodejs scriptname.js &
не работал, потому что nodejs, казалось, сожрал &, и поэтому это не позволило мне продолжать использовать терминал без сценария script.js.
Но я поставил nodejs scriptname.js
в файле.sh, иnohup sh startscriptname.sh &
работал.
Определенно не производственная вещь, но она решает проблему "мне нужно продолжать использовать мой терминал и не хочу запускать 5 разных терминалов".
Обновление за июнь 2017 года:
Решение для Linux: (Red Hat). Предыдущие комментарии не работают для меня. Это работает для меня на Amazon Web Service - Red Hat 7. Надеюсь, что это работает для кого-то там.
A. Create the service file
sudo vi /etc/systemd/system/myapp.service
[Unit]
Description=Your app
After=network.target
[Service]
ExecStart=/home/ec2-user/meantodos/start.sh
WorkingDirectory=/home/ec2-user/meantodos/
[Install]
WantedBy=multi-user.target
B. Create a shell file
/home/ec2-root/meantodos/start.sh
#!/bin/sh -
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080
npm start
then:
chmod +rx /home/ec2-root/meantodos/start.sh
(to make this file executable)
C. Execute the Following
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl status myapp
(If there are no errors, execute below. Autorun after server restarted.)
chkconfig myapp -add
Если вы используете nodejs на Linux-сервере, я думаю, что это лучший способ.
Создайте сценарий службы и скопируйте в /etc/init/nodejs.conf
запуск службы: запуск узла sudo servicejs
остановка службы: остановка службы sudo
Сервисный скрипт
description "DManager node.js server - Last Update: 2012-08-06"
author "Pedro Muniz - pedro.muniz@geeklab.com.br"
env USER="nodejs" #you have to create this user
env APPNAME="nodejs" #you can change the service name
env WORKDIR="/home/<project-home-dir>" #set your project home folder here
env COMMAND="/usr/bin/node <server name>" #app.js ?
# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown
# Automatically Respawn:
respawn
respawn limit 99 5
pre-start script
sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$APPNAME.log
end script
script
# Not sure why $HOME is needed, but we found that it is:
export HOME="<project-home-dir>" #set your project home folder here
export NODE_PATH="<project node_path>"
#log file, grant permission to nodejs user
exec start-stop-daemon --start --make-pidfile --pidfile /var/run/$APPNAME.pid --chuid $USER --chdir $WORKDIR --exec $COMMAND >> /var/log/$APPNAME.log 2>&1
end script
post-start script
# Optionally put a script here that will notifiy you node has (re)started
# /root/bin/hoptoad.sh "node.js has started!"
end script
pre-stop script
sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$APPNAME.log
end script
Поскольку мне не хватает этой опции в списке предоставленных ответов, я хотел бы добавить подходящую опцию с 2020 года: докер или любую эквивалентную платформу контейнера. Помимо обеспечения работы вашего приложения в стабильной среде, существуют дополнительные преимущества безопасности, а также улучшенная переносимость.
Существует поддержка докеров для Windows, macOS и большинства / основных дистрибутивов Linux. Установка докера на поддерживаемую платформу довольно проста и хорошо документирована. Настроить приложение Node.js так же просто, как поместить его в контейнер и запустить этот контейнер, убедившись, что он перезапускается после завершения работы.
Создать образ контейнера
Предполагая, что ваше приложение доступно в /home / me / my-app на этом сервере, создайте текстовый файл Dockerfile в папке /home / me / my-app с содержимым, аналогичным этому:
FROM node:lts-alpine
COPY /my-app /app
CMD ["/app/server.js"]
Создайте изображение с помощью такой команды:
docker build -t myapp-as-a-service /home/me
Примечание. Последний параметр - это выбор папки, содержащей этот Dockerfile, вместо самого Dockerfile. Вы можете выбрать другой, используя опцию -f.
Запустить контейнер
Используйте эту команду для запуска контейнера:
docker run -d --restart always -p 80:3000 myapp-as-a-service
Эта команда предполагает, что ваше приложение прослушивает порт 3000, и вы хотите, чтобы оно было доступно на порту 80 вашего хоста.
Конечно, это очень ограниченный пример, но это хорошая отправная точка.
Используйте nssm лучшее решение для windows, просто скачайте nssm, откройте cmd в каталоге nssm и введите
nssm install <service name> <node path> <app.js path>
eg: nssm install myservice "C:\Program Files\nodejs" "C:\myapp\app.js"
при этом будет установлена новая служба Windows, которая будет указана на сайте services.msc, откуда вы можете запускать или останавливать службу, эта служба будет запускаться автоматически, и вы можете настроить ее перезагрузку в случае сбоя.
Чтобы завершить различные предлагаемые варианты, вот еще один: daemon
команда в GNU/Linux, о которой вы можете прочитать здесь: http://libslack.org/daemon/manpages/daemon.1.html. (извинения, если это уже упоминалось в одном из комментариев выше).
Я немного опоздал. Простое решение — выполнить следующие две команды в терминале, как показано ниже.
nohup node ./server.js &
disown -h %1
Затем закройте сеанс ssh, и программа узла продолжит работать. Проверено на Ubuntu 18.
PM2 - это менеджер производственных процессов для приложений Node.js со встроенным балансировщиком нагрузки. Это позволяет вам поддерживать приложения в актуальном состоянии, перезагружать их без простоев и облегчать общие задачи системного администратора. https://github.com/Unitech/pm2
Я использую tmux для среды разработки нескольких окон / панелей на удаленных хостах. Отсоединить и поддерживать процесс в фоновом режиме очень просто. Посмотрите на Tmux
Кто -нибудь заметил тривиальную ошибку позиции "2>&1"?
2>&1 >> file
должно быть
>> file 2>&1
Для людей, использующих более новые версии модуля daemon npm - вам нужно передавать файловые дескрипторы вместо строк:
var fs = require('fs');
var stdoutFd = fs.openSync('output.log', 'a');
var stderrFd = fs.openSync('errors.log', 'a');
require('daemon')({
stdout: stdoutFd,
stderr: stderrFd
});
Проверьте фугу! Помимо запуска многих рабочих, вы также можете демонизировать процесс вашего узла!
Если вы используете pm2, вы можете использовать его с autorestart
установлен в false
:
Экосистема $ pm2
Это сгенерирует образец ecosystem.config.js
:
module.exports = {
apps: [
{
script: './scripts/companies.js',
autorestart: false,
},
{
script: './scripts/domains.js',
autorestart: false,
},
{
script: './scripts/technologies.js',
autorestart: false,
},
],
}
$ pm2 запустить экосистему.config.js
Я удивлен, что никто не упомянул Гувнора
Я пробовал навсегда, pm2 и т. Д. Но, когда речь заходит о надежном контроле и показателях производительности в сети, я обнаружил, что Guvnor безусловно лучший. Плюс, это также полностью с открытым исходным кодом.
Редактировать: Тем не менее, я не уверен, работает ли он на окнах. Я использовал это только на Linux.
Я получил следующую ошибку при использовании принятого ответа mikemaccana на экземпляре RHEL 8 AWS EC2:
(code=exited, status=216/GROUP)
Это произошло из-за использования пользователя / группы, установленного на: «никто».
При поиске в Google кажется, что использование пользователя / группы как «никто» / «nogroup» является плохой практикой для демонов, как указано здесь на обмене стеками unix.
Он отлично работал после того, как я установил пользователя / группу для моего фактического пользователя и группы.
Вы можете войти
whomai
и
groups
чтобы увидеть доступные варианты, чтобы исправить это.
Мой служебный файл для приложения с полным стеком node с mongodb:
[Unit]
Description=myapp
After=mongod.service
[Service]
ExecStart=/home/myusername/apps/myapp/root/build/server/index.js
Restart=always
RestartSec=30
User=myusername
Group=myusername
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/home/myusername/apps/myapp
[Install]
WantedBy=multi-user.target
Вы можете запустить приложение узла в фоновом режиме с помощью&
в юниксе. Убедитесь, что в вашем приложении узла не должно быть интерактивного режима, например получения данных из ввода.
node src/index.js -p 1234 --another-options &
В случае, если для целей локальной разработки вам необходимо запустить несколько экземпляров приложения NodeJS (экспресс, fastify и т. д.), тогдаconcurrently
может быть вариант. Вот настройка:
Предпосылки
- Ваше приложение NodeJS (экспресс, fastify и т. д.) размещено по адресу
/opt/mca/www/mca-backend/app
путь. - Предполагая, что вы используете узел v.16, установленный через
brew install node@16
Настраивать
Установить одновременно:
npm install -g concurrently
Создать файл
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>mca.backend</string> <key>LimitLoadToSessionType</key> <array> <string>Aqua</string> <string>Background</string> <string>LoginWindow</string> <string>StandardIO</string> <string>System</string> </array> <key>ProgramArguments</key> <array> <string>/usr/local/bin/concurrently</string> <string>--names</string> <string>dev,prd</string> <string>--success</string> <string>all</string> <string>--kill-others</string> <string>--no-color</string> <string>MCA_APP_STAGE=dev node ./server.mjs</string> <string>MCA_APP_STAGE=prod node ./server.mjs</string> </array> <key>RunAtLoad</key> <true/> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/usr/local/opt/node@16/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string> </dict> <key>WorkingDirectory</key> <string>/opt/mca/www/mca-backend/app</string> <key>StandardErrorPath</key> <string>/opt/mca/www/mca-backend/err.log</string> <key>StandardOutPath</key> <string>/opt/mca/www/mca-backend/out.log</string> </dict> </plist>
Загрузите и запустите:
launchctl bootstrap gui/`id -u` $HOME/Library/LaunchAgents/mca.backend.plist
Получить статус:
launchctl print gui/`id -u`/mca.backend
Останавливаться:
launchctl kill SIGTERM gui/`id -u`/mca.backend
Старт/Перезапуск:
launchctl kickstart -k -p gui/`id -u`/mca.backend
Выгрузить, если больше не нужно:
launchctl bootout gui/`id -u`/mca.backend
ВАЖНО : После того, как вы загрузите службу с любыми изменениями, внесенными в файл~/Library/LaunchAgents/mca.backend.plist
не будет работать, пока вы не выгрузите службу (используяlaunchctl bootout
), а затем загрузите его снова (используяlaunchctl bootstrap
).
Поиск неисправностей
Смотрите журналы запуска по адресу:/private/var/log/com.apple.xpc.launchd/launchd.log