Jak uruchomić Node.js jako proces w tle i nigdy nie umrzeć?

480

Łączę się z serwerem linux za pośrednictwem szpachli SSH. Próbowałem uruchomić go jako proces w tle, taki jak ten:

$ node server.js &

Jednak po 2,5 godziny terminal staje się nieaktywny i proces umiera. Czy w ogóle mogę utrzymać proces przy życiu nawet przy odłączonym terminalu?


Edytuj 1

Właściwie to próbowałem nohup, ale jak tylko zamknę terminal Putty SSH lub odłączę internet, proces serwera natychmiast się kończy.

Czy jest coś, co muszę zrobić w Putty?


Edytuj 2 (lutego 2012 r.)

Jest node.jsmoduł na zawsze . Będzie działał serwer node.js jako usługa demona.

murvinlai
źródło
7
W moim przypadku nohup działa, gdy wychodzę z terminalu, pisząc exit. Kiedy tylko zamykam okno Putty, to się nie udaje.
Paweł Furmaniak

Odpowiedzi:

513

Proste rozwiązanie (jeśli nie chcesz wracać do procesu, po prostu chcesz, aby nadal działał):

nohup node server.js &

Istnieje również jobspolecenie, aby wyświetlić indeksowaną listę procesów w tle. Możesz zabić proces działający w tle, uruchamiając go kill %1lub kill %2używając numeru będącego indeksem procesu.

Potężne rozwiązanie (pozwala ponownie połączyć się z procesem, jeśli jest interaktywny):

screen

Następnie możesz odłączyć, naciskając Ctrl + a + d, a następnie podłączyć ponownie, uruchamiając screen -r

Weź również pod uwagę nowszą alternatywę dla screena, tmux.

MK.
źródło
1
Więc jeśli uruchomię „screen”, utworzę ekran i uruchomię go, prawda?
murvinlai
30
tak, a następnie można odłączyć naciskając kombinację klawiszy Ctrl + a, d, a następnie podłączyć ponownie, uruchamiając ekran -r
MK.
1
@murvinlai EC2 jest środowiskiem i nie ma nic wspólnego z uprawnieniami roota. Prawdopodobnie chodzi o twój AMI. Na przykład z Amazon AMI na pewno możesz sudo bash.
ShuaiYuan
1
man bash: Jeśli polecenie zostanie zakończone przez operatora sterującego &, powłoka wykonuje polecenie w tle w podpowłoce. Powłoka nie czeka na zakończenie polecenia, a zwracany status to 0.
MK.
34
Wszystkim, którzy to czytają: uruchamianie serwera node.js na ekranie lub sesji tmux jest rozwiązaniem AMATORSKIM ! Nie rób tego, chyba że do szybkich testów. Aby proces działał, musisz go zdemonizować ! Używaj odpowiednich narzędzi do tego, jak na zawsze , PM2 lub zwykły starych skryptów init.d .
Victor Schröder,
1119

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

  1. nohupoznacza: Nie przerywaj tego procesu, nawet jeśli stty jest odcięty.
  2. > /dev/nulloznacza: stdout przechodzi do / dev / null (które jest urządzeniem pozornym, które nie rejestruje żadnych danych wyjściowych).
  3. 2>&1oznacza: stderr również przechodzi do standardowego wyjścia (do którego już przekierowano /dev/null). Możesz zastąpić & 1 ścieżką pliku, aby zachować dziennik błędów, np .:2>/tmp/myLog
  4. &na końcu oznacza: uruchom to polecenie jako zadanie w tle.
Yoichi
źródło
49
To powinna być zaakceptowana odpowiedź, ponieważ ma znacznie wyższą jakość niż obecnie akceptowana.
L0j1k
2
@ L0j1k dyskusyjny, OP wykazał poziom zrozumienia, że ​​do zaakceptowanej odpowiedzi potrzebne są dalsze wyjaśnienia.
JFA
41
SO nie dotyczy OP, ale tysięcy ludzi przychodzących na pytanie OP o pomoc.
L0j1k
3
Czy konieczne jest przekierowanie stdout i stderr? Czy działałoby to równie dobrze, gdybym ich w ogóle nie przekierowywał? A jeśli zamiast tego przekierowałem je do plików?
Shawn
10
Czy wysłać stdout AND stderr na /dev/null? Ładne logowanie ... Powodzenia w próbach debugowania tego ...
Victor Schröder
138

Naprawdę powinieneś spróbować użyć screen. Jest to nieco bardziej skomplikowane niż samo robienie nohup long_running &, ale zrozumienie ekranu, gdy już nigdy nie wrócisz.

Najpierw rozpocznij sesję ekranową:

user@host:~$ screen

Uruchom cokolwiek chcesz:

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

Naciśnij ctrl + A, a następnie d. Gotowy. Sesja trwa w tle.

Możesz wyświetlić listę wszystkich sesji screen -lsi dołączyć do niektórych za pomocą screen -r 20673.pts-0.srvpolecenia, gdzie 0673.pts-0.srv jest listą wpisów.

Alex Povar
źródło
125

To stare pytanie, ale ma wysoką pozycję w Google. Prawie nie mogę uwierzyć w najwyżej głosowane odpowiedzi, ponieważ uruchomienie procesu node.js w sesji ekranowej, z flagą &lub nawet z nohupflagą - wszystkie - są tylko obejściami.

Zwłaszcza rozwiązanie screen / tmux, które naprawdę powinno być uważane za rozwiązanie amatorskie . Screen i Tmux nie są przeznaczone do utrzymywania procesów w działaniu, ale do multipleksowania sesji terminalowych. W porządku, gdy uruchamiasz skrypt na serwerze i chcesz się rozłączyć. Ale w przypadku serwera node.js nie chcesz, aby proces był dołączany do sesji terminala. To jest zbyt delikatne. Aby wszystko działało, musisz demonizować ten proces!

Istnieje wiele dobrych narzędzi do tego.

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

Jedną dużą zaletą, którą widzę na korzyść PM2, jest to, że może on wygenerować skrypt uruchamiania systemu, aby proces trwał między ponownymi uruchomieniami:

$ pm2 startup [platform]

Gdzie platformmoże być 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

Skrypty inicjujące :

Nie wchodzę w szczegółowe informacje na temat pisania skryptu inicjującego, ponieważ nie jestem ekspertem w tym temacie i odpowiedź byłaby zbyt długa, ale w zasadzie są to proste skrypty powłoki uruchamiane przez zdarzenia systemu operacyjnego. Możesz przeczytać więcej na ten temat tutaj

Doker :

Po prostu uruchom swój serwer w kontenerze Docker z -dopcją i, voilá , masz demonizowany serwer node.js!

Oto przykładowy plik Docker (z oficjalnego przewodnika 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" ]

Następnie zbuduj obraz i uruchom kontener:

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

Mam nadzieję, że to pomoże komuś lądować na tej stronie. Zawsze używaj odpowiedniego narzędzia do pracy. Zaoszczędzi Ci wiele bólów głowy i ponad godziny!

Victor Schröder
źródło
2
Właśnie tego szukałem. Czy w przypadku rozwiązania pm2 można później podłączyć terminal?
Quantumplation,
4
@Quantumplation, no. Nie jest to możliwe, ponieważ proces nie działa w sesji interaktywnej. Ale możesz mieć to samo „odczucie”, tail -fumieszczając plik dziennika, który generuje pm2.
Victor Schröder
1
Ty określasz screenrozwiązanie, które znajduje wiele osób, a praca jest obejściem problemu. Istnieje wiele sposobów osiągnięcia określonego zadania. Wierzę, że zdarza się, że (rozważ konkretne pytanie) zdarza się, że osiąga się szczególne zadanie run as background and never diedoskonałości dla wielu. Ma również dodatkową zaletę polegającą na umożliwieniu użytkownikowi powrotu do niego w celu ponownej interakcji i wprowadzania zmian, jeśli chce. Kluczem jest to, że komponenty to backgroundi never die. Wszystkie rozwiązania mają pewne bonusy.
LD James
@Rakshith Ravi - Nie zgadzam się. Wszystkie wymagają dodatkowych plików do pobrania / oprogramowania / narzędzi (z wyjątkiem rozwiązania init, któremu nie podano żadnego rozwiązania). To nohup jest rozwiązanie. Jest wbudowany w Linuksa i właśnie po to. To jedna linia, jest czysta i działa zgodnie z przeznaczeniem, za każdym razem, niezależnie od aktualizacji. Ludzie powinni naprawdę unikać używania narzędzi innych firm do takich podstawowych zastosowań. Przykład dokera (na przykład) jest bardziej szczegółowy i wymaga dużo zasobów niż jedno proste polecenie w najczęściej głosowanej odpowiedzi. Uwielbiam Dockera, ale nie za to.
Jack_Hu
1
@Jack_Hu, nie mam wątpliwości co do kosztów ogólnych, ale nohuprozwiązanie nie spełnia wymogu „nigdy nie umieraj”. O ile nie napiszesz bardzo trudnej traplub zhackowanej nieskończonej pętli, nie widzę, jak utrzymać demonizację procesu bez użycia specjalnie napisanych do tego celu narzędzi (lub oczywiście skryptu inicjującego napisanego przez ciebie).
Victor Schröder
24

inne rozwiązanie odrzuca pracę

$ nohup node server.js &
[1] 1711
$ disown -h %1
myururdurmaz
źródło
disown jest dokładnie tym, czego szukałem, ale co robi flaga -h? Nie mogę go znaleźć w instrukcji
Rimantas Jacikevicius
ze strony podręcznika man: Jeśli podano opcję -h, każdy specyfikacja zadania nie jest usuwana z tabeli, ale jest oznaczana w taki sposób, że SIGHUP nie jest wysyłany do zadania, jeśli powłoka otrzyma SIGHUP. Jeśli nie podano specyfikacji zadania, opcja -a oznacza usunięcie lub zaznaczenie wszystkich zadań;
myururdurmaz
14

nohuppozwoli kontynuować program nawet po śmierci terminala. Rzeczywiście miałem sytuacje, w których nohupuniemożliwia prawidłowe zakończenie sesji SSH, więc powinieneś również przekierować dane wejściowe:

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

W zależności od nohupkonfiguracji może być konieczne przekierowanie standardowego wyjścia i standardowego błędu do plików.

Daniel Gallagher
źródło
7

Mam tę funkcję w moim pliku rc powłoki, w oparciu o odpowiedź @ Yoichi:

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

Możesz użyć tego w ten sposób:

nohup-template "command you would execute here"
thiagowfx
źródło
7

Nohup i screen oferują świetne, lekkie rozwiązania do uruchamiania Node.js w tle. Menedżer procesów Node.js ( PM2 ) to przydatne narzędzie do wdrażania. Zainstaluj go z npm globalnie w swoim systemie:

npm install pm2 -g

aby uruchomić aplikację Node.js jako demon:

pm2 start app.js

Opcjonalnie możesz połączyć go z Keymetrics.io SAAS monitorującym wykonanym przez Unitech.

Donald Derek
źródło
6
$ disown node server.js &

Usunie polecenie z listy aktywnych zadań i wyśle ​​polecenie w tło

Skynet
źródło
5

Czy czytałeś o poleceniu nohup ?

S.Lott
źródło
3

Aby uruchomić komendę jako usługę systemową na debianie z sysv init:

Skopiuj szkielet skryptu i dostosuj go do swoich potrzeb, prawdopodobnie wszystko, co musisz zrobić, to ustawić niektóre zmienne. Twój skrypt odziedziczy dokładne ustawienia domyślne /lib/init/init-d-script, jeśli coś nie pasuje do twoich potrzeb - zastąp to w swoim skrypcie. Jeśli coś pójdzie nie tak, możesz zobaczyć szczegóły w źródle /lib/init/init-d-script. Obowiązkowe są DAEMONi NAME. Skrypt użyje start-stop-daemondo uruchomienia twojego polecenia, w START_ARGSktórym możesz zdefiniować dodatkowe parametry start-stop-daemondo użycia.

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

W ten sposób uruchamiam niektóre rzeczy w języku Python na mojej wiki 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
}

Oprócz ustawiania zmiennych musiałem przesłonić, do_stop_cmdponieważ Python zastępuje plik wykonywalny, więc usługa nie zatrzymała się poprawnie.

użytkownik3132194
źródło
3

Oprócz wyżej wymienionych fajnych rozwiązań wspomnę także o narzędziach nadzorczych i monitorujących, które pozwalają na rozpoczęcie procesu, monitorowanie jego obecności i uruchomienie w przypadku śmierci. Za pomocą „monit” możesz także uruchomić niektóre aktywne kontrole, takie jak sprawdzenie, czy proces odpowiada na żądanie http

Krzysztof Księżyk
źródło
3

W przypadku Ubuntu używam tego:

(exec PROG_SH &> / dev / null &)

pozdrowienia

David Lopes
źródło
Drobny punkt: „exec” nie jest potrzebne, jeśli PROG_SH jest plikiem wykonywalnym. Rozwiązaniem zaproponowanym przez Davida jest oddzielenie dziecka od bieżącej działającej powłoki. Rodzic dziecka staje się „pid 1” i nie będzie to miało wpływu na zakończenie powłoki.
SoloPilot,
0

Wypróbuj to, aby uzyskać proste rozwiązanie

cmd i wyjdź

Łowca Frazier
źródło