跳到主要内容
CNode

如何用Systemd和Nginx部署Node.js应用程序?

社区
Yyingjie0904发布于 12 年前最后回复 12 年前
271130

如何用Systemd和Nginx部署Node.js应用程序?


###介绍 当部署一个网络应用程序到一个Droplet时,使用开发过程中用到的相同的设置是很有诱惑的,比如开启服务器时通过在终端运行 “ruby app.rb” 或 “node server.js”,这样简单容易,还能提供可视化的登陆。当SSH会话结束时,有人甚至会用“screen”或 “tmux” 或 “nohup”让它保持运行。这很危险:如果服务器崩溃,而周围又没人重启它,该怎么办?

你可以使用forever和crontab来解决问题。这篇教程提供了一个更强大,也是更复杂的解决方案。用systemd(未来在Arch、Fedora和CentOS上也可以用)网络应用程序可实现完全管理:通过控制组( cgroups)管理日志(logs), 正常运行时间(uptime), 资源(resources)和安全问题(security),高级后台程序启动可以统一访问,控制和调整.

这一教程使用一个简单的Node.js应用程序,但它适用于大多数,如果不是全部,用其他的也可以(可以是Ruby,Python等等)。对于PHP网络应用程序,建议改为使用一个更加专业的LAMP或LEMP堆栈。

Fedora和Arch都需要提供命令,一定要保持监视,以避免发生错误配置或混淆。当没有指向时,给两个系统的命令要相同。同时建议在按教程操作之前要通读整个教程,以便了解清楚它都需要什么,是否试用于你的情况。


###系统准备 —带有**systemd**的服务器。Arch Linux和Fedora droplets是被默认设置的,但systemd也可以在其他分支上安装;指向你的文件:Ubuntu,Debian。

Nginx, 用作反向代理http和websocket服务器。 • Git, 用来安装nvm,拉取你的应用程序。 • Root 访问.也可能作为一个普通用户登录,并sudo所有的命令,或**su –sudo su –**到一个根提示符。


**安装包** Arch:
 # pacman -Sy
# pacman -S nginx git

Fedora:

# yum install nginx git

###应用程序准备 你可以根据自己的喜好自定义设置,但它们须在开始之前设置好。
**用户** 应用程序会在它自己单独的用户账户里运行。选个与应用程序有关的名字,这样容易记住也容易维护。这里用的是`srv-node-sample`。
 # useradd -mrU srv-node-sample

**端口** 为了避免冲突,选一个大点的端口。这里,用的是“15301”。
###应用程序设置 安装应用程序运行所必须的东西来启动。对于Node.js(和Ruby,Python...),有两个选择:使用系统的运行时间,或一个特定用户的安装(例如使用[nvm](https://github.com/creationix/nvm),[rbenv](https://github.com/sstephenson/rbenv),[RVM](https://rvm.io/),[virtualenv](http://www.virtualenv.org/en/latest/)等等)。
**使用system node** Arch:
# pacman -S nodejs

Fedora:

# yum install nodejs

**用一个具体用户安装** 这一步需要在一个应用程序的主目录里安装,例如: `/home/srv-node-sample`,通过以那个用户的身份进行登录可以容易地完成。
# su srv-node-sample
$ cd
$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh
$ source ~/.nvm/nvm.sh
$ nvm install 0.10
$ nvm alias default 0.10

然后记录下node二进制文件安装的位置

$ which node
/home/srv-node-sample/.nvm/v0.10.22/bin/node

**部署你的应用程序** 登录到`srv-node-sample`时,部署你的code。这只是个例子,你的过程可能会有变化。
$ git clone git[@server](/user/server).company.tld:user/repo.git .
$ npm install
$ grunt deploy

对于这篇教程,用的是下面的实例应用程序:

var http = require('http');
http.createServer(function(req, res) {
    res.end('

Hello, world.

'); }).listen(15301);

然后返回到根目录:

$ exit

###Nginx 设置

这篇教程仅简单介绍必要的配置,想要了解关于配置Nginx更详细的内容,可以查看“如何配置Nginx网络服务器”或nginx手册。

将下面内容放到你的server block:

 location / {
    proxy_pass http://localhost:15301/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

然后建立它的后台程序:

# systemctl enable nginx
# systemctl restart nginx

###Systemd设置 在`/etc/systemd/system/node-sample.service`里,给应用程序创建一个服务文件。 有一些变量需要填充: • [node二进制文件] 这是作为srv-node-sample 用户的“which node”的输出. 上面提到的/usr/bin/node或~/.nvm/... 两个路径都可以。 • [主文件]这是你的应用程序的主文件。在这儿是‘index.js`. • 不要忘记替换 srv-node-sample!
[Service]
ExecStart=[node binary] /home/srv-node-sample/[main file]
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node-sample
User=srv-node-sample
Group=srv-node-sample
Environment=NODE_ENV=production

[Install] WantedBy=multi-user.target

现在开启该服务:

# systemctl enable node-sample
# systemctl start node-sample

###使用 ¬¬— ####状态 —
###Systemctl状态下的node-示例(systemctl status node-sample) Node-sample.service 加载完毕(loaded): 加载完毕(loaded)(/etc/systemd/system/node-sample.service; 激活启用(enabled)) 主动(Active):主动(active) (运行) 从周五 2013-11-22 01:12:15 UTC; 35秒之前 主PID: 7213 (node) CGroup: 名字=systemd:/system/node-sample.service └─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod... 11月22日 01:12:15 d02 systemd[1]: 开启 node-sample.service.
**日志记录**
###journalctl -u node-sample -- 日志于2013-11-21 周四19:05:17 UTC开始,于2013-11-22周五 01:12:15 UTC结束. -- 11月22日 01:12:15 d02 systemd[1]: Starting node-sample.service... 11月22日 01:12:15 d02 systemd[1]: Started node-sample.service. 11月22日 01:12:30 d02 node-sample[7213]: Sample message from application
**重启,停止**

强制重启:

# systemctl restart node-sample

停止应用程序

# systemctl stop node-sample

如果应用程序崩溃或结束,它将会自动重启:

# systemctl status node-sample
node-sample.service
   Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
   Active: active (running) since Fri 2013-11-22 01:12:15 UTC; 35s ago
 Main PID: 7213 (node)
   CGroup: name=systemd:/system/node-sample.service
           └─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...

Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.

# kill 7213

# systemctl status node-sample
node-sample.service
   Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
   Active: active (running) since Fri 2013-11-22 01:54:37 UTC; 6s ago
 Main PID: 7236 (node)
   CGroup: name=systemd:/system/node-sample.service
           └─7236 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...

Nov 22 01:54:37 d02 systemd[1]: node-sample.service holdoff time over, sch...t.
Nov 22 01:54:37 d02 systemd[1]: Stopping node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Starting node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Started node-sample.service.

PID已经变了,表示应用程序确实被结束并重启。


**Websockets** 如果应用程序使用websockets,下面几行需要添加到Nginx配置中:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

并且Nginx需要重新加载:

# systemctl reload nginx

From: https://www.digitalocean.com/community/articles/how-to-deploy-node-js-applications-using-systemd-and-nginx
查看回复

回复 (2)

J
jiyinyiyong#112 年前

文章不错, 看下 GFM 改进一些文章标记吧 :) http://github.github.com/github-flavored-markdown/

参与回复

登录后即可参与回复。登录