CNode

部署Node.js的应用

Mmashihua发布于15 年前最后回复9 年前9 回复29375 浏览0 收藏

最近Node.js很火,让很多的前端看到了可以直接从前端写到后端的希望。但是每次部署一个Node.js的应用却让前端苦恼不已。每次登陆服务器,用自己不熟悉的方式从版本控制仓库中拖下源代码,kill掉应用的进程,重起一个应用的守护进程。如果能够自动化的部署一个Node.js应用,而不需要去接触这些前端不太熟悉的Unix系统命令和管理。对于大家来说就是提升了生产力。Capistrano是一个强大的自动化部署工具,所以我们选用他来做自动化部署。并且我已经把做好了的一个部署脚本Nodebot提交到github上去,供大家参考。 首先我们需要一个环境,分为两个环境:部署客户端环境和服务器环境。 部署客户端系统需求: 你可以用任何系统了,系统只要具备下面的4个软件就可。 安装ruby。去http://www.ruby-lang.org/en/downloads/下载适合你系统的ruby版本。 安装rubygem。去http://rubyforge.org/projects/rubygems/下载最新版的RubyGems,解压后运行以下命令安装。 sudo ruby setup.rb 安装Capistrano和Capistrano-etx。运行以下的命令安装。sudo gem install capistrano capistrano-ext 这样你就拥有了在机器部署node.js应用的软件。然后你需要能够不使用密码直接登陆到服务器上。运行下面的命令: # Create a local ssh key ssh-keygen #Copy key to server cat ~/.ssh/id_rsa.pub | ssh user@domain.com "cat >> .ssh/authorized_keys" 这样你就可以不需要密码直接登陆到服务器。 服务器端系统需求: 当然要Unix一类的系统了,Nodebot需要具备upstart的系统(一个基于事件的守护进程管理系统)。虽然Node.js能跑在window上,但是那只适合开发环境,不适合生产环境。还要有下面的软件,你也可以下载Nodebot并在部署客户端运行命令cap  nodebot:setup 来自动化安装。 安装scm软件。比如git,svn或hg,取决于你的node.js应用源代码管理软件。 安装Node.js。没什么好说的,地球人都知道这是什么。 安装npm。Node.js的一个包管理软件 安装node-jake。一个javascript的代码构建工具,有点像make和rake。用来安装应用的依赖。 具备upstart的系统,比如Ubantu。来做应用的守护进程。参看 http://upstart.ubuntu.com/ 部署的登陆用户需要sudo权限,并且不需要提示输入密码。参考命令: #Add a sudoer sudo useradd -m foo #edit sudoer privilege sudo visudo 出现编辑器时,插入下面一行,foo就是你新建的用户: foo ALL=(ALL) NOPASSWD: ALL 然后在deploy.rb文件(下面会提到)里配置foo为部署用户。 部署客户端脚本 环境有了,那就要开工了。我们希望在服务器上的Node.js应用运行几个不同的环境:测试环境,开发环境,产品环境等。运行cap .命令会在当前的目录下产生一个文件和一个目录。在目录里有个deploy.rb,这是我们需要修改的文件。由于我们需要多个环境,所以我们引入了Capistrano-etx。 set :stages, %w[staging production] set :default_stage, 'staging' require 'capistrano/ext/multistage' 我们设定了两个环境:staging和production,默认是staging环境。我们再在config目录下建一个deploy目录,里面放的两个.rb文件对应不同的环境配置.最后部署环境的目录下是这样的一个结构: . ├── Capfile └── config ├── deploy │   ├── production.rb │   └── staging.rb ├── deploy.rb └── node.rb deploy.rb文件看起来像这样。你需要设定host, repository,user和admin_user : ## # Capistrano tasks for Ubantu. # # Author: Shihua Ma http://f2eskills.com/ set :stages, %w[staging production] set :default_stage, 'staging' require 'capistrano/ext/multistage' #application name set :application, "example" #start server script set :node_file, "app.js" #deploy host set :host, "hostname" #user name,must be a sudoer without prompting for password set :user, "username" set :admin_runner, user set :repository, "git@git@github.com:mashihua/Nodebot.git" set :scm, :git set :deploy_via, :remote_cache role :app, host set :use_sudo, true namespace :deploy do
desc "Start node server" task :start, :roles => :app, :except => { :no_release => true } do run "sudo start #{application}#{node_env}" end
desc "Stop node server" task :stop, :roles => :app, :except => { :no_release => true } do run "sudo stop #{application}
#{node_env}" end
desc "Restart node server" task :restart, :roles => :app, :except => { :no_release => true } do run "sudo restart #{application}#{node_env} || sudo start #{application}#{node_env}" end desc "Check required packages and install if packages are not installed" task :check_packages, roles => :app do run "cd #{release_path} && jake depends" end task :create_deploy_to_with_sudo, :roles => :app do run "sudo mkdir -p #{deploy_to}" run "sudo chown #{admin_runner}:#{admin_runner} #{deploy_to}" end desc "Update submodules" task :update_submodules, :roles => :app do run "cd #{release_path}; git submodule init && git submodule update" end
task :write_upstart_script, :roles => :app do upstart_script = <> #{shared_path}/log/#{node_env}.log 2>&1" end script respawn UPSTART put upstart_script, "/tmp/#{application}_upstart.conf" run "sudo mv /tmp/#{application}upstart.conf /etc/init/#{application}#{node_env}.conf" end end before 'deploy:setup', 'deploy:create_deploy_to_with_sudo' after 'deploy:setup', 'deploy:write_upstart_script' after "deploy:finalize_update", "deploy:update_submodules", "deploy:check_packages" staging.rb环境文件看起来像这样。设定了应用的环境,git的branch,应用的监听端口和部署目录: set :node_env, "staging" #git repos branch set :branch, "master" #listing port set :application_port, "1603" #deploy path set :deploy_to, "/srv/www/apps/#{application}/#{node_env}" production.rb环境文件看起来像这样: set :node_env, "production" #git repos branch set :branch, "production" #listing port set :application_port, "1604" #deploy path set :deploy_to, "/srv/www/apps/#{application}/#{node_env}"   主要命令: cap -T 查看所有的task cap deploy:setup   设置staging环境,比如创建部署的目录等。staging是默认环境,命令等同于cap staging deploy:setup。调用production环境的命令cap production deploy:setup,第一个参数是环境名,第二个参数是任务名。 cap nodebot:setup  安装系统一些软件和配置守护进程。上面已经介绍过。 cap production deploy   部署 production环境的Node.js应用。包括从仓库取最新的代码,链接最新的代码到一个目录。重起应用的Server。 cap deploy:stop, cap deploy:start和cap deploy:restart   停止,启动和重起staging环境的Server。 简单的Node.js应用: 我们用一个简单的Node.js应用来说明实际的效果,应用的目录结构就像这样: . ├── Jakefile.js ├── app.js ├── config │   └── requirements.json └── log log 应用日志的输出目录 app.js 就是应用的启动脚本 var express = require('express'); var app = express.createServer(); app.get('/', function(req, res){ //the log will out put to log/{node_env}.log console.log("Method:" + req.method); //send text to agent res.send('Hello World. NODE_ENV=' + process.env.NODE_ENV); }); //listening on application_port where set by capistrano app.listen(process.argv[2] || 3000); Jakefile.js jake构建工具调用的脚本,在本例子中用来安装express var fs = require('fs'); desc('Check and install required packages'); task('depends', [], function (arg) { var npm = require('npm'); npm.load({}, function (err) { if (err) return commandFailed(err); npm.on("log", function (message) { if(arg) console.log(message) }) var requirements = JSON.parse(fs.readFileSync('config/requirements.json')); npm.commands.install(requirements, function (err, data) { if (err) return commandFailed(err); }); }); }, true); config/requirements.json 应用依赖的定义 [ "express@2.4.7"] 实际部署的效果: staging环境, production环境 结论: 使用Nodebot你可以轻松的部署你的Node.js应用。把你的焦点放到实际的需求中,而不用关心部署环境的建立和部署应用的麻烦,只许在部署客户端轻松的输入简单的命令。

查看回复

回复 (9)

A
anonymous#1·15 年前

@mashihua 请问一下,我在编译的时候./configure显示缺少三个文件 Checking for header port.h : not found Checking for header ['sys/types.h', 'sys/event.h'] : not found Checking for function kqueue : not found 请问一下这个是什么原因呢?

A
anonymous#2·15 年前

是也乎,还是太复杂哪,依赖太多第3方工具,哪个工具不需要学习掌握的哪,,,

M
mashihua#3·15 年前

@cxzlhr , configure工具是检查依赖的工具,如果它显示'configure' finished successfully。就没有好担心的。除非你要用https,你需要安装libssl-dev。你说的这些缺失的是libev的依赖。比如kqueue是BSD-only的,其它的系统可能使用epoll。 @zjhiphop, 对不起,是我输入错了是capify . 社区给我的权限不让编辑我发布过的文章。

Z
zjhiphop#4·15 年前

我在ubuntu 11.04上测试之后,发现运行 'cap .'时候,会说‘the task `.' does not exist’,what's wrong?

M
mashihua#5·15 年前

@Zoom.Quiet, 下载Nodebot只需要配置客户端环境,修改host, repository,user,admin_user配置和服务器权限。

Z
zsea#7·9 年前

Docker

I
i5ting#8·11 年前

挖坟

A
a69694510#9·9 年前

支持

来自酷炫的 CNodeMD

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