部署Node.js的应用
原创:作者 mashihua
最近Node.js很火,让很多的前端看到了可以直接从前端写到后端的希望。但是每次部署一个Node.js的应用却让前端苦恼不已。每次登陆服务器,用自己不熟悉的方式从版本控制仓库中拖下源代码,kill掉应用的进程,重起一个应用的守护进程。如果能够自动化的部署一个Node.js应用,而不需要去接触这些前端不太熟悉的Unix系统命令和管理。对于大家来说就是提升了生产力。Capistrano是一个强大的自动化部署工具,所以我们选用他来做自动化部署。并且我已经把做好了的一个部署脚本<a href=“https://github.com/mashihua/Nodebot”>Nodebot</a>提交到github上去,供大家参考。 <br/> <br/>首先我们需要一个环境,分为两个环境:部署客户端环境和服务器环境。 <br/><h3>部署客户端系统需求:</h3> <br/>你可以用任何系统了,系统只要具备下面的4个软件就可。 <br/><ol> <br/> <li>安装ruby。去<a href=“http://www.ruby-lang.org/en/downloads/”>http://www.ruby-lang.org/en/downloads/</a>下载适合你系统的ruby版本。</li> <br/> <li>安装rubygem。去<a href=“http://rubyforge.org/projects/rubygems/”>http://rubyforge.org/projects/rubygems/</a>下载最新版的RubyGems,解压后运行以下命令安装。 sudo ruby setup.rb</li> <br/> <li>安装Capistrano和Capistrano-etx。运行以下的命令安装。sudo gem install capistrano capistrano-ext</li> <br/></ol> <br/>这样你就拥有了在机器部署node.js应用的软件。然后你需要能够不使用密码直接登陆到服务器上。运行下面的命令: <br/><pre># Create a local ssh key <br/>ssh-keygen <br/>#Copy key to server <br/>cat ~/.ssh/id_rsa.pub | ssh user@domain.com “cat >> .ssh/authorized_keys” <br/></pre> <br/>这样你就可以不需要密码直接登陆到服务器。 <br/><h3>服务器端系统需求:</h3> <br/>当然要Unix一类的系统了,Nodebot需要具备upstart的系统(一个基于事件的守护进程管理系统)。虽然Node.js能跑在window上,但是那只适合开发环境,不适合生产环境。还要有下面的软件,你也可以下载Nodebot并在部署客户端运行命令cap nodebot:setup 来自动化安装。 <br/><ol> <br/> <li>安装scm软件。比如git,svn或hg,取决于你的node.js应用源代码管理软件。</li> <br/> <li>安装Node.js。没什么好说的,地球人都知道这是什么。</li> <br/> <li>安装npm。Node.js的一个包管理软件</li> <br/> <li>安装node-jake。一个javascript的代码构建工具,有点像make和rake。用来安装应用的依赖。</li> <br/> <li>具备upstart的系统,比如Ubantu。来做应用的守护进程。参看 <a href=“http://upstart.ubuntu.com/”>http://upstart.ubuntu.com/</a></li> <br/></ol> <br/>部署的登陆用户需要sudo权限,并且不需要提示输入密码。参考命令: <br/><pre>#Add a sudoer <br/>sudo useradd -m foo <br/>#edit sudoer privilege <br/>sudo visudo <br/></pre> <br/>出现编辑器时,插入下面一行,foo就是你新建的用户: <br/><pre>foo ALL=(ALL) NOPASSWD: ALL</pre> <br/>然后在deploy.rb文件(下面会提到)里配置foo为部署用户。 <br/><h3>部署客户端脚本</h3> <br/>环境有了,那就要开工了。我们希望在服务器上的Node.js应用运行几个不同的环境:测试环境,开发环境,产品环境等。运行cap .命令会在当前的目录下产生一个文件和一个目录。在目录里有个deploy.rb,这是我们需要修改的文件。由于我们需要多个环境,所以我们引入了Capistrano-etx。 <br/><pre>set :stages, %w[staging production] <br/>set :default_stage, ‘staging’ <br/>require ‘capistrano/ext/multistage’ <br/></pre> <br/>我们设定了两个环境:staging和production,默认是staging环境。我们再在config目录下建一个deploy目录,里面放的两个.rb文件对应不同的环境配置.最后部署环境的目录下是这样的一个结构: <br/><pre>. <br/>├── Capfile <br/>└── config <br/> ├── deploy <br/> │ ├── production.rb <br/> │ └── staging.rb <br/> ├── deploy.rb <br/> └── node.rb</pre> <br/>deploy.rb文件看起来像这样。你需要设定host, repository,user和admin_user : <br/><pre>## <br/># Capistrano tasks for Ubantu. <br/># <br/># Author: Shihua Ma http://f2eskills.com/ <br/> <br/>set :stages, %w[staging production] <br/>set :default_stage, ‘staging’ <br/>require ‘capistrano/ext/multistage’ <br/>#application name <br/>set :application, “example” <br/>#start server script <br/>set :node_file, “app.js” <br/>#deploy host <br/>set :host, “hostname” <br/>#user name,must be a sudoer without prompting for password <br/>set :user, “username” <br/>set :admin_runner, user <br/> <br/> <br/>set :repository, “git@git@github.com:mashihua/Nodebot.git” <br/>set :scm, :git <br/>set :deploy_via, :remote_cache <br/>role :app, host <br/>set :use_sudo, true <br/> <br/>namespace :deploy do <br/>
<br/> desc “Start node server”
<br/> task :start, :roles => :app, :except => { :no_release => true } do
<br/> run “sudo start #{application}#{node_env}"
<br/> end
<br/>
<br/> desc “Stop node server”
<br/> task :stop, :roles => :app, :except => { :no_release => true } do
<br/> run "sudo stop #{application}#{node_env}”
<br/> end
<br/>
<br/> desc “Restart node server”
<br/> task :restart, :roles => :app, :except => { :no_release => true } do
<br/> run “sudo restart #{application}#{node_env} || sudo start #{application}#{node_env}”
<br/> end
<br/>
<br/> desc “Check required packages and install if packages are not installed”
<br/> task :check_packages, roles => :app do
<br/> run “cd #{release_path} && jake depends”
<br/> end
<br/>
<br/> task :create_deploy_to_with_sudo, :roles => :app do
<br/> run “sudo mkdir -p #{deploy_to}”
<br/> run “sudo chown #{admin_runner}:#{admin_runner} #{deploy_to}”
<br/> end
<br/>
<br/> desc “Update submodules”
<br/> task :update_submodules, :roles => :app do
<br/> run “cd #{release_path}; git submodule init && git submodule update”
<br/> end
<br/>
<br/> task :write_upstart_script, :roles => :app do
<br/> upstart_script = <> #{shared_path}/log/#{node_env}.log 2>&1"
<br/>end script
<br/>respawn
<br/>UPSTART
<br/>
<br/> put upstart_script, “/tmp/#{application}_upstart.conf”
<br/> run “sudo mv /tmp/#{application}upstart.conf /etc/init/#{application}#{node_env}.conf”
<br/> end
<br/>
<br/>end
<br/>
<br/>before ‘deploy:setup’, ‘deploy:create_deploy_to_with_sudo’
<br/>after ‘deploy:setup’, ‘deploy:write_upstart_script’
<br/>after “deploy:finalize_update”, “deploy:update_submodules”, “deploy:check_packages”
<br/></pre>
<br/>staging.rb环境文件看起来像这样。设定了应用的环境,git的branch,应用的监听端口和部署目录:
<br/><pre>set :node_env, “staging”
<br/>#git repos branch
<br/>set :branch, “master”
<br/>#listing port
<br/>set :application_port, “1603”
<br/>#deploy path
<br/>set :deploy_to, “/srv/www/apps/#{application}/#{node_env}”
<br/></pre>
<br/>production.rb环境文件看起来像这样:
<br/><pre>set :node_env, “production”
<br/>#git repos branch
<br/>set :branch, “production”
<br/>#listing port
<br/>set :application_port, “1604”
<br/>#deploy path
<br/>set :deploy_to, “/srv/www/apps/#{application}/#{node_env}”
<br/></pre>
<br/>
<br/><h3>主要命令:</h3>
<br/><ul>
<br/> <li>cap -T 查看所有的task</li>
<br/> <li>cap deploy:setup 设置staging环境,比如创建部署的目录等。staging是默认环境,命令等同于cap staging deploy:setup。调用production环境的命令cap production deploy:setup,第一个参数是环境名,第二个参数是任务名。</li>
<br/> <li>cap nodebot:setup 安装系统一些软件和配置守护进程。上面已经介绍过。</li>
<br/> <li>cap production deploy 部署 production环境的Node.js应用。包括从仓库取最新的代码,链接最新的代码到一个目录。重起应用的Server。</li>
<br/> <li>cap deploy:stop, cap deploy:start和cap deploy:restart 停止,启动和重起staging环境的Server。</li>
<br/></ul>
<br/><h3>简单的Node.js应用:</h3>
<br/>我们用一个简单的Node.js应用来说明实际的效果,应用的目录结构就像这样:
<br/><pre>.
<br/>├── Jakefile.js
<br/>├── app.js
<br/>├── config
<br/>│ └── requirements.json
<br/>└── log</pre>
<br/>
<br/>log 应用日志的输出目录
<br/>
<br/>app.js 就是应用的启动脚本
<br/><pre>var express = require(‘express’);
<br/>
<br/>var app = express.createServer();
<br/>
<br/>app.get(’/’, function(req, res){
<br/> //the log will out put to log/{node_env}.log
<br/> console.log(“Method:” + req.method);
<br/> //send text to agent
<br/> res.send(‘Hello World. NODE_ENV=’ + process.env.NODE_ENV);
<br/>});
<br/>
<br/>
<br/>//listening on application_port where set by capistrano
<br/>app.listen(process.argv[2] || 3000);
<br/></pre>
<br/>Jakefile.js jake构建工具调用的脚本,在本例子中用来安装express
<br/><pre>var fs = require(‘fs’);
<br/>
<br/>desc(‘Check and install required packages’);
<br/>task(‘depends’, [], function (arg) {
<br/> var npm = require(‘npm’);
<br/> npm.load({}, function (err) {
<br/> if (err) return commandFailed(err);
<br/> npm.on(“log”, function (message) { if(arg) console.log(message) })
<br/> var requirements = JSON.parse(fs.readFileSync(‘config/requirements.json’));
<br/> npm.commands.install(requirements, function (err, data) {
<br/> if (err) return commandFailed(err);
<br/> });
<br/> });
<br/>}, true);
<br/></pre>
<br/>config/requirements.json 应用依赖的定义
<br/><pre>[ “express@2.4.7”]</pre>
<br/>
<br/>实际部署的效果: <a href=“http://xiaoya.me:1603/”>staging环境</a>, <a href=“http://xiaoya.me:1604/”>production环境</a>
<br/><h2>结论:</h2>
<br/>使用<a href=“https://github.com/mashihua/Nodebot”>Nodebot</a>你可以轻松的部署你的Node.js应用。把你的焦点放到实际的需求中,而不用关心部署环境的建立和部署应用的麻烦,只许在部署客户端轻松的输入简单的命令。
部署Node.js的应用的更多相关文章
- 部署Node.js项目(CentOS)
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...
- 如何线上部署node.js项目
来源:http://blog.csdn.net/chenlinIT/article/details/73343793 前言 最近工作不是很忙,在空闲时间学习用node+express搭建自己的个人博客 ...
- 阿里云部署Node.js项目(CentOS)
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...
- 【转载】在Centos系统上采用二进制文件部署Node.js环境
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...
- 一种简单的生产环境部署Node.js程序方法
最近在部署Node.js程序时,写了段简单的脚本,发觉还挺简单的,忍不住想与大家分享. 配置文件 首先,本地测试环境和生产环境的数据库连接这些配置信息是不一样的,需要将其分开为两个文件存储 到conf ...
- Linux环境部署Node.js
介绍 先前在阿里云ECS上部署Node.js,碰到不少坑,都是自己不仔细造成的,所以准备再部署一遍,并记录下来.我将我的服务器重置了,这次选择的是CentOS 7.4 64位,上次的是7.2的. 使用 ...
- 【从零开始学习Node.js】一.在CentOS 7中部署Node.js环境
一.背景信息 Node.js是一个基于Chrome V8引擎的JavaScript运行环境,用来方便快速地搭建易于扩展的网络应用.Node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高效 ...
- 在Heroku上部署Node.js应用
最近在学习Node.js,想找一个可以免费部署Node的平台,于是便找到了Heroku 直接进入主题,接下来我们一步一步部署自己的Node应用. 步骤1: 注册一个免费的Heroku账号. 步骤2: ...
- CentOS 7部署Node.js+MongoDB:在VPS上从安装到Hello world
写好代码,花钱买了VPS,看着Charges一直上涨却无从下手?记一位新手司机从购买VPS到成功访问的过程 0.购买VPS 首先,选择VPS提供商,部署一个新的服务器(Deploy New Serve ...
随机推荐
- qt中执行 sql文件的方法
由于qt中没有原生的执行sql文件的方法.因此我们需要根据sql文件中的流的特点,将其分解成一个个语句单独执行. 1.首先通过Qfile读取sql文件 2.将sql文件中的内容通过“:”进行拆解 3. ...
- [J2EE]MyBatis HelloWorld
一.MyBatis简单介绍 iBatis是apche的一个开源项目.2010年迁移到google code后改名为MyBatis,2013年前已到github.MyBatis是一个基于java的持久层 ...
- java请求POST发送json格式请求
public static String upload(String url){ try { HttpClient httpclient = new DefaultHttpClient(); Http ...
- 把查询到结果合并放在一行 JOIN非union
select one.max,one.min,one.low sts,c.high ens,one.time from ( select a.max max,a.min min,b.low low,a ...
- python文件的编译
背景知识 pyc文件: .pyc 是一种二进制文件,是由 .py 文件经过编译后,生成一种byte code文件. .py 文件变成 .pyc 文件后,加载的速度有所提高,而且 .pyc 是一种跨平台 ...
- 日历类Calendar
在早期的JDK版本中,日期(Date)类附有两大功能:(1)允许用年.月.日.时.分.秒来解释日期:(2)允许对表示日期的字符串进行格式化和句法分析.在JDK1.1中提供了类Calendar来完成第一 ...
- XMLRPC 学习笔记(一)- Python 实现
参考文章: http://baike.baidu.com/view/643379.htm http://docs.python.org/2/library/xmlrpclib.html http:// ...
- 【BZOJ】3390: [Usaco2004 Dec]Bad Cowtractors牛的报复(kruskal)
http://www.lydsy.com/JudgeOnline/problem.php?id=3390 .. #include <cstdio> #include <cstring ...
- [转]SpecFlow使用入门
SpecFlow是一个BDD工具,在这里对BDD不多赘述,你可以阅读一下微软2010年十二月的一篇文章,此外如果你想要更多了解SpecFlow,可以参考我的另一篇翻译(当然,也可以直接进入官网) 一. ...
- herf 和 src 的区别
1.herf 表示超文本引用(hypertext reference),指向网络资源所在位置,建立和当前元素( 锚点)或当前文档(链接)之间的链接,如果我们在文档中添加 <link href=& ...