Як запустити Node.js як фоновий процес і ніколи не вмирати?


480

Я підключаюся до сервера linux через putty SSH. Я спробував запустити його як фоновий процес, такий:

$ node server.js &

Однак через 2,5 години термінал стає неактивним і процес вмирає. Чи все-таки я можу підтримувати процес живим навіть при відключенні терміналу?


Редагуйте 1

Насправді я намагався nohup, але як тільки я закриваю термінал Putty SSH або відключаю мережу Інтернет, процес сервера відразу зупиняється.

Чи є щось, що я маю зробити в Putty?


Редагувати 2 (лютого 2012 р.)

Є node.jsмодуль, назавжди . Він запустить сервер node.js як служба демон.


7
У моєму випадку nohup працює, коли я виходжу з терміналу, набравши текст exit. Коли я просто закриваю вікно Putty, воно виходить з ладу.
Pawel Furmaniak

Відповіді:


513

Просте рішення (якщо вам не цікаво повертатися до процесу, просто хочете, щоб він продовжував працювати):

nohup node server.js &

Також є jobsкоманда переглянути індексований список цих фонових процесів. І ви можете вбити фоновий процес, запустивши kill %1або kill %2з числом, що є індексом процесу.

Потужне рішення (дозволяє підключитися до процесу, якщо він є інтерактивним):

screen

Потім можна від'єднатись, натиснувши Ctrl + a + d, а потім приєднати назад, запустивши screen -r

Також розглянемо нову альтернативу екрану, tmux.


1
Отже, якщо я запускаю "екран", я створюю екран і запускаю всередину нього, правда?
murvinlai

30
так, і тоді ви можете від'єднатись, натиснувши Ctrl + a, d, а потім приєднати назад, виконавши екран -r
MK.

1
@murvinlai EC2 - це середовище і не має нічого спільного з привілеєм root. Ймовірно, це про ваш AMI. Наприклад, з Amazon AMI ви точно можете sudo bash.
ShuaiYuan

1
man bash: Якщо команду припиняє оператор управління &, оболонка виконує команду у фоновому режимі в нижній частині. Оболонка не чекає, коли команда закінчиться, і стан повернення дорівнює 0.
МК.

34
Будь ласка, нікому читати це: запуск Node.js сервера всередині екрану або tmux сесії є любителі рішенням! Не робіть цього, хіба що для швидких тестів. Щоб утримати процес, потрібно його демонізувати ! Використовуйте належні інструменти для нього, як і назавжди , PM2 або рівнинних старих скриптів init.d .
Віктор Шредер

1119

nohup node server.js > /dev/null 2>&1 &

  1. nohupозначає: Не припиняйте цей процес навіть тоді, коли стрить відрізано.
  2. > /dev/nullозначає: stdout переходить до / dev / null (це фіктивний пристрій, який не записує жодного виводу).
  3. 2>&1означає: stderr також переходить до stdout (на який вже переспрямовано /dev/null). Ви можете замінити & 1 на шлях до файлу, щоб вести журнал помилок, наприклад:2>/tmp/myLog
  4. &в кінці означає: виконати цю команду як фонове завдання.

49
Це має бути прийнятою відповіддю, оскільки вона набагато вищої якості, ніж прийнята зараз.
L0j1k

2
@ L0j1k дискусійний, ОП продемонстрував рівень розуміння того, що для прийнятої відповіді потрібне подальше пояснення.
JFA

41
Тож не про ОП стільки, скільки про тисячі людей, які звертаються з питанням ОП про допомогу.
L0j1k

3
Чи потрібно перенаправляти stdout і stderr? Це спрацювало б так само добре, якби я їх взагалі не перенаправляв? Або якщо я переспрямував їх на файли?
Шон

10
Надіслати stdout AND stderr до /dev/null? Приємного ведення журналу ... Удачі, намагаючись налагодити це ...
Віктор Шредер

138

Ви дійсно повинні спробувати використовувати screen. Це трохи складніше, ніж просто робити nohup long_running &, але зрозуміти екран, коли ти більше ніколи не повернешся.

Почніть свій екранний сеанс спочатку:

user@host:~$ screen

Виконайте все, що завгодно:

wget http://mirror.yandex.ru/centos/4.6/isos/i386/CentOS-4.6-i386-binDVD.iso

Натисніть ctrl + A, а потім d. Зроблено. Ваше сеанс продовжується у фоновому режимі.

Ви можете перелічити всі сеанси за допомогою screen -lsта долучити їх до screen -r 20673.pts-0.srvкоманди за командою, де 0673.pts-0.srv - список записів.


125

Це давнє запитання, але воно займає високі позиції в Google. Я майже не можу повірити у найвищі відповіді, оскільки запускається процес node.js всередині екранного сеансу, з &або навіть ізnohup прапором прапором - усі вони - лише обхідні шляхи.

Особливо рішення screen / tmux, яке справді слід вважати аматорським рішенням. Екран та Tmux призначені не для того, щоб тримати процеси, а для сеансів мультиплексування терміналів. Це добре, коли ви запускаєте скрипт на своєму сервері і хочете відключитися. Але для сервера node.js не хочеться, щоб ваш процес був приєднаний до термінального сеансу. Це занадто крихко. Щоб продовжувати роботу, вам потрібно демонізувати процес!

Для цього є маса хороших інструментів.

PM2 : http://pm2.keymetrics.io/

# basic usage
$ npm install pm2 -g
$ pm2 start server.js

# you can even define how many processes you want in cluster mode:
$ pm2 start server.js -i 4

# you can start various processes, with complex startup settings
# using an ecosystem.json file (with env variables, custom args, etc):
$ pm2 start ecosystem.json

Однією з великих переваг, яку я бачу на користь PM2, є те, що він може генерувати сценарій запуску системи, щоб процес зберігався між перезавантаженнями:

$ pm2 startup [platform]

Де platformможна бути ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

forever.js : https://github.com/foreverjs/forever

# basic usage
$ npm install forever -g
$ forever start app.js

# you can run from a json configuration as well, for
# more complex environments or multi-apps
$ forever start development.json

Сценарії Init :

Я не буду заглиблюватися в деталі про те, як написати сценарій init, тому що я не знавець у цій темі, і для цього відповідь було б занадто довго, але в основному це прості сценарії оболонки, викликані подіями ОС. Більше про це можна прочитати тут

Докер :

Просто запустіть ваш сервер у контейнері Docker з -dопцією і, voilá , у вас є демонізований сервер node.js!

Ось зразок Dockerfile (з офіційного керівництва node.js ):

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

Потім складіть своє зображення та запустіть контейнер:

$ docker build -t <your username>/node-web-app .
$ docker run -p 49160:8080 -d <your username>/node-web-app

Сподіваюсь, це допоможе комусь, хто перейшов на цю сторінку. Завжди використовуйте належний інструмент для роботи. Це позбавить вас від багатьох головних болів і годин!


2
Це те, що я шукав. Чи можна за допомогою рішення pm2, як пізніше приєднати до нього термінал?
Квантова пластика

4
@Quantumplation, ні. Це неможливо, оскільки процес не працює в інтерактивному сеансі. Але ви можете мати те саме "відчуття", tail -fвикористовуючи файл журналу, який створює pm2.
Віктор Шредер

1
Ви вказуєте screenрішення, яке багато людей знаходять, чи відповідає це завдання - це вирішення. Існує маса способів досягнення конкретного завдання. Я вважаю, що трапляється так, що (врахуйте конкретне питання) run as background and never dieдля багатьох це стає досягненням конкретного завдання . Він також має додатковий бонус за те, що дозволяє користувачеві повернутися до нього, щоб повторно взаємодіяти та вносити зміни, якщо він захоче. Ключовим фактором є backgroundі never die. Всі рішення мають певні бонуси.
Л. Д. Джеймс

@Rakshith Ravi - я не згоден. Всі вони потребують додаткових завантажень / програмного забезпечення / інструментів (крім рішення init, до якого не було дано рішення). nohup Це рішення. Він призначений для Linux, і для чого він потрібен. Це один рядок, він чистий, і він працює за призначенням, щоразу, незалежно від оновлень. Люди дійсно повинні намагатися уникати використання сторонніх інструментів для випадків базового використання, таких як цей. Приклад докера (наприклад) набагато більш багатослівний та ресурсомісткий, ніж одна проста команда у верхній частині голосової відповіді. Любіть Докер, але не заради цього.
Jack_Hu

1
@Jack_Hu, я не сумніваюся в накладних витратах, але nohupрішення не задовольняє вимозі "ніколи не вмирай". Якщо ви не trapнапишете дуже хитруватий чи химерний нескінченний цикл, я не бачу, як зберегти процес демонізованим без використання інструментів, спеціально написаних для цієї мети (чи, звичайно, написаного власноруч сценарію init).
Віктор Шредер

24

інше рішення відмовиться від роботи

$ nohup node server.js &
[1] 1711
$ disown -h %1

disown - це саме те, що я шукав, але що робить -h прапор? Я не можу знайти його в посібнику
Rimantas Jacikevicius

зі сторінки man: Якщо задано параметр -h, кожен специфікатор завдань не видаляється з таблиці, але позначається так, що SIGHUP не надсилається до завдання, якщо оболонка отримує SIGHUP. Якщо не вказано жодних робочих місць, опція -a означає видалити або позначити всі завдання;
myururdurmaz

14

nohupдозволить програмі продовжуватися навіть після вмирання терміналу. Насправді у мене були ситуації, коли nohupперешкоджає правильному завершенню сеансу SSH, тому вам слід також перенаправити введення даних:

$ nohup node server.js </dev/null &

Залежно від того, як nohupналаштовано, вам також може знадобитися перенаправити стандартний вихід і стандартну помилку на файли.


7

Я маю цю функцію в моєму файлі rc оболонки на основі відповіді @ Yoichi:

nohup-template () {
    [[ "$1" = "" ]] && echo "Example usage:\nnohup-template urxvtd" && return 0
    nohup "$1" > /dev/null 2>&1 &
}

Ви можете використовувати його таким чином:

nohup-template "command you would execute here"

7

Nohup і екран пропонують чудові легкі рішення для запуску Node.js у фоновому режимі. Менеджер процесів Node.js ( PM2 ) - це зручний інструмент для розгортання. Встановіть його з npm глобально у вашій системі:

npm install pm2 -g

запустити додаток Node.js як демон:

pm2 start app.js

Ви можете додатково пов’язати його з Keymetrics.io моніторинговим SAAS, зробленим Unitech.


6
$ disown node server.js &

Вона видалить команду зі списку активних завдань і надішле команду на задній план



3

Щоб запустити команду як системну службу на debian з sysv init:

Скопіюйте сценарій скелета і адаптуйте його під свої потреби, мабуть, все, що вам потрібно зробити, це встановити деякі змінні. Ваш сценарій успадкує тонкі за замовчуванням /lib/init/init-d-script, якщо щось не відповідає вашим потребам - замініть його у вашому сценарії. Якщо щось піде не так, ви можете побачити деталі у джерелі /lib/init/init-d-script. Обов’язкові вари є DAEMONі NAME. Сценарій буде використовуватися start-stop-daemonдля запуску вашої команди, у START_ARGSвас можна визначити додаткові параметри start-stop-daemonвикористання.

cp /etc/init.d/skeleton /etc/init.d/myservice
chmod +x /etc/init.d/myservice
nano /etc/init.d/myservice

/etc/init.d/myservice start
/etc/init.d/myservice stop

Ось як я запускаю деякі матеріали python для своєї wikiedia wiki:

...
DESC="mediawiki articles converter"
DAEMON='/home/mss/pp/bin/nslave'
DAEMON_ARGS='--cachedir /home/mss/cache/'
NAME='nslave'
PIDFILE='/var/run/nslave.pid'
START_ARGS='--background --make-pidfile --remove-pidfile --chuid mss --chdir /home/mss/pp/bin'

export PATH="/home/mss/pp/bin:$PATH"

do_stop_cmd() {
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
        $STOP_ARGS \
        ${PIDFILE:+--pidfile ${PIDFILE}} --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    rm -f $PIDFILE
    return $RETVAL
}

Окрім встановлення vars, мені довелося переосмислити do_stop_cmdчерез заміщення пітону виконуваним файлом, тому сервіс не зупинився належним чином.


3

Окрім крутих рішень вище, я згадаю також про інструменти нагляду та контролю, які дозволяють запустити процес, стежити за його наявністю та запускати його, якщо він загинув. За допомогою 'monit' ви також можете запустити деякі активні перевірки, наприклад перевірити, чи відповідає процес на http-запит


3

Для Ubuntu я використовую це:

(exec PROG_SH &> / dev / null &)

з повагою


Незначна точка: "exec" не потрібен, якщо PROG_SH є виконуваним файлом. Суть рішення, запропонованого Девідом, полягає у відстороненні дитини від поточної оболонки. Батько дитини стає "під-1" і на нього не впливатиме, коли оболонка припиниться.
SoloPilot

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.