Secara otomatis memulai selamanya (node) pada restart sistem

190

Saya menggunakan modul selamanya node untuk menjaga server node saya berjalan. Namun selamanya berakhir ketika ada restart sistem. Apakah ada cara saya dapat secara otomatis memulai node server (dengan selamanya) ketika sistem restart?

kehers
sumber
1
Apakah server ini ada di cloud? Apakah Anda memiliki skrip boot untuk itu?
Jorge Aranda
6
Periksa PM2 ! Ini juga mendukung pembuatan skrip startup (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech

Jawaban:

341

Saya sarankan menggunakan crontab. Mudah digunakan.

Bagaimana caranya

  1. Untuk mulai mengedit, jalankan yang berikut menggantikan "testuser" dengan pengguna runtime yang Anda inginkan untuk proses simpul. Jika Anda memilih pengguna lain selain diri Anda sendiri, Anda harus menjalankan ini dengan sudo.

    $ crontab -u testuser -e
  2. Jika Anda belum pernah melakukan ini sebelumnya, ia akan menanyakan editor mana yang ingin Anda sunting. Saya suka vim, tetapi akan merekomendasikan nano untuk kemudahan penggunaan.

  3. Setelah di editor tambahkan baris berikut:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Simpan file. Anda harus mendapatkan umpan balik bahwa cron telah diinstal.

  5. Untuk konfirmasi lebih lanjut tentang pemasangan cron, jalankan yang berikut (lagi-lagi ganti "testuser" dengan nama pengguna target Anda) untuk mendaftar crons yang saat ini diinstal:

    $ crontab -u testuser -l 

Perhatikan bahwa menurut pendapat saya, Anda harus selalu menggunakan path lengkap saat menjalankan binari di cron. Juga, jika jalur ke skrip selamanya Anda tidak benar, jalankan which foreveruntuk mendapatkan path lengkap.

Mengingat foreverpanggilan itu node, Anda mungkin juga ingin memberikan jalur lengkap ke node:

@reboot /usr/local/bin/forever start -c /usr/local/bin/node /your/path/to/your/app.js

Bacaan lebih lanjut

Julian Lannigan
sumber
2
Pendekatan ini baik, tetapi hanya untuk kasus-kasus ketika sistem reboot. Jika server dimatikan dan dihidupkan - tugas cron ini tidak akan dijalankan.
ecdeveloper
6
Apa yang membuatmu berpikir demikian? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Menjelaskan bahwa @rebootcron dijalankan pada cron deamon dimulai. Untuk menambahkan, saya belum pernah menemukan situasi yang menunjukkan bahwa cron saya yang diset pada @reboottidak berjalan pada boot sistem. Cara Anda mematikannya tidak relevan untuk ini.
Julian Lannigan
16
tampaknya /homebelum dipasang, jadi ini tidak akan berfungsi jika kode Anda tinggal /home.
chovy
6
Saya menemukan bahwa di atas gagal bagi saya karena simpul tidak ada di jalur ketika cron mencoba untuk menjalankan selamanya, bahkan dengan opsi -c. Namun, ternyata Anda dapat menambahkan pernyataan PATH = langsung di crontab selama itu di atas pernyataan jadwal. Setelah PATH diatur, pernyataan @reboot berfungsi seperti mimpi.
YorkshireKev
2
Terima kasih atas komentar Anda @chovy, itu sangat membantu. Bagi mereka yang menggunakan variabel lingkungan dari bashrc, ingat komentarnya. Karena / home tidak di-mount, itu tidak akan berfungsi. Atur variabel pada perintah crontab seperti@reboot varname=value ...
lsborg
123

Anda dapat menggunakan layanan selamanya untuk melakukan ini.

npm install -g forever-service
forever-service install test

Ini akan menyediakan app.js di direktori saat ini sebagai layanan melalui selamanya. Layanan akan secara otomatis restart setiap kali sistem dihidupkan ulang. Juga ketika berhenti itu akan mencoba berhenti anggun. Skrip ini juga menyediakan skrip logrotate.

Github url: https://github.com/zapty/forever-service

CATATAN: Saya adalah penulis layanan selamanya.

arva
sumber
2
Gunakan opsi -e "PORT = 80 ENV = prod FOO = bar"
arva
2
Saya tidak mendapatkan cara menjalankan layanan selamanya. Apa itu "tes" dalam "uji instalasi layanan selamanya"? Perintah saya untuk memulai aplikasi saya selamanya adalah: "/ usr / local / bin / selamanya mulai -c / usr / local / bin / node / home / alex / publik / node_modules / http-server / bin / http-server -s - d false ". Apa yang harus saya tulis?
Alex
3
Tes di sini adalah nama layanan. ketika Anda menjalankan tes instalasi layanan selamanya itu menciptakan layanan yang disebut tes, untuk menjalankan app.js dalam direktori itu untuk dijalankan sebagai layanan. Saya sarankan membaca dokumentasi bantuan pada halaman gihub, dan menambahkan masalah di sana jika Anda tidak dapat memahaminya.
arva
6
@Alex - untuk mengklarifikasi komentar arva - dalam contoh forever-service install test, testakan menjadi nama layanan , tetapi bukan nama program / node .js file yang sebenarnya untuk dijalankan. Secara default, mengasumsikan nama dari program ini adalah app.js, tetapi Anda dapat menimpanya dengan --scriptbendera, sebagai berikut: forever-service install test --script main.js. (Belum diuji, jadi tolong perbaiki saya jika ada detail sintaks yang salah.)
Dan Nissenbaum
3
@DanNissenbaum Terima kasih telah menjawab. Saya sekarang menggunakan PM2 yang bekerja dengan indah. Instruksi: digitalocean.com/community/tutorials/…
Alex
26

Kasing ini berlaku untuk Debian.

Tambahkan yang berikut ke /etc/rc.local

/usr/bin/sudo -u {{user}} /usr/local/bin/forever start {{app path}}

  • {{user}} mengganti nama pengguna Anda.
  • {{app path}}mengganti jalur aplikasi Anda. Sebagai contoh,/var/www/test/app.js
NiLL
sumber
2
Metode ini tidak berurusan dengan shutdown yang anggun, meskipun bagi banyak orang ini mungkin bukan masalah.
UpTheCreek
6
BTW - Saya pikir Anda harus mengedit /etc/rc.local, bukan/etc/init.d/rc.local
UpTheCreek
Setuju dengan @UpTheCreek bahwa /etc/rc.local adalah tempat yang lebih tepat untuk menambahkan ini - lihat: unix.stackexchange.com/a/59945 untuk penjelasan yang bagus.
So Over It
2
Juga, Anda mungkin ingin menentukan 'direktori kerja saat ini' di app.jsuntuk memastikan file relatif dimuat dengan benar - process.chdir('/your/path/to/your/app'); Node.js ref docs di sini
So Over It
1
Jika Anda perlu mengatur variabel lingkungan untuk skrip Node.JS Anda (seperti $ PORT untuk mengekspresikan), menambahkan baris berikut untuk /etc/rc.localmelakukan trik untuk saya:( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )
sffc
25
  1. Instal PM2 secara global menggunakan NPM

    npm install pm2 -g

  2. Mulai skrip Anda dengan pm2

    pm2 start app.js

  3. buat skrip startup aktif

    pm2 startup

    CATATAN: startup pm2 adalah untuk memulai PM2 ketika sistem reboot. PM2 sekali dimulai, restart semua proses yang telah dikelola sebelum sistem turun.

Jika Anda ingin menonaktifkan startup otomatis, cukup gunakan pm2 unstartup

Jika Anda ingin skrip startup dijalankan di bawah pengguna lain, cukup gunakan -u <username>opsi dan--hp <user_home>:

fsamuel
sumber
Tolong jangan posting jawaban yang sama untuk beberapa pertanyaan.
FelixSFD
Saya sangat suka bagaimana PM2 disempurnakan, dan dilengkapi dengan alat pemantauan yang luar biasa. Semoga ini lebih disorot untuk orang lain. @ rv7 Saya yakin Anda melihat ini, tetapi ada solusi windows: npmjs.com/package/pm2-windows-service . Belum mencobanya sendiri.
John Lee
11

Sebuah metode crontab alternatif terinspirasi oleh ini jawaban dan ini posting blog.

1. Buat file skrip bash (ubah bob menjadi pengguna yang diinginkan).

vi /home/bob/node_server_init.sh

2. Salin dan tempel ini di dalam file yang baru saja Anda buat.

#!/bin/sh

export NODE_ENV=production
export PATH=/usr/local/bin:$PATH
forever start /node/server/path/server.js > /dev/null

Pastikan untuk mengedit jalur di atas sesuai dengan konfigurasi Anda!

3. Pastikan skrip bash dapat dieksekusi.

chmod 700 /home/bob/node_server_init.sh

4. Uji skrip bash.

sh /home/bob/node_server_init.sh

5. Ganti "bob" dengan pengguna runtime untuk node.

crontab -u bob -e

6. Salin dan tempel (ubah bob ke pengguna yang diinginkan).

@reboot /bin/sh /home/bob/node_server_init.sh

Simpan crontab.

Anda telah berhasil sampai akhir, hadiah Anda adalah reboot (untuk menguji) :)

Emre
sumber
Metode ini bekerja paling baik untuk saya. Selamanya akan berhenti ketika saya meletakkan path lengkap ke file server.js. Jika saya menjalankannya di direktori yang sama, foreveer akan berfungsi dengan baik. Alasannya gagal adalah file server.js termasuk file lain, tetapi jalurnya kacau. Dengan menggunakan metode ini, saya bisa CD di skrip .sh saya ke direktori, kemudian jalankan semuanya relatif di sana.
BeardedGeek
9

Jawaban disalin dari pertanyaan terlampir .

Anda dapat menggunakan PM2 , ini adalah manajer proses produksi untuk aplikasi Node.js dengan penyeimbang beban bawaan.

Instal PM2

$ npm install pm2 -g

Mulai aplikasi

$ pm2 start app.js

Jika Anda menggunakan ekspres maka Anda dapat memulai aplikasi seperti

pm2 start ./bin/www --name="app"

Daftar semua proses yang berjalan:

$ pm2 list

Ini akan mendaftar semua proses. Anda kemudian dapat menghentikan / memulai kembali layanan Anda dengan menggunakan ID atau Nama aplikasi dengan perintah berikut.

$ pm2 stop all                  
$ pm2 stop 0                    
$ pm2 restart all               

Untuk menampilkan log

$ pm2 logs ['all'|app_name|app_id]
Vikash Rajpurohit
sumber
Bagaimana cara memulai OTOMATIS pada boot sistem? Anda cukup menyalin / menempelkan pengetikan manual CLI
Green
@ Hijau, Jalankan, $pm2 startupSetelah itu Anda akan melihat pm2 meminta untuk secara manual menjalankan perintah, salin dan jalankan itu. Lalu, $pm2 saveSekarang app.js Anda akan selamat dari reboot sistem
yajnesh
7

Anda perlu membuat skrip shell di folder /etc/init.d untuk itu. Agak rumit jika Anda belum pernah melakukannya tetapi ada banyak informasi di web tentang skrip init.d.

Berikut ini contoh skrip yang saya buat untuk menjalankan situs CoffeeScript selamanya:

#!/bin/bash
#
# initd-example      Node init.d 
#
# chkconfig: 345 
# description: Script to start a coffee script application through forever
# processname: forever/coffeescript/node
# pidfile: /var/run/forever-initd-hectorcorrea.pid 
# logfile: /var/run/forever-initd-hectorcorrea.log
#
# Based on a script posted by https://gist.github.com/jinze at https://gist.github.com/3748766
#


# Source function library.
. /lib/lsb/init-functions


pidFile=/var/run/forever-initd-hectorcorrea.pid 
logFile=/var/run/forever-initd-hectorcorrea.log 

sourceDir=/home/hectorlinux/website
coffeeFile=app.coffee
scriptId=$sourceDir/$coffeeFile


start() {
    echo "Starting $scriptId"

    # This is found in the library referenced at the top of the script
    start_daemon

    # Start our CoffeeScript app through forever
    # Notice that we change the PATH because on reboot
    # the PATH does not include the path to node.
    # Launching forever or coffee with a full path
    # does not work unless we set the PATH.
    cd $sourceDir
    PATH=/usr/local/bin:$PATH
    NODE_ENV=production PORT=80 forever start --pidFile $pidFile -l $logFile -a -d --sourceDir $sourceDir/ -c coffee $coffeeFile

    RETVAL=$?
}

restart() {
    echo -n "Restarting $scriptId"
    /usr/local/bin/forever restart $scriptId
    RETVAL=$?
}

stop() {
    echo -n "Shutting down $scriptId"
    /usr/local/bin/forever stop $scriptId
    RETVAL=$?
}

status() {
    echo -n "Status $scriptId"
    /usr/local/bin/forever list
    RETVAL=$?
}


case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage:  {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Saya harus memastikan folder dan PATH secara eksplisit diatur atau tersedia untuk pengguna root karena skrip init.d dijalankan sebagai root.

Hector Correa
sumber
2
Jika Anda memiliki dependensi yang juga dimulai dengan init.d Anda mungkin memiliki masalah pemuatan pesanan.
UpTheCreek
@ alexandru.topliceanu Saya sudah memperbaiki tautannya.
Hector Correa
6

Gunakan PM2

Yang merupakan opsi terbaik untuk menjalankan server server produksi

Apa keuntungan menjalankan aplikasi Anda dengan cara ini?

  • PM2 secara otomatis akan me-restart aplikasi Anda jika crash.

  • PM2 akan menyimpan log pengecualian tidak tertangani Anda - dalam hal ini, dalam file di /home/safeuser/.pm2/logs/app-err.log.

  • Dengan satu perintah, PM2 dapat memastikan bahwa setiap aplikasi yang dikelolanya restart ketika server reboot. Pada dasarnya, aplikasi simpul Anda akan mulai sebagai layanan.

ref: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Wisnu Mishra
sumber
5

Forever tidak dibuat untuk menjalankan aplikasi node sebagai layanan. Pendekatan yang tepat adalah dengan membuat entri / etc / inittab (sistem linux lama) atau pemula (sistem linux yang lebih baru).

Berikut ini beberapa dokumentasi tentang cara mengaturnya sebagai pemula: https://github.com/cvee/node-upstart

snez
sumber
Pemula gagal saya di CentOS dan saya membaca bahwa itu akan hilang. Membuat entri init.d sebenarnya bukan cara yang paling ramah pengguna, tapi itu linux saya rasa :)
Jorre
5

crontabtidak berfungsi untuk saya di CentOS x86 6.5. @reboot sepertinya tidak berfungsi.

Akhirnya saya mendapat solusi ini:

Edit: /etc/rc.local

sudo vi /etc/rc.local

Tambahkan baris ini ke akhir file. Ubah USER_NAMEdan PATH_TO_PROJECTke Anda sendiri. NODE_ENV=productionberarti aplikasi berjalan dalam mode produksi. Anda dapat menambahkan lebih banyak baris jika Anda perlu menjalankan lebih dari satu aplikasi node.js.

su - USER_NAME -c "NODE_ENV=production /usr/local/bin/forever start /PATH_TO_PROJECT/app.js"

Jangan diatur NODE_ENVdalam jalur terpisah, aplikasi Anda akan tetap berjalan dalam mode pengembangan, karena selamanya tidak mendapatkan NODE_ENV.

# WRONG!
su - USER_NAME -c "export NODE_ENV=production"

Simpan dan keluar vi (tekan ESC : w q return). Anda dapat mencoba me-reboot server Anda. Setelah server Anda reboot, aplikasi node.js Anda harus berjalan secara otomatis, bahkan jika Anda tidak masuk ke akun apa pun dari jarak jauh melalui ssh.

Anda sebaiknya mengatur NODE_ENVlingkungan di shell Anda. NODE_ENVakan diatur secara otomatis ketika akun Anda USER_NAMEmasuk.

echo export NODE_ENV=production >> ~/.bash_profile

Jadi Anda dapat menjalankan perintah seperti selamanya berhenti / mulai /PATH_TO_PROJECT/app.jsmelalui ssh tanpa pengaturan NODE_ENVlagi.

Vince Yuan
sumber
mendapat masalah yang sama pada debian 7.6. Ini diperbaiki untuk saya. Terimakasih banyak.
Daniele Vrut
Jika Anda tidak ingin menggunakan 'selamanya', Anda dapat mengubah baris ke 'su - USER_NAME -c "NODE_ENV = simpul produksi / PATH_TO_PROJECT / bin / www"'.
yaobin
3

Saya menulis sebuah skrip yang melakukan ini:

https://github.com/chovy/node-startup

Saya belum pernah mencoba selamanya, tetapi Anda dapat menyesuaikan perintah yang dijalankannya, sehingga harus langsung:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop
kenyal
sumber
1

Saya mencoba banyak jawaban di atas. Tak satu pun dari mereka yang bekerja untuk saya. Aplikasi saya dipasang di /homedan sebagai pengguna, bukan sebagai root. Ini mungkin berarti bahwa ketika skrip mulai yang disebutkan di atas berjalan, /homebelum terpasang, sehingga aplikasi belum dimulai.

Kemudian saya menemukan instruksi ini oleh Digital Ocean:

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Menggunakan PM2 seperti yang dijelaskan sangat sederhana dan berfungsi dengan baik: Server virtual saya mengalami dua crash fisik sejak - downtime hanya sekitar satu menit.

Alex
sumber
PM2 memiliki lebih banyak bintang (2x) di github, daripada selamanya, dan ia memiliki lebih banyak fitur juga. Saya pikir sebagian besar jawabannya sudah usang di sini.
inf3rno
1

Masalah dengan rc.local adalah bahwa perintah diakses sebagai root yang berbeda dari login sebagai pengguna dan menggunakan sudo.

Saya memecahkan masalah ini dengan menambahkan skrip .sh dengan perintah startup yang saya inginkan ke etc / profile.d. File .sh dalam profil.d akan dimuat secara otomatis dan perintah apa pun akan diperlakukan seolah-olah Anda menggunakan sudo biasa.

Satu-satunya downside ke ini adalah pengguna yang ditentukan harus loggin untuk memulai hal-hal yang dalam situasi saya selalu terjadi.

Moe Elsharif
sumber
0

lengkapi contoh crontab (terletak di / etc / crontab) ..

#!/bin/bash

# edit this file with .. crontab -u root -e
# view this file with .. crontab -u root -l

# put your path here if it differs
PATH=/root/bin:/root/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

# * * * * * echo "executes once every minute" > /root/deleteme

@reboot cd /root/bible-api-dbt-server; npm run forever;
@reboot cd /root/database-api-server; npm run forever;
@reboot cd /root/mailer-api-server; npm run forever;
danday74
sumber
-1

Anda dapat menggunakan perintah berikut di shell Anda untuk memulai node Anda selamanya:

forever app.js //my node script

Anda harus ingat bahwa server tempat aplikasi Anda berjalan harus selalu dijaga.

Gaurav Singh
sumber