文章目录
源由
node.js 越来越流行,托管 node.js 应用的云服务也越来越多,例如 nodejitsu、heroku 等。
但是这些云服务通常有这样那样的限制,又或者是要收费的。而有些时候我通常不需要跑很大的应用,或者是很稳定的应用,只是为了跑一些小的,或者是学习用的 node.js 应用,并且我也有自己的 VPS,想把这些应用托管在自己的服务器上。
于是我需要去找一个可以在自己的 VPS 上建设一个 node.js 私有云的软件。
比较
在看了
- nodester: 安装比较麻烦,不支持新版本的 nodejs,安装说明还是针对 node 0.4.11 的
- CloudFoundry: 比较庞大,而且是以 vm 方式安装,不适合 VPS
- OpenShift: 同 CloudFoundry,不只支持 node.js,安装复杂,不适合 VPS
- Nodejitsu: Nodejitsu 开源了他们所用的 node.js 应用管理项目 haibu,haibu 安装比较简单,而且支持最新的 nodejs 0.8.16,不过 Nodejitsu 同样开源的命令行客户端 jitsu 并不支持 haibu
- Stagecoach: 文档不够清晰,看了很久也没明白它的架构和怎么部署⋯⋯
这样看来似乎没有一个可以满足我的需要,不过 GitHub 是强大的,通过搜索找到了 ukraine 这个项目:
ukraine glues haibu and node-http-proxy adding a little helper, chernobyl, that deploys into this cloud. It is probably as stable as you think it is.
这就是我想要的。
修改
原始的 ukraine 虽然已经基本满足了我的需要,但是还有一些小的功能需要增加:
- 使用 nginx 作为前端,这样 node.js 应用可以部署在 nginx 后面,与 PHP 等项目并存
- 使用 SSL 保护 haibu 的服务端,防止 auth_token 因为不加密的 HTTP 通信而泄漏
- 因为使用 nginx 作为前端,所以 haibu 服务端和 node-http-proxy 都不需要监听 0.0.0.0,而只需要监听 127.0.0.1
- 防止 node.js 应用监听了常用端口而导致其他应用启动失败,因为使用了 nginx 作为前端,node.js 应用本身监听了什么端口就不重要了
- 防止 node.js 应用直接对外提供服务,同样因为已经有 nginx,node.js 应用只需要监听 127.0.0.1 就行了
- chernobyl 不支持配置每个不同的 ukraine 监听在哪个端口,以及有没有配置 SSL
- 我想 ukraine 作为一个服务存在,这样在 VPS 启动时可以自动启动
- node.js 应用需要支持绑定自定义域名,而不是只能绑定子域名
所以我 fork 了 radekstepan 的 ukraine 到
安装修改后的 ukraine
如果你和我一样,也需要一个这样简单的 node.js 私云,那么以下的内容可以帮助里部署 ukraine 到自己的 VPS 上。
注意:安装教程以在 Ubuntu/Debian 上为例,并且所有命令是以 root 用户执行。
1. 安装 node.js
haibu 需要 node.js 的版本大于 0.8,所以需要安装最新的 node.js 包,或者自行编译安装。
参考这篇文章:Installing Node.js via package manager
2. 安装 forever
forever 是用来维持 ukraine 一直在启动状态
npm install forever -g
3. 配置 nodejs 用户
为了使所有 node.js 应用不使用 root 权限运行,防止出现权限方便的风险,需要添加一个用户 nodejs
来运行 node.js 应用。
groupadd nodejs
useradd -g nodejs -m -s /bin/bash nodejs
4. 获取并安装 ukraine
为了管理方便,这里安装 ukraine 到 /srv/ukraine 中,如果你不安装在这个位置,那么相关的脚本和配置文件都需要修改。
cd /srv
git clone https://github.com/ohdarling/ukraine
cd ukraine
git checkout private-cloud
npm install
chown -R nodejs.nodejs /srv/ukraine
5. 配置 ukraine
cd /srv/ukraine
cp config.example.json config.json
vim config.json
为了安全起见,建议 auth_token 不要留空。
example.com
需要替换为你自己的域名,这样以后部署了 node.js 应用时,会自动分配一个 package-name.example.com 的子域名。
6. 安装服务脚本
注意:这个脚本只适用于 Ubuntu/Debian。
cd /srv/ukraine
cp server/init-script/ukraine /etc/init.d/
chmod +x /etc/init.d/ukraine
7. 使用 nginx 作为前端服务
为了使 node.js 应用与原有的 PHP 共存,使用 nginx 作为 ukraine 的前端服务。
注意:部署 node.js 应用到 ukraine 需要 nginx 启用 chunkin 模块,默认情况下 nginx 并没有安装此模块,可以自行编译安装(参考 nginx-extras
,这个包中包含的 nginx 已经编译了 chunkin 模块。
添加以下配置文件内容到 /etc/nginx/sites-available/ukraine
,并且在 /etc/nginx/sites-enabled/
中添加一个到配置文件的符号链接。注意,需要替换配置文件内容中的 haibu.example.com
和 *.example.com
为你自己的域名。
server {
listen 80;
server_name haibu.example.com;
access_log /var/log/nginx/localhost.access.log;
chunkin on;
error_page 411 = @my_411_error;
location @my_411_error {
chunkin_resume;
}
location / {
proxy_pass http://localhost:9002;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 80;
server_name *.example.com;
access_log /var/log/nginx/localhost.access.log;
location / {
proxy_pass http://localhost:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}
建议在 haibu.example.com 这个站点上启动 SSL 来保护 auth_token。
添加完配置文件后,使用以下命令让 nginx 重新载入配置:
nginx -s reload
8. 启动 ukraine
service ukraine start
9. 检查 ukraine 是否正常运行
打开浏览器,访问 http://haibu.example.com/version
,将会看到以下内容:
{"version":"haibu 0.9.7"}
注意,如果在之前已经配置了 auth_token,将会看到:
{"message":"Wrong auth token"}
这说明 ukraine 已经正常启动。
部署自己的 node.js 应用
首先需要在本地安装 ukraine:
npm install -g git://github.com/ohdarling/ukraine\#private-cloud
如果之前配置了 auth_token:
chernobyl config haibu.example.com auth_token=xxxx
如果之前配置了 SSL:
chernobyl config haibu.example.com https=true
chernobyl config haibu.example.com haibu_port=443
现在可以部署 node.js 应用了,进入到 node.js 应用的根目录,运行以下命令:
chernobyl deploy haibu.example.com .
这就会部署这个 node.js 应用到 haibu.example.com 了。
给 node.js 应用绑定自定义域名
在给 node.js 绑定自定义域名,只需要在 package.json
中添加 domains
属性即可:
{
"name": "example-app",
"version": "0.0.2",
"domains": [
"custom-example.com"
]
"dependencies": {
"express": "2.5.x"
},
"scripts": {
"start": "server.js"
}
}
同样需要修改 nginx 的配置文件,把自定义域名加到 server_name 中:
server {
listen 80;
server_name *.example.com, custom-example.com;
access_log /var/log/nginx/localhost.access.log;
location / {
proxy_pass http://localhost:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}
注意事项
- 所有 node.js 应用会监听在一个随机端口,并且会监听在 127.0.0.1,也就意味着在外部没有办法直接访问这个应用
- package.json 中 scripts.start 属性,不需要带 node,只需要指定以哪个脚本启动即可,例如以下是错误的:
{
"name" : "example-app",
"scripts" : {
"start" : "node server.js"
}
}
- 如果需要 node.js 鉴定特定的端口,并能直接对外服务,可以在 package.json 的 env 属性中添加 "HAIBU_INDEPENDENT_SERVICE": "true",例如:
{
"name" : "somesocks",
"scripts" : {
"start" : "server.js"
},
"env" : {
"HAIBU_INDEPENDENT_SERVICE" : "true"
}
}
问题及反馈
你可以在 GitHub 上 fork 这个仓库:
联系我
Twitter: @ohdarling88
Email: ohdarling88 at gmail.com
感谢
- Nodejitsu for haibu and other open source projects
- radekstepan for ukraine
参考资料
- https://github.com/joyent/node/wiki/Node-Hosting
- https://github.com/ohdarling/ukraine
- https://github.com/radekstepan/ukraine
- https://github.com/nodejitsu/haibu
- https://github.com/nodejitsu/haibu-carapace
- Installing Node.js via package manager
--- EOF ---
Cool. VPS有要求么?
没要求,能跑 nodejs 就行。