Làm cách nào để chạy ứng dụng Node.js theo quy trình của chính nó?


195

Cách tốt nhất để triển khai Node.js là gì?

Tôi có một Dreamhost VPS (đó là cái mà họ gọi là VM ) và tôi đã có thể cài đặt Node.js và thiết lập proxy. Điều này hoạt động rất tốt miễn là tôi giữ kết nối SSH mà tôi đã bắt đầu mở nút.


6
Hmm, có vẻ lạ đối với tôi khi bạn gọi bằng cách sử dụng Mãi mãi là "triển khai node.js". Nó không chỉ là một công cụ giám sát / giám sát quá trình? Thông thường triển khai web có nghĩa là (ít nhất là những gì tôi gặp trong các bài viết) một số hoạt động liên quan đến nhau làm cho một ứng dụng web có sẵn (công cụ xử lý này là một phần của nó). Dù sao, đây vẫn là một bài viết tuyệt vời ở đây trong StackOverflow khi tôi học được từ câu trả lời của mọi người.
mikong

Đây chỉ là triển khai đơn giản nhất của node.js trên Dreamhost. Mục tiêu chỉ đơn giản là để nút chạy đáng tin cậy như một điểm khởi đầu để xây dựng từ đó.
tôn trọng TheCode

Làm thế nào bạn xử lý chuyển tiếp tên miền đến nút cổng đang chạy?
grm

2
@grm tôi sử dụng HTTP Proxy github.com/nodejitsu/node-http-proxy
respectTheCode

Chúng tôi đang sử dụng Elastic Beanstalk và nó đang hoạt động khá độc đáo.
tôn trọng TheCode

Câu trả lời:


107

Câu trả lời năm 2016 : gần như mọi bản phân phối Linux đều đi kèm với systemd, có nghĩa là mãi mãi, monit, PM2, v.v. không còn cần thiết nữa - HĐH của bạn đã xử lý các tác vụ này .

Tạo một myapp.servicetệp (rõ ràng thay thế 'myapp' bằng tên ứng dụng của bạn):

[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=nobody
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp

[Install]
WantedBy=multi-user.target

Lưu ý nếu bạn chưa quen với Unix: /var/www/myapp/app.js nên có #!/usr/bin/env nodengay dòng đầu tiên.

Sao chép tập tin dịch vụ của bạn vào /etc/systemd/systemthư mục.

Nói với systemd về dịch vụ mới với systemctl daemon-reload.

Bắt đầu với systemctl start myapp.

Cho phép nó chạy khi khởi động với systemctl enable myapp.

Xem nhật ký với journalctl -u myapp

Điều này được lấy từ Cách chúng tôi triển khai các ứng dụng nút trên Linux, phiên bản 2018 , cũng bao gồm các lệnh để tạo AWS / DigitalOcean / Azure CloudConfig để xây dựng máy chủ Linux / nút (bao gồm cả .servicetệp).


1
Bất cứ ý tưởng về làm thế nào để đối phó với Failed to issue method call: Unit name ... is not valid.?
Julien Genestoux

1
@JulienGenestoux tên 'đơn vị' giống với dịch vụ của bạn. Có vẻ như có một sự khác biệt ở đó. Sau khi bạn sao chép tệp vào /etc/systemd/systembạn có thể cần chạy systemctl daemon-reload(systemd thường sẽ cho bạn biết nếu điều này là cần thiết). TBH này được hỏi tốt nhất là một câu hỏi riêng biệt.
mikemaccana

3
Thay vì sao chép tệp dịch vụ của bạn vào /etc/systemd/system, bạn chỉ có thể sử dụng systemctl enable /full/path/to/myapp.service, điều này tạo ra một liên kết tượng trưng /etc/systemd/systemcho bạn.
Arne

1
Làm thế nào để nó so sánh với pm2? Nó có thể thay thế pm2 hoặc pm2 cung cấp nhiều tính năng cần thiết hơn không?
Sergei Basharov

1
@VinodSrivastav nodeđược gọi bằng /var/www/myapp/app.jschính nó. Trong Unix, nếu bạn tạo một tệp thực thi và dòng đầu tiên bắt đầu với #!/some/filetệp sẽ được diễn giải với tệp nhị phân đó. Google 'phiên dịch Unix' để biết thêm.
mikemaccana

101

Sử dụng mãi mãi . Nó chạy các chương trình Node.js trong các quy trình riêng biệt và khởi động lại chúng nếu có chết.

Sử dụng:

  • forever start example.js để bắt đầu một quá trình.
  • forever list để xem danh sách tất cả các quy trình bắt đầu mãi mãi
  • forever stop example.jsđể dừng quá trình hoặc forever stop 0dừng quá trình với chỉ số 0 (như được hiển thị bởi forever list).

Đây là gần. Nó bắt đầu tốt nhưng sẽ không để tôi dừng lại bất cứ điều gì. Tôi đã có thể đăng xuất và đăng nhập trở lại và sau đó giết tiến trình nút. Mãi mãi không khởi động lại nó. Vì vậy, tôi đang suy nghĩ điều gì đó về cách thức hoạt động của nó không tương thích với DH.
tôn trọng TheCode

@Kevin, bạn không thể giết tiến trình nút vì bản thân Forever chạy trên nút! Tôi đã thêm một số hướng dẫn sử dụng vào câu trả lời của mình, bao gồm cách dừng quá trình. Tôi đã sử dụng cái này trên VPS của tôi và nó hoạt động như một cơ duyên.
David Tang

forever stop 0có một lỗi và mọi thứ chỉ rơi ra từ đó. Tôi đã cố gắng làm điều này mà không cần root trên chính người dùng của mình để tôi có thể dọn dẹp dễ dàng một khi tôi tìm được giải pháp phù hợp. Đó có thể là vấn đề của tôi. Tôi sẽ xem xét thêm một số.
tôn trọng TheCode

Tôi đã có một cái gì đó sai với npm đã gây ra vấn đề. Với npm và nút được cài đặt chính xác mãi mãi hoạt động tuyệt vời. Điều cuối cùng tôi làm là thêm các lệnh khởi động mãi mãi vào một bộ cronjob để chạy khi khởi động lại. Bây giờ tôi đang làm việc trên một ứng dụng nút nhỏ cho phép tôi bắt đầu và dừng mãi mãi procs.
tôn trọng TheCode

Có một giải pháp thay thế cho Forever sử dụng API cụm gốc của nút: github.com/superjoe30/naught
andrewrk

41

Tôi đã viết về phương thức triển khai của mình ở đây: Triển khai các ứng dụng node.js

Nói ngắn gọn:

  • Sử dụng git post-receive hook
  • Jake cho công cụ xây dựng
  • Khởi đầu như một trình bao bọc dịch vụ cho nút
  • Monit để theo dõi và khởi động lại các ứng dụng mà chúng đi xuống
  • nginx để định tuyến các yêu cầu đến các ứng dụng khác nhau trên cùng một máy chủ

2
Nếu tôi sẽ luôn có một trang web Node duy nhất trên máy chủ của mình, tôi có thể bỏ Nginx một cách an toàn không?
Dor

3
Liên kết dường như bị phá vỡ
Verybadalloc

@Dor Tôi biết đây là một phản hồi muộn, nhưng tôi sẽ không. Ngoài những thứ như chấm dứt SSL và bộ nhớ đệm, proxy ngược nginx trước máy chủ cho phép bạn linh hoạt về cơ sở hạ tầng hơn so với chạy nút trực tiếp trên cổng 80. Điều đó cũng có nghĩa là bạn không phải chạy nút như root, mà tôi nghĩ là một cuộc tranh luận khá nặng nề ủng hộ việc thiết lập nginx.
Chris Browne

16

pm2 thực hiện các thủ thuật.

Các tính năng là: Giám sát, tải lại mã nóng, cân bằng tải tích hợp, tập lệnh khởi động tự động và quá trình hồi sinh / kết xuất.


Có tương thích với các dịch vụ như Heroku không?
FRD

@FRD Tôi không nghĩ nó hoạt động với heroku, hãy xem bài viết này
nickleefly

9

Bạn có thể sử dụng monit, forever, upstarthoặc systemdđể bắt đầu máy chủ của bạn.

Bạn có thể sử dụng Varnish hoặc HAProxy thay vì Nginx (Nginx được biết là không hoạt động với websockets).

Là một giải pháp nhanh chóng và bẩn thỉu, bạn có thể sử dụng nohup node your_app.js &để ngăn chặn ứng dụng của mình chấm dứt với máy chủ của mình, nhưng forever, monitvà các giải pháp được đề xuất khác là tốt hơn.


2
Một người dùng "Sergey Yarotskiy" đã cố gắng chỉnh sửa bài đăng của bạn nói rằng Nginx hiện hỗ trợ WebSockets (kể từ phiên bản 1.3). Tôi đã từ chối chỉnh sửa vì tôi nghĩ nó nên được đăng dưới dạng bình luận. (Nếu không, bạn có hai câu trái ngược nhau trong cùng một bài, điều này gây nhầm lẫn.)
Backlin

7

Tôi đã tạo một tập lệnh Upstart hiện đang được sử dụng cho các ứng dụng của mình:

description "YOUR APP NAME"
author "Capy - http://ecapy.com"

env LOG_FILE=/var/log/node/miapp.log
env APP_DIR=/var/node/miapp
env APP=app.js
env PID_NAME=miapp.pid
env USER=www-data
env GROUP=www-data
env POST_START_MESSAGE_TO_LOG="miapp HAS BEEN STARTED."
env NODE_BIN=/usr/local/bin/node
env PID_PATH=/var/opt/node/run
env SERVER_ENV="production"

######################################################

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 99 5

pre-start script
    mkdir -p $PID_PATH
    mkdir -p /var/log/node
end script

script
    export NODE_ENV=$SERVER_ENV
    exec start-stop-daemon --start --chuid $USER:$GROUP --make-pidfile --pidfile $PID_PATH/$PID_NAME --chdir $APP_DIR --exec $NODE_BIN -- $APP >> $LOG_FILE 2>&1
end script

post-start script
    echo $POST_START_MESSAGE_TO_LOG >> $LOG_FILE
end script

Tùy chỉnh tất cả trước khi #########, tạo một tệp trong /etc/init/your-service.conf và dán nó vào đó.

Sau đó bạn có thể:

start your-service
stop your-service
restart your-service
status your-service

Cảm ơn bạn, chỉ những gì tôi cần.
Nilson Morais

6

Tôi đã viết một hướng dẫn khá toàn diện để triển khai Node.js, với các tệp ví dụ:

Hướng dẫn: Cách triển khai các ứng dụng Node.js, với các ví dụ

Nó bao gồm những thứ như http-proxy, SSLSocket.IO .


Điều này có vẻ tuyệt vời. Tôi đang sử dụng heroku để phát triển và khởi chạy ban đầu nhưng cuối cùng sẽ cần mở rộng quy mô của heroku và triển khai trực tiếp lên EC2. Tôi sẽ chơi với điều này khi tôi có thời gian.
tôn trọng TheCode

5

Đây là một bài viết dài hơn về việc giải quyết vấn đề này với systemd: http://savanne.be/articles/deploying-node-js-with-systemd/

Một số điều cần lưu ý:

  • Ai sẽ bắt đầu theo dõi quá trình của bạn? Mãi mãi là một công cụ tuyệt vời, nhưng nó cần một công cụ giám sát để duy trì hoạt động. Điều đó hơi ngớ ngẩn, tại sao không sử dụng hệ thống init của bạn?
  • Bạn có thể theo dõi đầy đủ các quy trình của bạn?
  • Bạn đang chạy nhiều phụ trợ? Nếu vậy, bạn có sẵn các điều khoản để ngăn chặn bất kỳ ai trong số họ hạ bệ những người khác về việc sử dụng tài nguyên không?
  • Dịch vụ sẽ được cần thiết tất cả các thời gian? Nếu không, hãy xem xét kích hoạt ổ cắm (xem bài viết).

Tất cả những điều này được thực hiện dễ dàng với systemd.


5

Nếu bạn có quyền truy cập root, tốt hơn bạn nên thiết lập một daemon để nó chạy an toàn và âm thanh trong nền. Bạn có thể đọc cách làm điều đó đối với DebianUbuntu trong bài đăng trên blog Chạy Node.js dưới dạng Dịch vụ trên Ubuntu .


Tôi không nghĩ rằng tôi đã root nhưng có vẻ như tôi phải kích hoạt nó trong bảng điều khiển web. Tôi sẽ cung cấp cho một shot này.
tôn trọng TheCode

3

Mãi mãi sẽ làm nên chuyện.

@Kevin: Bạn sẽ có thể giết quá trình tốt. Tôi sẽ kiểm tra lại tài liệu một chút. Nếu bạn có thể tái tạo lỗi, sẽ rất tuyệt nếu đăng nó thành một vấn đề trên GitHub.


Kevin là ai? OP?
Peter Mortensen


2

Như Box9 đã nói, Mãi mãi là một lựa chọn tốt cho mã sản xuất. Nhưng cũng có thể tiếp tục quá trình ngay cả khi kết nối SSH bị đóng khỏi máy khách.

Mặc dù không nhất thiết là một ý tưởng tốt cho sản xuất, nhưng điều này rất tiện lợi khi ở giữa các phiên gỡ lỗi dài hoặc theo dõi đầu ra của bàn điều khiển của các quy trình dài hoặc bất cứ khi nào hữu ích để ngắt kết nối SSH của bạn, nhưng giữ cho thiết bị đầu cuối tồn tại trong máy chủ để kết nối lại sau (như khởi động ứng dụng Node.js tại nhà và kết nối lại với bàn điều khiển sau này tại nơi làm việc để kiểm tra xem mọi thứ đang diễn ra như thế nào).

Giả sử rằng máy chủ của bạn là hộp * nix, bạn có thể sử dụng lệnh màn hình từ trình bao để duy trì quá trình chạy ngay cả khi máy khách SSH bị đóng. Bạn có thể tải xuống / cài đặt màn hình từ web nếu chưa được cài đặt (tìm gói cho bản phân phối của bạn nếu Linux hoặc sử dụng MacPorts nếu OS X).

Nó hoạt động như sau:

  1. Khi bạn lần đầu mở kết nối SSH, hãy nhập 'màn hình' - thao tác này sẽ bắt đầu phiên màn hình của bạn.
  2. Bắt đầu hoạt động như bình thường (nghĩa là bắt đầu ứng dụng Node.js của bạn)
  3. Khi bạn đã hoàn tất, đóng thiết bị đầu cuối của bạn. Quá trình máy chủ của bạn sẽ tiếp tục chạy.
  4. Để kết nối lại với bảng điều khiển của bạn, ssh trở lại máy chủ, đăng nhập và nhập 'screen -r' để kết nối lại. Bối cảnh giao diện điều khiển cũ của bạn sẽ bật lại sẵn sàng để bạn tiếp tục sử dụng nó.
  5. Để thoát khỏi màn hình, trong khi được kết nối với máy chủ, hãy nhập 'exit' trên dấu nhắc bàn điều khiển - nó sẽ thả bạn vào vỏ thông thường.

Bạn có thể có nhiều phiên màn hình chạy đồng thời như thế này nếu bạn cần và bạn có thể kết nối với bất kỳ phiên nào từ bất kỳ máy khách nào. Đọc tài liệu trực tuyến cho tất cả các tùy chọn.


Thông tin tốt để có. Tôi đồng ý rằng nó sẽ không hoạt động để sản xuất nhưng có thể rất hữu ích khi gỡ lỗi trên một máy chủ từ xa.
tôn trọng TheCode

tại sao không sử dụng nút nohup myapp.js & 2> /var/log/myapp.log 1> / dev / null
markus_p

Tôi tìm thấy điều này hữu ích youtube.com/watch?v=P4mT5Tbx_KE giải thích nohupforever
Vinod Srivastav

1

Mãi mãi là một lựa chọn tốt để duy trì các ứng dụng chạy (và npm có thể cài đặt như một mô-đun tốt đẹp).

Nhưng đối với 'triển khai' nghiêm trọng hơn - những thứ như quản lý từ xa về triển khai, khởi động lại, chạy các lệnh, v.v. - Tôi sẽ sử dụng capistrano với phần mở rộng nút.

https://github.com/loopj/capistrano-node-deploy


1

https://paastor.com là một dịch vụ tương đối mới triển khai cho bạn, đến VPS hoặc máy chủ khác. Có một CLI để đẩy mã. Paastor có một cấp miễn phí, ít nhất là nó đã làm tại thời điểm đăng bài này.



1

Hãy thử nút-triển khai-máy chủ . Nó là một bộ công cụ phức tạp để triển khai một ứng dụng lên các máy chủ riêng của bạn. Nó được viết bằng Node.js và sử dụng npm để cài đặt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.