<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/seanlou" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/seanlou" type="application/rss+xml"></fs:self_link><lastBuildDate>Thu, 03 Mar 2011 08:00:00 GMT</lastBuildDate><title>seanlou的博客</title><description>天道酬勤</description><link>http://saberma.me/</link><link xmlns="http://www.w3.org/2005/Atom" href="http://saberma.me/atom.xml" rel="self"></link><link xmlns="http://www.w3.org/2005/Atom" href="http://saberma.me/"></link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/</id><author xmlns="http://www.w3.org/2005/Atom"><name>saberma</name><email>mahb45@gmail.com</email></author><pubDate>Fri, 01 Apr 2011 13:22:29 GMT</pubDate><dc:creator>saberma</dc:creator><item><title>虚拟化开发环境</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565425/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/linux/2011/03/03/vagrant-virtual-develop-enviroment</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;ShopQi&lt;/a&gt; 中应用到的技术越来越多，开发环境的搭建变得越来越繁琐，这对开源项目的团队协作是相当不利的&lt;br /&gt;
试想，每个程序员的偏好都不同，所使用的操作系统，编辑器都是五花八门的，在开发过程中由于开发环境不一致出现问题的不在少数，调试难度也大&lt;/p&gt;
&lt;p&gt;所以，很多公司要求所有的开发机器不能随意安装软件，要保持开发环境高度一致&lt;br /&gt;
这种强制限制虽然让人感到不自由，但在公司做软件，也算情有可原&lt;/p&gt;
&lt;p&gt;而做开源项目就不同了，我们要尽可能提供便利，减少安装过程对原有环境的影响&lt;br /&gt;
要实现这一目标是非常困难的，还好，现在有了Vagrant&lt;/p&gt;
&lt;h2&gt;Vagrant&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/develop/vagrant.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Vargant是构建虚拟化开发环境的工具，它是用ruby开发的，并以gem方面发布，它会帮我们&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;创建一个Ubuntu10.04版本的32位VirtualBox虚拟机，并应用chef安装项目所需的ruby、数据库、应用服务器程序等&lt;/li&gt;
	&lt;li&gt;将宿主机项目所在的目录与虚拟机共享，我们在宿主机用喜欢的编辑器修改程序，虚拟机中的开发环境可以立即读取到&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样就可以保证项目组成员的开发环境是一致的,不一定是rails项目才适用,java php或其他的都是可以使用vagrant&lt;/p&gt;
&lt;p&gt;有时候,我们需要跟进开发多个项目,有的用java,有的用ruby,有的使用mysql,有的使用mongodb&lt;br /&gt;
把这些都装起来也没问题,但是有点浪费性能了,同一时间我们只会开发一个项目&lt;br /&gt;
用vagrant我们可以很好的解决这类问题,每个项目一个虚拟机,需要时才启动&lt;/p&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;p&gt;虚拟机的操作系统镜像文件是经过定制的，在vargant中引入的镜像文件称为&amp;quot;Box&amp;quot;&lt;br /&gt;
我们先下载这个镜像文件，地址如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://files.vagrantup.com/lucid32.box&quot;&gt;http://files.vagrantup.com/lucid32.box&lt;/a&gt;&lt;br /&gt;
假设下载后放至~/lucid32.box&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同时需要下载VirtualBox程序，并安装&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://www.virtualbox.org/wiki/Downloads&quot;&gt;http://www.virtualbox.org/wiki/Downloads&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;安装前请确保宿主机已经安装了ruby和rubygem&lt;/p&gt;
&lt;pre&gt;
gem install bundler vagrant --no-ri --no-rdoc&lt;/pre&gt;
&lt;h3&gt;创建虚拟机&lt;/h3&gt;
&lt;p&gt;先引入刚才下载的镜像文件，作为vagant管理下的一个box，以后每次要生成一个用于开发的虚拟机，都会从这个box中复制出来&lt;/p&gt;
&lt;pre&gt;
vagrant box add lucid32 ~/lucid32.box
#进入项目目录
cd ~/Documents/shopqi
#初始化，生成配置文件Vagrantfile
vagrant init lucid32
#生成项目虚拟机
vagrant up&lt;/pre&gt;
&lt;p&gt;等一会儿，一个ubuntu的虚拟机就建好了&lt;/p&gt;
&lt;h3&gt;在虚拟机上安装开发环境&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/vagrant/pstree.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;vagrant可以根据chef指定的cookbook recipe进行安装，关于chef的介绍可以参考 &lt;a href=&quot;/linux/2011/01/27/chef-for-automate-deploy.html&quot;&gt;应用chef构建服务器集群自动化部署与管理&lt;/a&gt;&lt;br /&gt;
这里采用的是不依赖chef服务器的chef-solo方式，recipe采用 &lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;ShopQi&lt;/a&gt; 服务器部署的cookbook&lt;br /&gt;
指定recipe，需要修改Vagrantfile，增加以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.vm.provision :chef_solo do |chef|&lt;br /&gt;
　chef.recipe_url = &amp;#8220;https://dl.dropbox.com/u/19519145/shopqi/chef-solo.tar.gz&amp;#8221;&lt;br /&gt;
　chef.add_recipe &amp;#8220;develop&amp;#8221;&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;chef-solo.tar.gz文件是包含cookbooks集合的压缩包&lt;/p&gt;
&lt;pre&gt;
#进入cookbooks所在目录后运行命令
tar zcvf chef-solo.tar.gz ./cookbooks&lt;/pre&gt;
&lt;p&gt;develop cookbook会引入开发机所需要的依赖recipe， &lt;a href=&quot;https://github.com/saberma/chef-repo/blob/master/cookbooks/develop/recipes/default.rb&quot;&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;启动虚拟机&lt;/h3&gt;
&lt;pre&gt;
vagrant up
#如果已经启动，只想更新或者调试recipe，运行vagrant provision&lt;/pre&gt;
&lt;p&gt;如果你和我一样,喜欢rvm来管理ruby版本,并安装了除system自带的ruby,则需要修改/etc/profile,否则gems会被安装在自带ruby之下&lt;br /&gt;
参考 &lt;a href=&quot;http://rvm.beginrescueend.com/integration/vagrant/&quot;&gt;http://rvm.beginrescueend.com/integration/vagrant/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;ssh登录虚拟机&lt;/h3&gt;
&lt;p&gt;之后，我们可以登录虚拟机，像以前一样执行rake等命令&lt;/p&gt;
&lt;pre&gt;
vagrant ssh
#查看项目目录，会发现与宿主机的当前目录内容一致
ls /vagrant&lt;/pre&gt;
&lt;p&gt;刚才引入的cookbook包含了nginx recipe，所以我们可以看看虚拟机上nginx是否能正常访问了&lt;/p&gt;
&lt;pre&gt;
wget -qO- 127.0.0.1:3000&lt;/pre&gt;
&lt;p&gt;結果返回:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body bgcolor=&quot;white&quot; text=&quot;black&quot;&amp;gt;
&amp;lt;center&amp;gt;&amp;lt;h1&amp;gt;Welcome to nginx!&amp;lt;/h1&amp;gt;&amp;lt;/center&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;p&gt;说明能正常访问，为了能在宿主机上用浏览器访问它，我们需要进行端口映射&lt;br /&gt;
修改VagrantFile，加入以下内容:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vagrant::Config.run do |config|&lt;br /&gt;
　# Forward guest port 3000 to host port 8088 and name the mapping &amp;#8220;web&amp;#8221;&lt;br /&gt;
　config.vm.forward_port(&amp;#8220;web&amp;#8221;, 3000, 8088)&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用浏览器打开 &lt;a href=&quot;http://127.0.0.1:8088&quot;&gt;http://127.0.0.1:8088&lt;/a&gt; 就可以访问了&lt;/p&gt;
&lt;h3&gt;打包发布&lt;/h3&gt;
&lt;p&gt;现在开发环境已经安装好了，整个过程非常高效。更进一步，我们可以把已经做好的环境打包成镜像文件，分发给其他人，他们就可以瞬间建好开发环境了。&lt;/p&gt;
&lt;p&gt;准备pkg文件,此文件只用于定义映射端口,会被合并至Vagrantfile文件中,内容一般为&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vagrant::Config.run do |config|&lt;br /&gt;
  #Forward nginx&lt;br /&gt;
  config.vm.forward_port(&amp;#8220;web&amp;#8221;, 3000, 8088)&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
#执行打包
vagrant package --vagrantfile Vagrantfile.pkg&lt;/pre&gt;
&lt;p&gt;执行后当前目录会生成package.box文件&lt;/p&gt;
&lt;h3&gt;关闭虚拟机&lt;/h3&gt;
&lt;pre&gt;
vagrant halt&lt;/pre&gt;
&lt;h2&gt;测试&lt;/h2&gt;
&lt;h3&gt;单元测试&lt;/h3&gt;
&lt;p&gt;还是跟以前一样&lt;/p&gt;
&lt;h3&gt;验收测试&lt;/h3&gt;
&lt;p&gt;由于cucumber使用的@javascript，需要打开浏览器测试ajax。而虚拟机并未安装桌面，此测试进行不了。&lt;br /&gt;
开源社区中有不少技术可以进行headless后台测试，但都不成熟.&lt;/p&gt;
&lt;p&gt;所以,我们只能在宿主机上进行这样的测试了,这样的话,宿主机又要安装项目的相关插件,这可不少.&lt;br /&gt;
有什么办法能让插件跟着项目跑,而不把插件安装到系统上呢?&lt;/p&gt;
&lt;p&gt;答案是可以的,我们在虚拟机上使用bundle install安装插件的时候,指定参数&amp;#8212;path vendor/bundle，将插件安装在项目的vendor/bundle目录，这样在宿主机就不用再安装这些插件了。&lt;br /&gt;
还有,我们的测试数据库还在虚拟机上,还得修改 &lt;code&gt;Vagrantfile&lt;/code&gt; ,把mongodb,redis-server,nodejs等服务的端口映射至宿主机&lt;br /&gt;
直接在宿主机上运行以下命令就可以测试了&lt;/p&gt;
&lt;pre&gt;
bundle exec cucumber features&lt;/pre&gt;
&lt;p&gt;注意:将gems打包后,会导致在虚拟机运行rails各种命令时,速度巨慢,原因是virtaulbox共享目录的bug:随着目录内文件数的增长,对共享目录的访问会很慢&lt;br /&gt;
解决方案是应用nfs共享目录,具体查看这里 &lt;a href=&quot;http://vagrantup.com/docs/nfs.html&quot;&gt;http://vagrantup.com/docs/nfs.html&lt;/a&gt; 和 &lt;a href=&quot;http://vagrantup.com/docs/host_only_networking.html&quot;&gt;http://vagrantup.com/docs/host_only_networking.html&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;
#宿主机需要安装nfs服务
sudo apt-get install nfs-kernel-server&lt;/pre&gt;
&lt;h3&gt;进入rails控制器&lt;/h3&gt;
&lt;p&gt;经过上面的处理,插件已经安装好了,但是由于rails并未安装进系统,使用以下命令是进不了控制台的&lt;/p&gt;
&lt;pre&gt;
rails c&lt;/pre&gt;
&lt;p&gt;得在项目目录下,运行&lt;/p&gt;
&lt;pre&gt;
script/rails c&lt;/pre&gt;
&lt;h2&gt;报错&lt;/h2&gt;
&lt;h3&gt;找不到client.pem&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[default] I cannot read /etc/chef/client.pem, which you told me to use to sign requests!: stderr&lt;br /&gt;
[default]  (: stderr&lt;br /&gt;
[default] Chef::Exceptions::PrivateKeyMissing: stderr&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也太奇怪了，用的是chef-solo方式，而非chef-server，怎么也需要client.pem?&lt;br /&gt;
原来是部分cookbook使用了search方法，此方法用于从chef-server中查找相应的信息&lt;/p&gt;
&lt;p&gt;解决方法是在cookbook中加入判断条件，开发环境部署时不调用search，生产环境才调用&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;node[:instance_role]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&amp;#8216;unknown&amp;#8217;: unknown terminal type.&lt;/h3&gt;
&lt;p&gt;很不幸，这是vagrant的一个bug，详情参考 &lt;a href=&quot;https://github.com/mitchellh/vagrant/commit/77a1b9a6efe4f5cdc99343e844835fc790a64c28&quot;&gt;commit#77a1b9a6efe4f5cdc993&lt;/a&gt;&lt;br /&gt;
解决方法，更新vagrant至0.7.3，不过，这个版本还没有发布，只能先手动修改本地gem的代码了&lt;/p&gt;
&lt;h3&gt;&lt;span class=&quot;caps&quot;&gt;FATAL&lt;/span&gt;: No cookbook found in [&amp;#8220;/tmp/vagrant-chef/cookbooks-0&amp;#8221;, &amp;#8220;/tmp/vagrant-chef/cookbooks&amp;#8221;], make sure cookbook_path is set correctly.&lt;/h3&gt;
&lt;p&gt;这是vagrant的一个bug,详情请看&lt;br /&gt;
&lt;a href=&quot;https://github.com/mitchellh/vagrant/issues#issue/308&quot;&gt;https://github.com/mitchellh/vagrant/issues#issue/308&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/mitchellh/vagrant/issues/closed#issue/297&quot;&gt;https://github.com/mitchellh/vagrant/issues/closed#issue/297&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;不影响使用,作者正在修复&amp;#8230;&lt;/p&gt;
&lt;h3&gt;运行chef-solo过程的其他错误?&lt;/h3&gt;
&lt;pre&gt;
#登录虚拟机
vagrant ssh
#在虚拟机运行chef-solo,显示更显示的debug信息
cd /tmp/vagrant-chef
sudo chef-solo -c solo.rb -j dna.json -l debug&lt;/pre&gt;
&lt;p&gt;如果希望vagrant命令运行时都显示详细信息,可以配置Vagrantfile&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.vm.provision :chef_solo do |chef|&lt;br /&gt;
　chef.log_level = :debug&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant官网&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://vagrantup.com/docs/provisioners/chef_solo.html&quot;&gt;chef_solo配置&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://tickets.opscode.com/browse/CHEF-1115&quot;&gt;client.pem error&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/fnichol/wiki-notes/wiki/Creating-An-Ubuntu-10.10-x32-Vagrant-Box&quot;&gt;Creating An Ubuntu 10.10 x32 Vagrant Box&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://wiki.csinitiative.com/display/tri/Setting+up+a+Vagrant+VM+for+TriSano&quot;&gt;Setting up a Vagrant VM for TriSano&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Vagrant&quot;&gt;opscode vagrant&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;ShopQi&lt;/a&gt; 中应用到的技术越来越多，开发环境的搭建变得越来越繁琐，这对开源项目的团队协作是相当不利的&lt;br /&gt;
试想，每个程序员的偏好都不同，所使用的操作系统，编辑器都是五花八门的，在开发过程中由于开发环境不一致出现问题的不在少数，调试难度也大&lt;/p&gt;
&lt;p&gt;所以，很多公司要求所有的开发机器不能随意安装软件，要保持开发环境高度一致&lt;br /&gt;
这种强制限制虽然让人感到不自由，但在公司做软件，也算情有可原&lt;/p&gt;
&lt;p&gt;而做开源项目就不同了，我们要尽可能提供便利，减少安装过程对原有环境的影响&lt;br /&gt;
要实现这一目标是非常困难的，还好，现在有了Vagrant&lt;/p&gt;
&lt;h2&gt;Vagrant&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/develop/vagrant.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Vargant是构建虚拟化开发环境的工具，它是用ruby开发的，并以gem方面发布，它会帮我们&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;创建一个Ubuntu10.04版本的32位VirtualBox虚拟机，并应用chef安装项目所需的ruby、数据库、应用服务器程序等&lt;/li&gt;
	&lt;li&gt;将宿主机项目所在的目录与虚拟机共享，我们在宿主机用喜欢的编辑器修改程序，虚拟机中的开发环境可以立即读取到&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样就可以保证项目组成员的开发环境是一致的,不一定是rails项目才适用,java php或其他的都是可以使用vagrant&lt;/p&gt;
&lt;p&gt;有时候,我们需要跟进开发多个项目,有的用java,有的用ruby,有的使用mysql,有的使用mongodb&lt;br /&gt;
把这些都装起来也没问题,但是有点浪费性能了,同一时间我们只会开发一个项目&lt;br /&gt;
用vagrant我们可以很好的解决这类问题,每个项目一个虚拟机,需要时才启动&lt;/p&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;p&gt;虚拟机的操作系统镜像文件是经过定制的，在vargant中引入的镜像文件称为&amp;quot;Box&amp;quot;&lt;br /&gt;
我们先下载这个镜像文件，地址如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://files.vagrantup.com/lucid32.box&quot;&gt;http://files.vagrantup.com/lucid32.box&lt;/a&gt;&lt;br /&gt;
假设下载后放至~/lucid32.box&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同时需要下载VirtualBox程序，并安装&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://www.virtualbox.org/wiki/Downloads&quot;&gt;http://www.virtualbox.org/wiki/Downloads&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;安装前请确保宿主机已经安装了ruby和rubygem&lt;/p&gt;
&lt;pre&gt;
gem install bundler vagrant --no-ri --no-rdoc&lt;/pre&gt;
&lt;h3&gt;创建虚拟机&lt;/h3&gt;
&lt;p&gt;先引入刚才下载的镜像文件，作为vagant管理下的一个box，以后每次要生成一个用于开发的虚拟机，都会从这个box中复制出来&lt;/p&gt;
&lt;pre&gt;
vagrant box add lucid32 ~/lucid32.box
#进入项目目录
cd ~/Documents/shopqi
#初始化，生成配置文件Vagrantfile
vagrant init lucid32
#生成项目虚拟机
vagrant up&lt;/pre&gt;
&lt;p&gt;等一会儿，一个ubuntu的虚拟机就建好了&lt;/p&gt;
&lt;h3&gt;在虚拟机上安装开发环境&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/vagrant/pstree.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;vagrant可以根据chef指定的cookbook recipe进行安装，关于chef的介绍可以参考 &lt;a href=&quot;/linux/2011/01/27/chef-for-automate-deploy.html&quot;&gt;应用chef构建服务器集群自动化部署与管理&lt;/a&gt;&lt;br /&gt;
这里采用的是不依赖chef服务器的chef-solo方式，recipe采用 &lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;ShopQi&lt;/a&gt; 服务器部署的cookbook&lt;br /&gt;
指定recipe，需要修改Vagrantfile，增加以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.vm.provision :chef_solo do |chef|&lt;br /&gt;
　chef.recipe_url = &amp;#8220;https://dl.dropbox.com/u/19519145/shopqi/chef-solo.tar.gz&amp;#8221;&lt;br /&gt;
　chef.add_recipe &amp;#8220;develop&amp;#8221;&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;chef-solo.tar.gz文件是包含cookbooks集合的压缩包&lt;/p&gt;
&lt;pre&gt;
#进入cookbooks所在目录后运行命令
tar zcvf chef-solo.tar.gz ./cookbooks&lt;/pre&gt;
&lt;p&gt;develop cookbook会引入开发机所需要的依赖recipe， &lt;a href=&quot;https://github.com/saberma/chef-repo/blob/master/cookbooks/develop/recipes/default.rb&quot;&gt;查看内容&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;启动虚拟机&lt;/h3&gt;
&lt;pre&gt;
vagrant up
#如果已经启动，只想更新或者调试recipe，运行vagrant provision&lt;/pre&gt;
&lt;p&gt;如果你和我一样,喜欢rvm来管理ruby版本,并安装了除system自带的ruby,则需要修改/etc/profile,否则gems会被安装在自带ruby之下&lt;br /&gt;
参考 &lt;a href=&quot;http://rvm.beginrescueend.com/integration/vagrant/&quot;&gt;http://rvm.beginrescueend.com/integration/vagrant/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;ssh登录虚拟机&lt;/h3&gt;
&lt;p&gt;之后，我们可以登录虚拟机，像以前一样执行rake等命令&lt;/p&gt;
&lt;pre&gt;
vagrant ssh
#查看项目目录，会发现与宿主机的当前目录内容一致
ls /vagrant&lt;/pre&gt;
&lt;p&gt;刚才引入的cookbook包含了nginx recipe，所以我们可以看看虚拟机上nginx是否能正常访问了&lt;/p&gt;
&lt;pre&gt;
wget -qO- 127.0.0.1:3000&lt;/pre&gt;
&lt;p&gt;結果返回:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body bgcolor=&quot;white&quot; text=&quot;black&quot;&amp;gt;
&amp;lt;center&amp;gt;&amp;lt;h1&amp;gt;Welcome to nginx!&amp;lt;/h1&amp;gt;&amp;lt;/center&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;p&gt;说明能正常访问，为了能在宿主机上用浏览器访问它，我们需要进行端口映射&lt;br /&gt;
修改VagrantFile，加入以下内容:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vagrant::Config.run do |config|&lt;br /&gt;
　# Forward guest port 3000 to host port 8088 and name the mapping &amp;#8220;web&amp;#8221;&lt;br /&gt;
　config.vm.forward_port(&amp;#8220;web&amp;#8221;, 3000, 8088)&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用浏览器打开 &lt;a href=&quot;http://127.0.0.1:8088&quot;&gt;http://127.0.0.1:8088&lt;/a&gt; 就可以访问了&lt;/p&gt;
&lt;h3&gt;打包发布&lt;/h3&gt;
&lt;p&gt;现在开发环境已经安装好了，整个过程非常高效。更进一步，我们可以把已经做好的环境打包成镜像文件，分发给其他人，他们就可以瞬间建好开发环境了。&lt;/p&gt;
&lt;p&gt;准备pkg文件,此文件只用于定义映射端口,会被合并至Vagrantfile文件中,内容一般为&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vagrant::Config.run do |config|&lt;br /&gt;
  #Forward nginx&lt;br /&gt;
  config.vm.forward_port(&amp;#8220;web&amp;#8221;, 3000, 8088)&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
#执行打包
vagrant package --vagrantfile Vagrantfile.pkg&lt;/pre&gt;
&lt;p&gt;执行后当前目录会生成package.box文件&lt;/p&gt;
&lt;h3&gt;关闭虚拟机&lt;/h3&gt;
&lt;pre&gt;
vagrant halt&lt;/pre&gt;
&lt;h2&gt;测试&lt;/h2&gt;
&lt;h3&gt;单元测试&lt;/h3&gt;
&lt;p&gt;还是跟以前一样&lt;/p&gt;
&lt;h3&gt;验收测试&lt;/h3&gt;
&lt;p&gt;由于cucumber使用的@javascript，需要打开浏览器测试ajax。而虚拟机并未安装桌面，此测试进行不了。&lt;br /&gt;
开源社区中有不少技术可以进行headless后台测试，但都不成熟.&lt;/p&gt;
&lt;p&gt;所以,我们只能在宿主机上进行这样的测试了,这样的话,宿主机又要安装项目的相关插件,这可不少.&lt;br /&gt;
有什么办法能让插件跟着项目跑,而不把插件安装到系统上呢?&lt;/p&gt;
&lt;p&gt;答案是可以的,我们在虚拟机上使用bundle install安装插件的时候,指定参数&amp;#8212;path vendor/bundle，将插件安装在项目的vendor/bundle目录，这样在宿主机就不用再安装这些插件了。&lt;br /&gt;
还有,我们的测试数据库还在虚拟机上,还得修改 &lt;code&gt;Vagrantfile&lt;/code&gt; ,把mongodb,redis-server,nodejs等服务的端口映射至宿主机&lt;br /&gt;
直接在宿主机上运行以下命令就可以测试了&lt;/p&gt;
&lt;pre&gt;
bundle exec cucumber features&lt;/pre&gt;
&lt;p&gt;注意:将gems打包后,会导致在虚拟机运行rails各种命令时,速度巨慢,原因是virtaulbox共享目录的bug:随着目录内文件数的增长,对共享目录的访问会很慢&lt;br /&gt;
解决方案是应用nfs共享目录,具体查看这里 &lt;a href=&quot;http://vagrantup.com/docs/nfs.html&quot;&gt;http://vagrantup.com/docs/nfs.html&lt;/a&gt; 和 &lt;a href=&quot;http://vagrantup.com/docs/host_only_networking.html&quot;&gt;http://vagrantup.com/docs/host_only_networking.html&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;
#宿主机需要安装nfs服务
sudo apt-get install nfs-kernel-server&lt;/pre&gt;
&lt;h3&gt;进入rails控制器&lt;/h3&gt;
&lt;p&gt;经过上面的处理,插件已经安装好了,但是由于rails并未安装进系统,使用以下命令是进不了控制台的&lt;/p&gt;
&lt;pre&gt;
rails c&lt;/pre&gt;
&lt;p&gt;得在项目目录下,运行&lt;/p&gt;
&lt;pre&gt;
script/rails c&lt;/pre&gt;
&lt;h2&gt;报错&lt;/h2&gt;
&lt;h3&gt;找不到client.pem&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[default] I cannot read /etc/chef/client.pem, which you told me to use to sign requests!: stderr&lt;br /&gt;
[default]  (: stderr&lt;br /&gt;
[default] Chef::Exceptions::PrivateKeyMissing: stderr&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也太奇怪了，用的是chef-solo方式，而非chef-server，怎么也需要client.pem?&lt;br /&gt;
原来是部分cookbook使用了search方法，此方法用于从chef-server中查找相应的信息&lt;/p&gt;
&lt;p&gt;解决方法是在cookbook中加入判断条件，开发环境部署时不调用search，生产环境才调用&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;node[:instance_role]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&amp;#8216;unknown&amp;#8217;: unknown terminal type.&lt;/h3&gt;
&lt;p&gt;很不幸，这是vagrant的一个bug，详情参考 &lt;a href=&quot;https://github.com/mitchellh/vagrant/commit/77a1b9a6efe4f5cdc99343e844835fc790a64c28&quot;&gt;commit#77a1b9a6efe4f5cdc993&lt;/a&gt;&lt;br /&gt;
解决方法，更新vagrant至0.7.3，不过，这个版本还没有发布，只能先手动修改本地gem的代码了&lt;/p&gt;
&lt;h3&gt;&lt;span class=&quot;caps&quot;&gt;FATAL&lt;/span&gt;: No cookbook found in [&amp;#8220;/tmp/vagrant-chef/cookbooks-0&amp;#8221;, &amp;#8220;/tmp/vagrant-chef/cookbooks&amp;#8221;], make sure cookbook_path is set correctly.&lt;/h3&gt;
&lt;p&gt;这是vagrant的一个bug,详情请看&lt;br /&gt;
&lt;a href=&quot;https://github.com/mitchellh/vagrant/issues#issue/308&quot;&gt;https://github.com/mitchellh/vagrant/issues#issue/308&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/mitchellh/vagrant/issues/closed#issue/297&quot;&gt;https://github.com/mitchellh/vagrant/issues/closed#issue/297&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;不影响使用,作者正在修复&amp;#8230;&lt;/p&gt;
&lt;h3&gt;运行chef-solo过程的其他错误?&lt;/h3&gt;
&lt;pre&gt;
#登录虚拟机
vagrant ssh
#在虚拟机运行chef-solo,显示更显示的debug信息
cd /tmp/vagrant-chef
sudo chef-solo -c solo.rb -j dna.json -l debug&lt;/pre&gt;
&lt;p&gt;如果希望vagrant命令运行时都显示详细信息,可以配置Vagrantfile&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.vm.provision :chef_solo do |chef|&lt;br /&gt;
　chef.log_level = :debug&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant官网&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://vagrantup.com/docs/provisioners/chef_solo.html&quot;&gt;chef_solo配置&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://tickets.opscode.com/browse/CHEF-1115&quot;&gt;client.pem error&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/fnichol/wiki-notes/wiki/Creating-An-Ubuntu-10.10-x32-Vagrant-Box&quot;&gt;Creating An Ubuntu 10.10 x32 Vagrant Box&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://wiki.csinitiative.com/display/tri/Setting+up+a+Vagrant+VM+for+TriSano&quot;&gt;Setting up a Vagrant VM for TriSano&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Vagrant&quot;&gt;opscode vagrant&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565425/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565425/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565425/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565425/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/linux/2011/03/03/vagrant-virtual-develop-enviroment.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565425/6499449</fs:itemid><pubDate>Thu, 03 Mar 2011 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/linux/2011/03/03/vagrant-virtual-develop-enviroment</guid></item><item><title>我的Ubuntu</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565426/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/linux/2011/02/24/my-ubuntu</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;我安装的Ubuntu版本是10.04，代号Lucid，32位，以下为安装后的配置过程&lt;/p&gt;
&lt;h2&gt;安装升级&lt;/h2&gt;
&lt;h3&gt;基本安装&lt;/h3&gt;
&lt;pre&gt;
#换源，试来试去，还是台湾的源最快
sudo wget https://gist.github.com/raw/352828/ca1d292be9a10fe01b7e0b72d65a74b781683311/sources.list -O /etc/apt/sources.list
sudo apt-get update
sudo apt-get upgrade
#ibus输入法，比Fcitx好用
sudo add-apt-repository ppa:shawn-p-huang/ppa 
sudo apt-get update
sudo apt-get install ibus-gtk ibus-pinyin ibus-pinyin-db-open-phrase ibus-table-wubi
im-switch -s ibus
#chrome浏览器
sudo apt-get install chromium-browser&lt;/pre&gt;
&lt;h3&gt;开发安装&lt;/h3&gt;
&lt;p&gt;虽然我已经把项目移至虚拟化开发环境中，但有些小项目还是需要在宿主机开发的，所以本地的基础开发环境还是要建立，而像mongodb、redis、nginx这些就不要再安装了，通通移至虚拟机&lt;/p&gt;
&lt;pre&gt;
#git
sudo apt-get install git-core openssl
#rvm
bash &amp;lt; &amp;lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
rvm install 1.9.2
rvm 1.9.2 --default
#or sometimes we will get:no such file to load -- openssl (LoadError)
cd ~/.rvm/src/ruby-1.9.2-*/ext/openssl
ruby extconf.rb
make &amp;amp;&amp;amp; make install
#irb should support readline. rmagick need.
sudo apt-get install ncurses-dev libreadline6 libreadline-dev graphicsmagick libmagick9-dev
cd ~/.rvm/src/ruby-1.9.2-*/ext/readline
ruby extconf.rb
make &amp;amp;&amp;amp; make install
#vim编辑神器
sudo apt-get install vim vim-ruby&lt;/pre&gt;
&lt;h2&gt;基本配置&lt;/h2&gt;
&lt;h3&gt;关闭特效&lt;/h3&gt;
&lt;p&gt;用于开发的机子当然是性能优先了&lt;/p&gt;
&lt;p&gt;右击桌面-[Change Desktop BackGround]-[Visual Effects]&lt;br /&gt;
选中[None]&lt;/p&gt;
&lt;h3&gt;自动隐藏任务栏&lt;/h3&gt;
&lt;p&gt;自动隐藏顶端及底端的任务栏，使浏览器及编辑器的窗口可显示的空间最大化&lt;/p&gt;
&lt;p&gt;右击任务栏-[Properties]-[General]&lt;br /&gt;
选中[Autohide]&lt;/p&gt;
&lt;h3&gt;自动记忆&lt;/h3&gt;
&lt;p&gt;关机时已经打开了哪些程序（浏览器、包括terminal中的各个tab），重新开机后会自动打开。&lt;br /&gt;
[System]-[Perferences]-[Startup Applications]-[Options]&lt;br /&gt;
勾选[Automatically remember running applications when logging out]&lt;/p&gt;
&lt;p&gt;顺便把[Startup Programs]中不需要开机启动的程序关闭掉，如Bluetooth Manager&lt;/p&gt;
&lt;h2&gt;Shell&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/ubuntu/zsh.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;安装终极Shell zsh，拥有更强的补全功能(常用工具的参数补全)&lt;/p&gt;
&lt;pre&gt;
sudo apt-get install zsh
#引入增强插件,支持git,rails等补全，可选多种外观皮肤
wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
#zsh作为默认shell，重启后生效
chsh -s /bin/zsh&lt;/pre&gt;
&lt;p&gt;修改zsh配置，定义需要引入的插件，修改 &lt;code&gt;~/.zshrc&lt;/code&gt; 的plugins值为:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;plugins=(command-not-found git rails ruby vagrant)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/wiki/themes&quot;&gt;zsh外观皮肤大全&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins&quot;&gt;zsh插件大全&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;具体有哪些补全功能呢，可以查看列表&lt;/p&gt;
&lt;pre&gt;
#-h不列出文件名
grep -h -r -e '^alias' ~/.oh-my-zsh&lt;/pre&gt;
&lt;h2&gt;浏览器&lt;/h2&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.ubuntu.org.cn/Qref/Source&quot;&gt;Ubuntu中文wiki&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/ibus/wiki/Ubuntu&quot;&gt;Ibus install&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;p&gt;我安装的Ubuntu版本是10.04，代号Lucid，32位，以下为安装后的配置过程&lt;/p&gt;
&lt;h2&gt;安装升级&lt;/h2&gt;
&lt;h3&gt;基本安装&lt;/h3&gt;
&lt;pre&gt;
#换源，试来试去，还是台湾的源最快
sudo wget https://gist.github.com/raw/352828/ca1d292be9a10fe01b7e0b72d65a74b781683311/sources.list -O /etc/apt/sources.list
sudo apt-get update
sudo apt-get upgrade
#ibus输入法，比Fcitx好用
sudo add-apt-repository ppa:shawn-p-huang/ppa 
sudo apt-get update
sudo apt-get install ibus-gtk ibus-pinyin ibus-pinyin-db-open-phrase ibus-table-wubi
im-switch -s ibus
#chrome浏览器
sudo apt-get install chromium-browser&lt;/pre&gt;
&lt;h3&gt;开发安装&lt;/h3&gt;
&lt;p&gt;虽然我已经把项目移至虚拟化开发环境中，但有些小项目还是需要在宿主机开发的，所以本地的基础开发环境还是要建立，而像mongodb、redis、nginx这些就不要再安装了，通通移至虚拟机&lt;/p&gt;
&lt;pre&gt;
#git
sudo apt-get install git-core openssl
#rvm
bash &amp;lt; &amp;lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
rvm install 1.9.2
rvm 1.9.2 --default
#or sometimes we will get:no such file to load -- openssl (LoadError)
cd ~/.rvm/src/ruby-1.9.2-*/ext/openssl
ruby extconf.rb
make &amp;amp;&amp;amp; make install
#irb should support readline. rmagick need.
sudo apt-get install ncurses-dev libreadline6 libreadline-dev graphicsmagick libmagick9-dev
cd ~/.rvm/src/ruby-1.9.2-*/ext/readline
ruby extconf.rb
make &amp;amp;&amp;amp; make install
#vim编辑神器
sudo apt-get install vim vim-ruby&lt;/pre&gt;
&lt;h2&gt;基本配置&lt;/h2&gt;
&lt;h3&gt;关闭特效&lt;/h3&gt;
&lt;p&gt;用于开发的机子当然是性能优先了&lt;/p&gt;
&lt;p&gt;右击桌面-[Change Desktop BackGround]-[Visual Effects]&lt;br /&gt;
选中[None]&lt;/p&gt;
&lt;h3&gt;自动隐藏任务栏&lt;/h3&gt;
&lt;p&gt;自动隐藏顶端及底端的任务栏，使浏览器及编辑器的窗口可显示的空间最大化&lt;/p&gt;
&lt;p&gt;右击任务栏-[Properties]-[General]&lt;br /&gt;
选中[Autohide]&lt;/p&gt;
&lt;h3&gt;自动记忆&lt;/h3&gt;
&lt;p&gt;关机时已经打开了哪些程序（浏览器、包括terminal中的各个tab），重新开机后会自动打开。&lt;br /&gt;
[System]-[Perferences]-[Startup Applications]-[Options]&lt;br /&gt;
勾选[Automatically remember running applications when logging out]&lt;/p&gt;
&lt;p&gt;顺便把[Startup Programs]中不需要开机启动的程序关闭掉，如Bluetooth Manager&lt;/p&gt;
&lt;h2&gt;Shell&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/ubuntu/zsh.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;安装终极Shell zsh，拥有更强的补全功能(常用工具的参数补全)&lt;/p&gt;
&lt;pre&gt;
sudo apt-get install zsh
#引入增强插件,支持git,rails等补全，可选多种外观皮肤
wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
#zsh作为默认shell，重启后生效
chsh -s /bin/zsh&lt;/pre&gt;
&lt;p&gt;修改zsh配置，定义需要引入的插件，修改 &lt;code&gt;~/.zshrc&lt;/code&gt; 的plugins值为:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;plugins=(command-not-found git rails ruby vagrant)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/wiki/themes&quot;&gt;zsh外观皮肤大全&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins&quot;&gt;zsh插件大全&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;具体有哪些补全功能呢，可以查看列表&lt;/p&gt;
&lt;pre&gt;
#-h不列出文件名
grep -h -r -e '^alias' ~/.oh-my-zsh&lt;/pre&gt;
&lt;h2&gt;浏览器&lt;/h2&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.ubuntu.org.cn/Qref/Source&quot;&gt;Ubuntu中文wiki&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/ibus/wiki/Ubuntu&quot;&gt;Ibus install&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565426/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565426/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565426/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565426/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/linux/2011/02/24/my-ubuntu.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565426/6499449</fs:itemid><pubDate>Thu, 24 Feb 2011 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/linux/2011/02/24/my-ubuntu</guid></item><item><title>应用chef安装openvpn</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565427/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/linux/2011/02/13/use-chef-to-install-openvpn-in-burst-vps</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;h2&gt;burst vps&lt;/h2&gt;
&lt;p&gt;之前买了burst的vps，现在准备为它安装openvpn&lt;br /&gt;
使用openvpn需要先登录后台管理 &lt;a href=&quot;https://184.82.225.10:2408&quot;&gt;https://184.82.225.10:2408/index.php&lt;/a&gt;&lt;br /&gt;
在Networking &amp;amp; Utilities 启用 Enable Tun/Tap&lt;/p&gt;
&lt;h2&gt;安装openvpn&lt;/h2&gt;
&lt;p&gt;假设vps ip为188.188.188.188&lt;br /&gt;
ssh密码为123456&lt;/p&gt;
&lt;p&gt;把这台vps当成vpn服务器，实现无障碍访问互联网&lt;/p&gt;
&lt;pre&gt;
export EDITOR=vim
knife role create vpn&lt;/pre&gt;
&lt;p&gt;knife会打开vim，将内容修改为:&lt;/p&gt;
&lt;pre&gt;
{
  &quot;name&quot;: &quot;vpn&quot;,
  &quot;description&quot;: &quot;openvpn server&quot;,
  &quot;json_class&quot;: &quot;Chef::Role&quot;,
  &quot;default_attributes&quot;: {
    &quot;chef&quot;: {
      &quot;server_url&quot;: &quot;https://api.opscode.com/organizations/#{YOUR COMPANY!}&quot;,
      &quot;cache_path&quot;: &quot;/var/chef/cache&quot;,
      &quot;backup_path&quot;: &quot;/var/chef/backup&quot;,
      &quot;validation_client_name&quot;: &quot;#{YOUR COMPANY!}-validator&quot;,
      &quot;run_path&quot;: &quot;/var/chef&quot;
    }
  },
  &quot;override_attributes&quot;: {
  },
  &quot;chef_type&quot;: &quot;role&quot;,
  &quot;run_list&quot;: [
    &quot;recipe[openvpn::default]&quot;
  ]
}&lt;/pre&gt;
&lt;p&gt;修改完后退出vim，会提示已经&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Created (or updated) role[vpn]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;下载相应的cookbook&lt;/p&gt;
&lt;pre&gt;
#此命令最常用
knife cookbook site vendor openvpn&lt;/pre&gt;
&lt;p&gt;远程生成服务端的keys，以下命令在本地执行&lt;br /&gt;
在bash，dot点号命令与source命令一样，把文件加载至shell内存空间&lt;/p&gt;
&lt;p&gt;修改/cookbooks/openvpn/templates/default/server.up.sh.erb，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/sbin/sysctl -w net.ipv4.ip_forward=1&lt;br /&gt;
/sbin/iptables -t nat -A &lt;span class=&quot;caps&quot;&gt;POSTROUTING&lt;/span&gt; -s &amp;lt;%= @openvpn[:subnet] &lt;span&gt;&amp;gt;/&amp;lt;&lt;/span&gt;= @openvpn[:netmask] &lt;span&gt;&amp;gt; -j &lt;span class=&quot;caps&quot;&gt;SNAT&lt;/span&gt;  &amp;#8212;to-source &amp;lt;&lt;/span&gt;= @openvpn[:local] %&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;修改cookbooks/openvpn/recipes/default.rb，加入变量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;template &amp;#8220;/etc/openvpn/server.up.sh&amp;#8221; do&lt;br /&gt;
　source &amp;#8220;server.up.sh.erb&amp;#8221;&lt;br /&gt;
　variables :openvpn =&amp;gt; node[:openvpn]&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
cd files/default/easy-rsa
. vars
rake server&lt;/pre&gt;
&lt;p&gt;为node加入role&lt;/p&gt;
&lt;pre&gt;
knife node list
#以上查看node id，假如为201166，现在查看node的run_list
#加入刚才新增的role
knife node run_list add 201166 &quot;role[vpn]&quot;
knife cookbook upload -a&lt;/pre&gt;
&lt;p&gt;远程登录vps，开始按run_list运行指定recipe&lt;/p&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client&lt;/pre&gt;
&lt;p&gt;在本地配置vpn client&lt;/p&gt;
&lt;pre&gt;
sudo apt-get install openvpn
cd files/default/easy-rsa
. vars
#注意不要运行多次，多次运行的时候请更换name，否则生成的.crt文件会为空
rake client name=&quot;client&quot; gateway=&quot;188.188.188.188&quot;
sudo mkdir /etc/openvpn
cd /etc/openvpn
sudo cp /tmp/client.zip .
sudo unzip client.zip&lt;/pre&gt;
&lt;p&gt;修改DNS，否则就算边上vpn也不能访问twitter等，修改 &lt;code&gt;/etc/resolv.conf&lt;/code&gt;为:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nameserver 8.8.8.8&lt;br /&gt;
nameserver 8.8.4.4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;测试&lt;/p&gt;
&lt;pre&gt;
#在服务端运行
openvpn --config /etc/openvpn/server.conf --script-security 2
#在客户端运行
sudo openvpn --config /etc/openvpn/client.conf&lt;/pre&gt;
&lt;p&gt;此时，再通过浏览器访问的google.com不会再跳转至google.com.hk了&lt;/p&gt;
&lt;h2&gt;ssh通道?&lt;/h2&gt;
&lt;p&gt;除了vpn，我们还可以使用ssh通道访问受限网站&lt;/p&gt;
&lt;pre&gt;
#autossh支持断线重连
sudo apt-get install autossh
autossh -M 2000 -N -v root@188.188.188.188 -D 127.0.0.1:7070&lt;/pre&gt;
&lt;p&gt;结合&amp;quot;chrome proxy switch&amp;quot;:https://chrome.google.com/extensions/detail/caehdcpeofiiigpdhbabniblemipncjj?hl=zh-cn 可以让浏览器自动切换代理&lt;/p&gt;
&lt;h2&gt;调试&lt;/h2&gt;
&lt;h3&gt;日志&lt;/h3&gt;
&lt;pre&gt;
tail -f /var/log/openvpn.log&lt;/pre&gt;
&lt;h2&gt;参考资源&lt;br /&gt;
&lt;a href=&quot;http://www.lenghost.cn/vps/burstnet-vps-openvpn-install/&quot;&gt;BurstNET的VPS安装OpenVPN教程总结&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://openvpn.net/index.php/open-source/documentation/howto.html&quot;&gt;Openvpn Document&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.wowubuntu.com/blog/ubuntu_ssh_tunneling&quot;&gt;ssh tunneling&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://imyue.net/?p=1167&quot;&gt;Chrome自动使用代理&lt;/a&gt;&lt;/h2&gt;</content><content:encoded>&lt;h2&gt;burst vps&lt;/h2&gt;
&lt;p&gt;之前买了burst的vps，现在准备为它安装openvpn&lt;br /&gt;
使用openvpn需要先登录后台管理 &lt;a href=&quot;https://184.82.225.10:2408&quot;&gt;https://184.82.225.10:2408/index.php&lt;/a&gt;&lt;br /&gt;
在Networking &amp;amp; Utilities 启用 Enable Tun/Tap&lt;/p&gt;
&lt;h2&gt;安装openvpn&lt;/h2&gt;
&lt;p&gt;假设vps ip为188.188.188.188&lt;br /&gt;
ssh密码为123456&lt;/p&gt;
&lt;p&gt;把这台vps当成vpn服务器，实现无障碍访问互联网&lt;/p&gt;
&lt;pre&gt;
export EDITOR=vim
knife role create vpn&lt;/pre&gt;
&lt;p&gt;knife会打开vim，将内容修改为:&lt;/p&gt;
&lt;pre&gt;
{
  &quot;name&quot;: &quot;vpn&quot;,
  &quot;description&quot;: &quot;openvpn server&quot;,
  &quot;json_class&quot;: &quot;Chef::Role&quot;,
  &quot;default_attributes&quot;: {
    &quot;chef&quot;: {
      &quot;server_url&quot;: &quot;https://api.opscode.com/organizations/#{YOUR COMPANY!}&quot;,
      &quot;cache_path&quot;: &quot;/var/chef/cache&quot;,
      &quot;backup_path&quot;: &quot;/var/chef/backup&quot;,
      &quot;validation_client_name&quot;: &quot;#{YOUR COMPANY!}-validator&quot;,
      &quot;run_path&quot;: &quot;/var/chef&quot;
    }
  },
  &quot;override_attributes&quot;: {
  },
  &quot;chef_type&quot;: &quot;role&quot;,
  &quot;run_list&quot;: [
    &quot;recipe[openvpn::default]&quot;
  ]
}&lt;/pre&gt;
&lt;p&gt;修改完后退出vim，会提示已经&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Created (or updated) role[vpn]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;下载相应的cookbook&lt;/p&gt;
&lt;pre&gt;
#此命令最常用
knife cookbook site vendor openvpn&lt;/pre&gt;
&lt;p&gt;远程生成服务端的keys，以下命令在本地执行&lt;br /&gt;
在bash，dot点号命令与source命令一样，把文件加载至shell内存空间&lt;/p&gt;
&lt;p&gt;修改/cookbooks/openvpn/templates/default/server.up.sh.erb，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/sbin/sysctl -w net.ipv4.ip_forward=1&lt;br /&gt;
/sbin/iptables -t nat -A &lt;span class=&quot;caps&quot;&gt;POSTROUTING&lt;/span&gt; -s &amp;lt;%= @openvpn[:subnet] &lt;span&gt;&amp;gt;/&amp;lt;&lt;/span&gt;= @openvpn[:netmask] &lt;span&gt;&amp;gt; -j &lt;span class=&quot;caps&quot;&gt;SNAT&lt;/span&gt;  &amp;#8212;to-source &amp;lt;&lt;/span&gt;= @openvpn[:local] %&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;修改cookbooks/openvpn/recipes/default.rb，加入变量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;template &amp;#8220;/etc/openvpn/server.up.sh&amp;#8221; do&lt;br /&gt;
　source &amp;#8220;server.up.sh.erb&amp;#8221;&lt;br /&gt;
　variables :openvpn =&amp;gt; node[:openvpn]&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
cd files/default/easy-rsa
. vars
rake server&lt;/pre&gt;
&lt;p&gt;为node加入role&lt;/p&gt;
&lt;pre&gt;
knife node list
#以上查看node id，假如为201166，现在查看node的run_list
#加入刚才新增的role
knife node run_list add 201166 &quot;role[vpn]&quot;
knife cookbook upload -a&lt;/pre&gt;
&lt;p&gt;远程登录vps，开始按run_list运行指定recipe&lt;/p&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client&lt;/pre&gt;
&lt;p&gt;在本地配置vpn client&lt;/p&gt;
&lt;pre&gt;
sudo apt-get install openvpn
cd files/default/easy-rsa
. vars
#注意不要运行多次，多次运行的时候请更换name，否则生成的.crt文件会为空
rake client name=&quot;client&quot; gateway=&quot;188.188.188.188&quot;
sudo mkdir /etc/openvpn
cd /etc/openvpn
sudo cp /tmp/client.zip .
sudo unzip client.zip&lt;/pre&gt;
&lt;p&gt;修改DNS，否则就算边上vpn也不能访问twitter等，修改 &lt;code&gt;/etc/resolv.conf&lt;/code&gt;为:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nameserver 8.8.8.8&lt;br /&gt;
nameserver 8.8.4.4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;测试&lt;/p&gt;
&lt;pre&gt;
#在服务端运行
openvpn --config /etc/openvpn/server.conf --script-security 2
#在客户端运行
sudo openvpn --config /etc/openvpn/client.conf&lt;/pre&gt;
&lt;p&gt;此时，再通过浏览器访问的google.com不会再跳转至google.com.hk了&lt;/p&gt;
&lt;h2&gt;ssh通道?&lt;/h2&gt;
&lt;p&gt;除了vpn，我们还可以使用ssh通道访问受限网站&lt;/p&gt;
&lt;pre&gt;
#autossh支持断线重连
sudo apt-get install autossh
autossh -M 2000 -N -v root@188.188.188.188 -D 127.0.0.1:7070&lt;/pre&gt;
&lt;p&gt;结合&amp;quot;chrome proxy switch&amp;quot;:https://chrome.google.com/extensions/detail/caehdcpeofiiigpdhbabniblemipncjj?hl=zh-cn 可以让浏览器自动切换代理&lt;/p&gt;
&lt;h2&gt;调试&lt;/h2&gt;
&lt;h3&gt;日志&lt;/h3&gt;
&lt;pre&gt;
tail -f /var/log/openvpn.log&lt;/pre&gt;
&lt;h2&gt;参考资源&lt;br /&gt;
&lt;a href=&quot;http://www.lenghost.cn/vps/burstnet-vps-openvpn-install/&quot;&gt;BurstNET的VPS安装OpenVPN教程总结&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://openvpn.net/index.php/open-source/documentation/howto.html&quot;&gt;Openvpn Document&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.wowubuntu.com/blog/ubuntu_ssh_tunneling&quot;&gt;ssh tunneling&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://imyue.net/?p=1167&quot;&gt;Chrome自动使用代理&lt;/a&gt;&lt;/h2&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565427/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565427/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565427/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565427/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/linux/2011/02/13/use-chef-to-install-openvpn-in-burst-vps.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565427/6499449</fs:itemid><pubDate>Sun, 13 Feb 2011 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/linux/2011/02/13/use-chef-to-install-openvpn-in-burst-vps</guid></item><item><title>应用chef构建服务器集群自动化部署与管理</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565428/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/linux/2011/01/27/chef-for-automate-deploy</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;为了将rails程序部署到服务器上，需要做的工作有&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;安装服务器各组件，如libcurl等&lt;/li&gt;
	&lt;li&gt;配置服务器，如用户管理、iptable等&lt;/li&gt;
	&lt;li&gt;安装数据库&lt;/li&gt;
	&lt;li&gt;安装缓存服务&lt;/li&gt;
	&lt;li&gt;安装配置前端应用服务器&lt;/li&gt;
	&lt;li&gt;安装rvm&lt;/li&gt;
	&lt;li&gt;安装项目所需gems&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以上工作属于新服务器到位后的一次性工作，而项目更新升级的工作属于不定期重复性工作，大致如下：&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;下载最新源代码&lt;/li&gt;
	&lt;li&gt;运行数据库脚本&lt;/li&gt;
	&lt;li&gt;重新启动应用服务器&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此外，日常工作还包括服务器的监控、维护等&lt;/p&gt;
&lt;p&gt;当项目规模不大，服务器只有一两台时，可以手动或者应用 &lt;a href=&quot;https://github.com/capistrano/capistrano&quot;&gt;Capistrano&lt;/a&gt; 及 &lt;a href=&quot;https://github.com/mbailey/deprec&quot;&gt;deprec&lt;/a&gt; 自动处理&lt;/p&gt;
&lt;h3&gt;capistrano的缺点&lt;/h3&gt;
&lt;p&gt;在应用capify安装某些组件的过程中，如果出现问题，只能进入源代码检查相应的recipe，因为capistrano的recipe相对来说是隐性的&lt;br /&gt;
比如，安装之前，我们不知道mysql的安装会是通过package直接安装还是通过下载source本地编译后安装，也无法获知其版本&lt;br /&gt;
而当recipe不符合你的要求时，需要对其进行改造的成本比较大&lt;/p&gt;
&lt;p&gt;随着项目规模的不断扩大，比如，有了专门的数据库服务器，甚至是数据库服务器集群，这时候capistrano就会显示力不从心了&lt;br /&gt;
我们需要有专业的服务器管理配置工具来统一管理所有的服务器，这类工具不少，这里只介绍chef&lt;/p&gt;
&lt;h2&gt;Chef&lt;/h2&gt;
&lt;h3&gt;Chef是一个什么样的工具&lt;/h3&gt;
&lt;p&gt;想像一下我们现在需要搭建一台mysql database slave服务器，安装过程我们手动操作了&lt;br /&gt;
没过多久，我们需要第二台，这时候我们会想，如果之后安装第一台的时候把操作过程执行的命令写成脚本&lt;br /&gt;
现在安装第二台，运行一下脚本就行了，节约时间而且不容易出错&lt;/p&gt;
&lt;p&gt;chef就相当于这样的一个脚本管理工具，但功能要强大得多，可定制性强&lt;br /&gt;
chef将脚本命令代码化，定制时只需要修改代码，安装的过程就是执行代码的过程&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/chef/chef.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Chef的三种管理模式&lt;/h3&gt;
&lt;p&gt;1. Chef-Solo&lt;/p&gt;
&lt;p&gt;由一台普通电脑控制所有的服务器，不需要专设一台chef-server&lt;/p&gt;
&lt;p&gt;2. Client-Server&lt;/p&gt;
&lt;p&gt;所有的服务器作为chef-client，统一由chef-server进行管理，管理包括安装、配置等工作&lt;br /&gt;
chef-server可以自建，但安装的东西较多，由于使用solr作为全文搜索引擎，还需要安装java&lt;/p&gt;
&lt;p&gt;3. Opscode Platform&lt;/p&gt;
&lt;p&gt;类似于Client-Server，只是Server端不需要自建，而是采用 &lt;a href=&quot;http://www.opscode.com&quot;&gt;http://www.opscode.com&lt;/a&gt; 提供的chef-server服务，本文描述以此方式为主，免费帐号可以管理5个服务器&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/chef/opscode.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Library程序库&lt;/h3&gt;
&lt;p&gt;程序库是定义的module方法，可以在chef中任何地方被调用，在方法体内可以执行与数据库等资源的交互动作&lt;br /&gt;
详见 &lt;a href=&quot;http://wiki.opscode.com/display/chef/Libraries&quot;&gt;Libraries&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;操作对象&lt;/h3&gt;
&lt;p&gt;chef可以通过recipe指定新建目录、生成配置文件、安装gems等操作，可控性非常强&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新建目录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;新建目录/data，owner为node[:user]指定的内容，权限代码为0755&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;directory &amp;#8220;/data&amp;#8221; do&lt;br /&gt;
　owner node[:user]&lt;br /&gt;
　mode 0755&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;生成配置文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以someservice.conf.erb为模板，生成/data/someservice.conf配置文件，生成时会传递参数applications给模板&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;template &amp;#8220;/data/someservice.conf&amp;#8221; do&lt;br /&gt;
　owner node[:user]&lt;br /&gt;
　mode 0644&lt;br /&gt;
　source &amp;#8220;someservice.conf.erb&amp;#8221; &lt;br /&gt;
　variables({&lt;br /&gt;
　　:applications =&amp;gt; node[:apps]&lt;br /&gt;
　})&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;把一台新的vps纳入chef管理&lt;/h2&gt;
&lt;p&gt;假设vps ip为188.188.188.188&lt;br /&gt;
ssh密码为123456&lt;/p&gt;
&lt;h3&gt;注册&lt;/h3&gt;
&lt;p&gt;到 &lt;a href=&quot;https://cookbooks.opscode.com/users/new&quot;&gt;https://cookbooks.opscode.com/users/new&lt;/a&gt; 注册帐号&lt;br /&gt;
通过邮件认证后，进入控制台 &lt;a href=&quot;https://manage.opscode.com&quot;&gt;https://manage.opscode.com&lt;/a&gt; 创建organization&lt;br /&gt;
按提示下载两个链接文件至~/Downloads: Download validation key | Generate knife config&lt;br /&gt;
点击右上角的用户名，下载链接文件至~/Download: Get a new private key&lt;/p&gt;
&lt;p&gt;下载后的knife.txt要改名为knife.rb&lt;br /&gt;
&lt;strong&gt;以上三个文件请妥善保管，下载之后opscode平台不再保存这些文件&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;本地安装&lt;/h3&gt;
&lt;pre&gt;
gem install chef net-ssh-multi --no-ri --no-rdoc
cd ~/Documents
git clone git://github.com/opscode/chef-repo.git
cd chef-repo
mkdir -p .chef&lt;/pre&gt;
&lt;pre&gt;
# USERNAME和ORGANIZATION改为实际的文件名称
cd ~/Downloads
cp USERNAME.pem ~/Documents/chef-repo/.chef
cp ORGANIZATION-validator.pem ~/Documents/chef-repo/.chef
cp knife.rb ~/Documents/chef-repo/.chef&lt;/pre&gt;
&lt;pre&gt;
#测试连接opscode platform
knife client list
#成功连接则显示validator的数组，如
#[ &quot;shopqi-validator&quot; ]&lt;/pre&gt;
&lt;h3&gt;为vps安装ruby及chef客户端环境&lt;/h3&gt;
&lt;pre&gt;
knife bootstrap 188.188.188.188 -u root -P 123456
#ssh登录服务器不再需要输入密码
ssh root@188.188.188.188 'sh -c &quot;mkdir ~/.ssh&quot;'
scp ~/.ssh/id_rsa.pub root@188.188.188.188:/root/.ssh/authorized_keys&lt;/pre&gt;
&lt;h3&gt;远程测试是否安装正常&lt;/h3&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client
#如果出现错误，可使用调试模式
chef-client -l debug&lt;/pre&gt;
&lt;h2&gt;让vps运行第一个cookbook&lt;/h2&gt;
&lt;p&gt;安装完服务器操作系统后，第一件事情就是更新软件&lt;br /&gt;
一般情况下，我们会在服务器上运行命令&lt;/p&gt;
&lt;pre&gt;
sudo apt-get update&lt;/pre&gt;
&lt;p&gt;现在我们要通过chef来指定vps运行此命令&lt;/p&gt;
&lt;h3&gt;本地安装apt cookbook&lt;/h3&gt;
&lt;pre&gt;
#此命令最常用，会从opscode官网 &quot;http://cookbooks.opscode.com/&quot;:http://cookbooks.opscode.com/ 下载cookbook
knife cookbook site vendor apt&lt;/pre&gt;
&lt;p&gt;为node加入recipe&lt;/p&gt;
&lt;pre&gt;
knife node list
#以上查看node id，假如为201166，现在查看node的run_list
knife node show 201166 -r
#加入apt recipe到vps的run list中
knife node run_list add 201166 &quot;recipe[apt]&quot;
knife node show 201166 -r
knife cookbook upload -a&lt;/pre&gt;
&lt;h3&gt;远程登录vps，开始按run_list运行指定recipe&lt;/h3&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client
#每次本地更新后都要在远程运行chef-client比较麻烦，可以使用以下命令，设置为后台程序运行
chef-client -i 3600 -s 600&lt;/pre&gt;
&lt;h2&gt;安装ruby-on-rails3&lt;/h2&gt;
&lt;h3&gt;下载cookbook&lt;/h3&gt;
&lt;pre&gt;
#参数-d要求下载依赖的cookbook
knife cookbook site vendor rvm -d
#此cookbook调用了chef内置的deploy resource，实现类似于capistrano的部署功能
#但此cookbook还依赖了java cookbook等，忽略它们即可
knife cookbook site vendor application -d&lt;/pre&gt;
&lt;h3&gt;新增apps data bag&lt;/h3&gt;
&lt;p&gt;data bag相当于全局变量，application cookcook需要根据apps指定role,recipe等参数&lt;/p&gt;
&lt;pre&gt;
export EDITOR=vim
#参考 &quot;https://github.com/opscode/cookbooks/tree/master/application&quot;:https://github.com/opscode/cookbooks/tree/master/application 将json粘贴进来
#退出vim时，data bag会被自动上传至chef server，本地不保存
knife data bag create apps 55true
#保存至本地
mkdir data_bags/apps
knife data bag show apps 55true &amp;gt; data_bags/apps/55true.json
knife data bag from file apps 55true.json&lt;/pre&gt;
&lt;h3&gt;新增role rails&lt;/h3&gt;
&lt;pre&gt;
export EDITOR=vim
knife role create rails&lt;/pre&gt;
&lt;h3&gt;Tip&lt;/h3&gt;
&lt;p&gt;服务器集群中可能会区分出production, staging环境，也可能同一应用部署在多台服务器中，但只需由其中的一台服务器运行数据库迁徙脚本&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;新增production, staging等role，设置app_environment attribute，分配至相应的node，这样可以重复使用deploy cookbook&lt;/li&gt;
	&lt;li&gt;新增app_name_run_migrations role，设置run_migrations attribute&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;常用cookbook&lt;/h2&gt;
&lt;p&gt;以下列出在 &lt;a href=&quot;https://github.com/opscode/cookbooks&quot;&gt;https://github.com/opscode/cookbooks&lt;/a&gt; 中常用的cookbook&lt;/p&gt;
&lt;h3&gt;apt&lt;/h3&gt;
&lt;p&gt;此recipt会运行apt-get update，用于更新操作系统&lt;/p&gt;
&lt;h3&gt;runit&lt;/h3&gt;
&lt;p&gt;用于保证unicorn等服务时刻处于运行状态&lt;br /&gt;
runsvdir服务会不停地监测/etc/sv目录下的服务目录，每个目录对应一个runsv服务&lt;br /&gt;
如果某个runsv服务出现故障停止了,runsvdir会自动重新启动它&lt;/p&gt;
&lt;pre&gt;
#sv服务不启动时查看日志
ps -ef | grep runsvdir
#查看服务的状态
sv stat unicorn_server
#查看服务的日志
tail -f /etc/sv/unicorn_server/log/main/current&lt;/pre&gt;
&lt;h3&gt;bluepill&lt;/h3&gt;
&lt;p&gt;runit保证了服务的运行，bluepill保证进程的cpu、memory占用率处于正常水平&lt;/p&gt;
&lt;h3&gt;users&lt;/h3&gt;
&lt;p&gt;新增用户，用户定义在users data bag中&lt;/p&gt;
&lt;h3&gt;mongodb&lt;/h3&gt;
&lt;p&gt;安装1.6.5版本的mongo server&lt;br /&gt;
&lt;a href=&quot;https://github.com/papercavalier/mongodb-cookbook&quot;&gt;https://github.com/papercavalier/mongodb-cookbook&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;unicorn&lt;/h3&gt;
&lt;p&gt;经过对比，还是选择37signal的unicorn cookbook，因为支持多app部署，而unicornapp不支持(opscode官方已经删除此cookbook)。为了对unicorn子线程进行监控，两者都使用了bluepill取代God进行监控。&lt;br /&gt;
注意：在production环境下，rails3默认不会处理public目录下静态文件的请求，所以不能像dev环境下直接通过指定端口访问某个unicorn服务&lt;/p&gt;
&lt;h3&gt;application&lt;/h3&gt;
&lt;p&gt;&lt;del&gt;这个包含太多的依赖cookbook了，经过以上的实践，还是觉得不用它了，因为里面对rails项目有用的就是deploy部分，自己重写一个也很容易&lt;/del&gt;&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;p&gt;在service或者definition中传递参数时，如果将父params需要级联传递下去，得手动为params赋值至其他变量，因为在service或者definition块中，params参数已经被当前块覆盖了&lt;br /&gt;
详情参考：&amp;quot;http://tickets.opscode.com/browse/&lt;span class=&quot;caps&quot;&gt;CHEF&lt;/span&gt;-422&amp;quot;&lt;/p&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/adamhjk/infrastructure-automation-with-chef&quot; title=&quot;Read This First&quot;&gt;Infrastructure Automation with Chef&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial&quot;&gt;Getting started with Chef tutorial&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.agileweboperations.com/getting-started-with-the-opscode-chef-platform-configuration-management-in-the-cloud&quot;&gt;Getting Started With The Opscode Chef Platform – Configuration Management In The Cloud&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.agileweboperations.com/how-to-deploy-ruby-on-rails-with-the-opscode-chef-application-cookbook&quot;&gt;How to Deploy Ruby on Rails With The Opscode Chef Application Cookbook&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://brainspl.at/articles/2009/01/31/cooking-with-chef-101&quot;&gt;Cooking with Chef 101&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.slideshare.net/adamhjk/why-startups-need-automated-infrastructures&quot;&gt;Why Startups Need Automated Infrastructures&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Deploy+Resource&quot;&gt;Deploy Resource&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/opscode/cookbooks/tree/master/application&quot;&gt;application cookbook&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://smarden.org/runit/&quot;&gt;runit&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;p&gt;为了将rails程序部署到服务器上，需要做的工作有&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;安装服务器各组件，如libcurl等&lt;/li&gt;
	&lt;li&gt;配置服务器，如用户管理、iptable等&lt;/li&gt;
	&lt;li&gt;安装数据库&lt;/li&gt;
	&lt;li&gt;安装缓存服务&lt;/li&gt;
	&lt;li&gt;安装配置前端应用服务器&lt;/li&gt;
	&lt;li&gt;安装rvm&lt;/li&gt;
	&lt;li&gt;安装项目所需gems&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以上工作属于新服务器到位后的一次性工作，而项目更新升级的工作属于不定期重复性工作，大致如下：&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;下载最新源代码&lt;/li&gt;
	&lt;li&gt;运行数据库脚本&lt;/li&gt;
	&lt;li&gt;重新启动应用服务器&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此外，日常工作还包括服务器的监控、维护等&lt;/p&gt;
&lt;p&gt;当项目规模不大，服务器只有一两台时，可以手动或者应用 &lt;a href=&quot;https://github.com/capistrano/capistrano&quot;&gt;Capistrano&lt;/a&gt; 及 &lt;a href=&quot;https://github.com/mbailey/deprec&quot;&gt;deprec&lt;/a&gt; 自动处理&lt;/p&gt;
&lt;h3&gt;capistrano的缺点&lt;/h3&gt;
&lt;p&gt;在应用capify安装某些组件的过程中，如果出现问题，只能进入源代码检查相应的recipe，因为capistrano的recipe相对来说是隐性的&lt;br /&gt;
比如，安装之前，我们不知道mysql的安装会是通过package直接安装还是通过下载source本地编译后安装，也无法获知其版本&lt;br /&gt;
而当recipe不符合你的要求时，需要对其进行改造的成本比较大&lt;/p&gt;
&lt;p&gt;随着项目规模的不断扩大，比如，有了专门的数据库服务器，甚至是数据库服务器集群，这时候capistrano就会显示力不从心了&lt;br /&gt;
我们需要有专业的服务器管理配置工具来统一管理所有的服务器，这类工具不少，这里只介绍chef&lt;/p&gt;
&lt;h2&gt;Chef&lt;/h2&gt;
&lt;h3&gt;Chef是一个什么样的工具&lt;/h3&gt;
&lt;p&gt;想像一下我们现在需要搭建一台mysql database slave服务器，安装过程我们手动操作了&lt;br /&gt;
没过多久，我们需要第二台，这时候我们会想，如果之后安装第一台的时候把操作过程执行的命令写成脚本&lt;br /&gt;
现在安装第二台，运行一下脚本就行了，节约时间而且不容易出错&lt;/p&gt;
&lt;p&gt;chef就相当于这样的一个脚本管理工具，但功能要强大得多，可定制性强&lt;br /&gt;
chef将脚本命令代码化，定制时只需要修改代码，安装的过程就是执行代码的过程&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/chef/chef.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Chef的三种管理模式&lt;/h3&gt;
&lt;p&gt;1. Chef-Solo&lt;/p&gt;
&lt;p&gt;由一台普通电脑控制所有的服务器，不需要专设一台chef-server&lt;/p&gt;
&lt;p&gt;2. Client-Server&lt;/p&gt;
&lt;p&gt;所有的服务器作为chef-client，统一由chef-server进行管理，管理包括安装、配置等工作&lt;br /&gt;
chef-server可以自建，但安装的东西较多，由于使用solr作为全文搜索引擎，还需要安装java&lt;/p&gt;
&lt;p&gt;3. Opscode Platform&lt;/p&gt;
&lt;p&gt;类似于Client-Server，只是Server端不需要自建，而是采用 &lt;a href=&quot;http://www.opscode.com&quot;&gt;http://www.opscode.com&lt;/a&gt; 提供的chef-server服务，本文描述以此方式为主，免费帐号可以管理5个服务器&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/chef/opscode.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Library程序库&lt;/h3&gt;
&lt;p&gt;程序库是定义的module方法，可以在chef中任何地方被调用，在方法体内可以执行与数据库等资源的交互动作&lt;br /&gt;
详见 &lt;a href=&quot;http://wiki.opscode.com/display/chef/Libraries&quot;&gt;Libraries&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;操作对象&lt;/h3&gt;
&lt;p&gt;chef可以通过recipe指定新建目录、生成配置文件、安装gems等操作，可控性非常强&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新建目录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;新建目录/data，owner为node[:user]指定的内容，权限代码为0755&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;directory &amp;#8220;/data&amp;#8221; do&lt;br /&gt;
　owner node[:user]&lt;br /&gt;
　mode 0755&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;生成配置文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以someservice.conf.erb为模板，生成/data/someservice.conf配置文件，生成时会传递参数applications给模板&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;template &amp;#8220;/data/someservice.conf&amp;#8221; do&lt;br /&gt;
　owner node[:user]&lt;br /&gt;
　mode 0644&lt;br /&gt;
　source &amp;#8220;someservice.conf.erb&amp;#8221; &lt;br /&gt;
　variables({&lt;br /&gt;
　　:applications =&amp;gt; node[:apps]&lt;br /&gt;
　})&lt;br /&gt;
end&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;把一台新的vps纳入chef管理&lt;/h2&gt;
&lt;p&gt;假设vps ip为188.188.188.188&lt;br /&gt;
ssh密码为123456&lt;/p&gt;
&lt;h3&gt;注册&lt;/h3&gt;
&lt;p&gt;到 &lt;a href=&quot;https://cookbooks.opscode.com/users/new&quot;&gt;https://cookbooks.opscode.com/users/new&lt;/a&gt; 注册帐号&lt;br /&gt;
通过邮件认证后，进入控制台 &lt;a href=&quot;https://manage.opscode.com&quot;&gt;https://manage.opscode.com&lt;/a&gt; 创建organization&lt;br /&gt;
按提示下载两个链接文件至~/Downloads: Download validation key | Generate knife config&lt;br /&gt;
点击右上角的用户名，下载链接文件至~/Download: Get a new private key&lt;/p&gt;
&lt;p&gt;下载后的knife.txt要改名为knife.rb&lt;br /&gt;
&lt;strong&gt;以上三个文件请妥善保管，下载之后opscode平台不再保存这些文件&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;本地安装&lt;/h3&gt;
&lt;pre&gt;
gem install chef net-ssh-multi --no-ri --no-rdoc
cd ~/Documents
git clone git://github.com/opscode/chef-repo.git
cd chef-repo
mkdir -p .chef&lt;/pre&gt;
&lt;pre&gt;
# USERNAME和ORGANIZATION改为实际的文件名称
cd ~/Downloads
cp USERNAME.pem ~/Documents/chef-repo/.chef
cp ORGANIZATION-validator.pem ~/Documents/chef-repo/.chef
cp knife.rb ~/Documents/chef-repo/.chef&lt;/pre&gt;
&lt;pre&gt;
#测试连接opscode platform
knife client list
#成功连接则显示validator的数组，如
#[ &quot;shopqi-validator&quot; ]&lt;/pre&gt;
&lt;h3&gt;为vps安装ruby及chef客户端环境&lt;/h3&gt;
&lt;pre&gt;
knife bootstrap 188.188.188.188 -u root -P 123456
#ssh登录服务器不再需要输入密码
ssh root@188.188.188.188 'sh -c &quot;mkdir ~/.ssh&quot;'
scp ~/.ssh/id_rsa.pub root@188.188.188.188:/root/.ssh/authorized_keys&lt;/pre&gt;
&lt;h3&gt;远程测试是否安装正常&lt;/h3&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client
#如果出现错误，可使用调试模式
chef-client -l debug&lt;/pre&gt;
&lt;h2&gt;让vps运行第一个cookbook&lt;/h2&gt;
&lt;p&gt;安装完服务器操作系统后，第一件事情就是更新软件&lt;br /&gt;
一般情况下，我们会在服务器上运行命令&lt;/p&gt;
&lt;pre&gt;
sudo apt-get update&lt;/pre&gt;
&lt;p&gt;现在我们要通过chef来指定vps运行此命令&lt;/p&gt;
&lt;h3&gt;本地安装apt cookbook&lt;/h3&gt;
&lt;pre&gt;
#此命令最常用，会从opscode官网 &quot;http://cookbooks.opscode.com/&quot;:http://cookbooks.opscode.com/ 下载cookbook
knife cookbook site vendor apt&lt;/pre&gt;
&lt;p&gt;为node加入recipe&lt;/p&gt;
&lt;pre&gt;
knife node list
#以上查看node id，假如为201166，现在查看node的run_list
knife node show 201166 -r
#加入apt recipe到vps的run list中
knife node run_list add 201166 &quot;recipe[apt]&quot;
knife node show 201166 -r
knife cookbook upload -a&lt;/pre&gt;
&lt;h3&gt;远程登录vps，开始按run_list运行指定recipe&lt;/h3&gt;
&lt;pre&gt;
ssh root@188.188.188.188
chef-client
#每次本地更新后都要在远程运行chef-client比较麻烦，可以使用以下命令，设置为后台程序运行
chef-client -i 3600 -s 600&lt;/pre&gt;
&lt;h2&gt;安装ruby-on-rails3&lt;/h2&gt;
&lt;h3&gt;下载cookbook&lt;/h3&gt;
&lt;pre&gt;
#参数-d要求下载依赖的cookbook
knife cookbook site vendor rvm -d
#此cookbook调用了chef内置的deploy resource，实现类似于capistrano的部署功能
#但此cookbook还依赖了java cookbook等，忽略它们即可
knife cookbook site vendor application -d&lt;/pre&gt;
&lt;h3&gt;新增apps data bag&lt;/h3&gt;
&lt;p&gt;data bag相当于全局变量，application cookcook需要根据apps指定role,recipe等参数&lt;/p&gt;
&lt;pre&gt;
export EDITOR=vim
#参考 &quot;https://github.com/opscode/cookbooks/tree/master/application&quot;:https://github.com/opscode/cookbooks/tree/master/application 将json粘贴进来
#退出vim时，data bag会被自动上传至chef server，本地不保存
knife data bag create apps 55true
#保存至本地
mkdir data_bags/apps
knife data bag show apps 55true &amp;gt; data_bags/apps/55true.json
knife data bag from file apps 55true.json&lt;/pre&gt;
&lt;h3&gt;新增role rails&lt;/h3&gt;
&lt;pre&gt;
export EDITOR=vim
knife role create rails&lt;/pre&gt;
&lt;h3&gt;Tip&lt;/h3&gt;
&lt;p&gt;服务器集群中可能会区分出production, staging环境，也可能同一应用部署在多台服务器中，但只需由其中的一台服务器运行数据库迁徙脚本&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;新增production, staging等role，设置app_environment attribute，分配至相应的node，这样可以重复使用deploy cookbook&lt;/li&gt;
	&lt;li&gt;新增app_name_run_migrations role，设置run_migrations attribute&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;常用cookbook&lt;/h2&gt;
&lt;p&gt;以下列出在 &lt;a href=&quot;https://github.com/opscode/cookbooks&quot;&gt;https://github.com/opscode/cookbooks&lt;/a&gt; 中常用的cookbook&lt;/p&gt;
&lt;h3&gt;apt&lt;/h3&gt;
&lt;p&gt;此recipt会运行apt-get update，用于更新操作系统&lt;/p&gt;
&lt;h3&gt;runit&lt;/h3&gt;
&lt;p&gt;用于保证unicorn等服务时刻处于运行状态&lt;br /&gt;
runsvdir服务会不停地监测/etc/sv目录下的服务目录，每个目录对应一个runsv服务&lt;br /&gt;
如果某个runsv服务出现故障停止了,runsvdir会自动重新启动它&lt;/p&gt;
&lt;pre&gt;
#sv服务不启动时查看日志
ps -ef | grep runsvdir
#查看服务的状态
sv stat unicorn_server
#查看服务的日志
tail -f /etc/sv/unicorn_server/log/main/current&lt;/pre&gt;
&lt;h3&gt;bluepill&lt;/h3&gt;
&lt;p&gt;runit保证了服务的运行，bluepill保证进程的cpu、memory占用率处于正常水平&lt;/p&gt;
&lt;h3&gt;users&lt;/h3&gt;
&lt;p&gt;新增用户，用户定义在users data bag中&lt;/p&gt;
&lt;h3&gt;mongodb&lt;/h3&gt;
&lt;p&gt;安装1.6.5版本的mongo server&lt;br /&gt;
&lt;a href=&quot;https://github.com/papercavalier/mongodb-cookbook&quot;&gt;https://github.com/papercavalier/mongodb-cookbook&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;unicorn&lt;/h3&gt;
&lt;p&gt;经过对比，还是选择37signal的unicorn cookbook，因为支持多app部署，而unicornapp不支持(opscode官方已经删除此cookbook)。为了对unicorn子线程进行监控，两者都使用了bluepill取代God进行监控。&lt;br /&gt;
注意：在production环境下，rails3默认不会处理public目录下静态文件的请求，所以不能像dev环境下直接通过指定端口访问某个unicorn服务&lt;/p&gt;
&lt;h3&gt;application&lt;/h3&gt;
&lt;p&gt;&lt;del&gt;这个包含太多的依赖cookbook了，经过以上的实践，还是觉得不用它了，因为里面对rails项目有用的就是deploy部分，自己重写一个也很容易&lt;/del&gt;&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;p&gt;在service或者definition中传递参数时，如果将父params需要级联传递下去，得手动为params赋值至其他变量，因为在service或者definition块中，params参数已经被当前块覆盖了&lt;br /&gt;
详情参考：&amp;quot;http://tickets.opscode.com/browse/&lt;span class=&quot;caps&quot;&gt;CHEF&lt;/span&gt;-422&amp;quot;&lt;/p&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/adamhjk/infrastructure-automation-with-chef&quot; title=&quot;Read This First&quot;&gt;Infrastructure Automation with Chef&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial&quot;&gt;Getting started with Chef tutorial&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.agileweboperations.com/getting-started-with-the-opscode-chef-platform-configuration-management-in-the-cloud&quot;&gt;Getting Started With The Opscode Chef Platform – Configuration Management In The Cloud&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.agileweboperations.com/how-to-deploy-ruby-on-rails-with-the-opscode-chef-application-cookbook&quot;&gt;How to Deploy Ruby on Rails With The Opscode Chef Application Cookbook&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://brainspl.at/articles/2009/01/31/cooking-with-chef-101&quot;&gt;Cooking with Chef 101&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.slideshare.net/adamhjk/why-startups-need-automated-infrastructures&quot;&gt;Why Startups Need Automated Infrastructures&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Deploy+Resource&quot;&gt;Deploy Resource&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/opscode/cookbooks/tree/master/application&quot;&gt;application cookbook&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://smarden.org/runit/&quot;&gt;runit&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565428/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565428/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565428/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565428/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/linux/2011/01/27/chef-for-automate-deploy.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565428/6499449</fs:itemid><pubDate>Thu, 27 Jan 2011 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/linux/2011/01/27/chef-for-automate-deploy</guid></item><item><title>应用node.js,redis,resque构建实时项目</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565429/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/rails/2011/01/10/node-js-juggeraut-redis-resque</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;我对javascript语言还是很喜欢，所以对node.js这么有创意的东西，很早就开始关注了。&lt;br /&gt;
据说在实时领域的表现非常好，资源占用也不多，很想实践一番，以后正式项目有对实时性的需求，就可以放心地使用node.js了。&lt;/p&gt;
&lt;p&gt;所以我决定将 &lt;a href=&quot;https://github.com/saberma/55true&quot;&gt;55true&lt;/a&gt; 重新开发，加入即时问答的机制，普通功能开发上使用rails3，而实时性上应用node.js。&lt;br /&gt;
虽然node.js相关的框架已经非常多，也有类似于rails的MVC框架，但是毕竟发展时间还不长，所以使用rails结合node.js的方式进行开发是个不错的发展方式，各取所长。&lt;/p&gt;
&lt;h2&gt;Node.js&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/nodejs.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;node.js是一种可以用js来编写的服务端程序&lt;/p&gt;
&lt;p&gt;这次使用 &lt;a href=&quot;https://github.com/maccman/juggernaut&quot;&gt;https://github.com/maccman/juggernaut&lt;/a&gt; 框架，结合redis，实现rails与node.js服务的交互。&lt;br /&gt;
node.js的发展非常的快，有类似于rails bundler的插件管理工具npm，但为降低node.js相关框架的管理复杂度，我直接将juggernaut及其依赖的js文件都放在 &lt;a href=&quot;https://github.com/saberma/55true&quot;&gt;55true&lt;/a&gt; 的根目录。&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;pre&gt;
cd ~/Downloads
wget http://nodejs.org/dist/node-v0.2.6.tar.gz
tar -xzvf node-v0.2.6.tar.gz
cd node-v0.2.4
./configure
make
make install&lt;/pre&gt;
&lt;h3&gt;Juggernaut&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/maccman/juggernaut&quot;&gt;Juggernaut&lt;/a&gt; 是包含服务端及客户端的实时解决方案，最初服务端是用ruby eventmachine实现的。&lt;br /&gt;
node.js出来后，整个框架就用node.js重写了&lt;/p&gt;
&lt;h3&gt;启动Juggeranut&lt;/h3&gt;
&lt;pre&gt;
#node server.js
sudo node server.js&lt;/pre&gt;
&lt;p&gt;使用root帐号启动，否则firefox客户端访问会报错&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Flash is optional, but it&amp;#8217;s the default fallback for Firefox (until the beta is released). Start the server using root if you want Flash support. It needs to open a restricted por&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Redis&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/redis.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;redis是类似于memcached的高性能键值缓存工具，但它支持更多的值类型、功能更加丰富，且可以将存储内容定时持久化到磁盘中，是NoSQL家庭中出色的一员&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;pre&gt;
wget https://github.com/antirez/redis/tarball/2.2.0-rc2
tar -xzvf antirez-redis-2.2.0-rc2-0-g0540df2.tar.gz
cd antirez-redis-b703b5d
make
sudo make install&lt;/pre&gt;
&lt;h3&gt;客户端&lt;/h3&gt;
&lt;pre&gt;
redis-cli&lt;/pre&gt;
&lt;h3&gt;调试&lt;/h3&gt;
&lt;p&gt;运行客户端后，输入命令&lt;/p&gt;
&lt;pre&gt;
monitor&lt;/pre&gt;
&lt;h3&gt;注意expire&lt;/h3&gt;
&lt;p&gt;redis的expire命令有限制，执行此命令后，对key进行的任何操作都将先对key进行清空操作，详见 &lt;a href=&quot;http://redis.io/topics/expire&quot;&gt;http://redis.io/topics/expire&lt;/a&gt;&lt;br /&gt;
2.1.3以上版本不存在这个限制，但未正式发布稳定版，2.1正式发布时会更改为2.2版本&lt;/p&gt;
&lt;p&gt;具体表现如下:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;redis&amp;gt; set a 100&lt;br /&gt;
OK&lt;br /&gt;
redis&amp;gt; expire a 600&lt;br /&gt;
(integer) 1&lt;br /&gt;
redis&amp;gt; incr a&lt;br /&gt;
(integer) 1&lt;br /&gt;
redis&amp;gt; get a&lt;br /&gt;
&amp;#8220;1&amp;#8221; #正常来说，应返回101，因为还key还没有过期&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果对这个限制敏感，可以尝试 &lt;a href=&quot;http://redis.io/download&quot;&gt;2.2.0rc2版本&lt;/a&gt;&lt;br /&gt;
&lt;code&gt;make&lt;/code&gt; 之后最好再执行下 &lt;code&gt;make test&lt;/code&gt; 测试是否正常，我试过，确实不再存在上面说的奇怪表现&lt;/p&gt;
&lt;h3&gt;redis-rb&lt;/h3&gt;
&lt;p&gt;redis支持多语言实现的客户端访问，redis-rb是redis的客户端之一，基于ruby语言实现。&lt;br /&gt;
redis-rb中的方法名称与redis的一致&lt;/p&gt;
&lt;h2&gt;Resque&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/resque.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;resque是基于redis的后台任务组件，能把任何类或模块作为任务在后台执行，且自带前台管理功能，方便查看执行情况。&lt;/p&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;p&gt;1. 编写任务&lt;/p&gt;
&lt;pre&gt;
class WorkerClass
  @queue = &quot;demo&quot;
  def self.perform(args)
    sleep 3 
    puts &quot;Doing something complex with  #{args}&quot;
  end
end&lt;/pre&gt;
&lt;p&gt;2. 进入任务队列&lt;/p&gt;
&lt;pre&gt;
require &quot;resque&quot;
Resque.enqueue(WorkerClass, args)&lt;/pre&gt;
&lt;p&gt;3. 运行任务&lt;/p&gt;
&lt;h3&gt;与rails3整合&lt;/h3&gt;
&lt;p&gt;0. 配置redis&lt;br /&gt;
新增 &lt;code&gt;config/redis.yml&lt;/code&gt; 文件，加入以下内容&lt;/p&gt;
&lt;pre&gt;
defaults: &amp;amp;defaults
  host: localhost
  port: 6379

development:
  &amp;lt;&amp;lt;: *defaults

test:
  &amp;lt;&amp;lt;: *defaults

staging:
  &amp;lt;&amp;lt;: *defaults

production:
  &amp;lt;&amp;lt;: *defaults
&lt;/pre&gt;
&lt;p&gt;1. 加载resque&lt;/p&gt;
&lt;pre&gt;
echo &quot;require 'resque'&quot; &amp;gt; config/initializers/load_resque.rb
config = YAML::load(File.open(&quot;#{Rails.root}/config/redis.yml&quot;))[Rails.env]
Resque.redis = Redis.new(:host =&amp;gt; config['host'], :port =&amp;gt; config['port'])&lt;/pre&gt;
&lt;p&gt;2. 由于worker类都放在app/jobs，因此需要指定rails加载此目录&lt;br /&gt;
修改 &lt;code&gt;config/application.rb&lt;/code&gt;，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.autoload_paths += %W(#{config.root}/app/jobs)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3. 加入rake任务&lt;br /&gt;
修改 @RakeFile@，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;require &amp;#8216;resque/tasks&amp;#8217;&lt;br /&gt;
task &amp;#8220;resque:setup&amp;#8221; =&amp;gt; :environment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二句指明运行 &lt;code&gt;resque:setup&lt;/code&gt; 前先初始化rails环境&lt;/p&gt;
&lt;h3&gt;运行resque后台任务&lt;/h3&gt;
&lt;pre&gt;
QUEUE=* rake resque:work&lt;/pre&gt;
&lt;h3&gt;查看任务执行情况&lt;/h3&gt;
&lt;pre&gt;
#运行resque前台管理服务器
resque-web -p 8282&lt;/pre&gt;
&lt;p&gt;打开浏览器，访问 &lt;a href=&quot;http://0.0.0.0:8282&quot;&gt;http://0.0.0.0:8282&lt;/a&gt;&lt;br /&gt;
前台可以查看失败的worker及其日志，可以手动执行retry操作&lt;/p&gt;
&lt;h3&gt;定时任务&lt;/h3&gt;
&lt;p&gt;如需定时执行任务，可以使用 &lt;a href=&quot;https://github.com/bvandenbos/resque-scheduler&quot;&gt;resque-scheduler&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;测试&lt;/h3&gt;
&lt;p&gt;在测试的时候我们不需要测试过程与resque是异步的,否则resque执行的时候数据可能已经被清空了,使用resque_spec插件可以让resque worker立即执行&lt;/p&gt;
&lt;p&gt;详情查看 &lt;a href=&quot;https://github.com/leshill/resque_spec&quot;&gt;https://github.com/leshill/resque_spec&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://redis.io/commands&quot;&gt;Resque commands&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/defunkt/resque&quot;&gt;Resque github repository&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.redistogo.com/2010/07/26/resque-with-redis-to-go/&quot;&gt;Resque with redis to go&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://rubylearning.com/blog/2010/11/08/do-you-know-resque/&quot;&gt;Do you know resque&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.llamarada.net/?p=2202&quot;&gt;resque-scheduler, resque, rails integration, redis&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;p&gt;我对javascript语言还是很喜欢，所以对node.js这么有创意的东西，很早就开始关注了。&lt;br /&gt;
据说在实时领域的表现非常好，资源占用也不多，很想实践一番，以后正式项目有对实时性的需求，就可以放心地使用node.js了。&lt;/p&gt;
&lt;p&gt;所以我决定将 &lt;a href=&quot;https://github.com/saberma/55true&quot;&gt;55true&lt;/a&gt; 重新开发，加入即时问答的机制，普通功能开发上使用rails3，而实时性上应用node.js。&lt;br /&gt;
虽然node.js相关的框架已经非常多，也有类似于rails的MVC框架，但是毕竟发展时间还不长，所以使用rails结合node.js的方式进行开发是个不错的发展方式，各取所长。&lt;/p&gt;
&lt;h2&gt;Node.js&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/nodejs.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;node.js是一种可以用js来编写的服务端程序&lt;/p&gt;
&lt;p&gt;这次使用 &lt;a href=&quot;https://github.com/maccman/juggernaut&quot;&gt;https://github.com/maccman/juggernaut&lt;/a&gt; 框架，结合redis，实现rails与node.js服务的交互。&lt;br /&gt;
node.js的发展非常的快，有类似于rails bundler的插件管理工具npm，但为降低node.js相关框架的管理复杂度，我直接将juggernaut及其依赖的js文件都放在 &lt;a href=&quot;https://github.com/saberma/55true&quot;&gt;55true&lt;/a&gt; 的根目录。&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;pre&gt;
cd ~/Downloads
wget http://nodejs.org/dist/node-v0.2.6.tar.gz
tar -xzvf node-v0.2.6.tar.gz
cd node-v0.2.4
./configure
make
make install&lt;/pre&gt;
&lt;h3&gt;Juggernaut&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/maccman/juggernaut&quot;&gt;Juggernaut&lt;/a&gt; 是包含服务端及客户端的实时解决方案，最初服务端是用ruby eventmachine实现的。&lt;br /&gt;
node.js出来后，整个框架就用node.js重写了&lt;/p&gt;
&lt;h3&gt;启动Juggeranut&lt;/h3&gt;
&lt;pre&gt;
#node server.js
sudo node server.js&lt;/pre&gt;
&lt;p&gt;使用root帐号启动，否则firefox客户端访问会报错&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Flash is optional, but it&amp;#8217;s the default fallback for Firefox (until the beta is released). Start the server using root if you want Flash support. It needs to open a restricted por&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Redis&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/redis.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;redis是类似于memcached的高性能键值缓存工具，但它支持更多的值类型、功能更加丰富，且可以将存储内容定时持久化到磁盘中，是NoSQL家庭中出色的一员&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;pre&gt;
wget https://github.com/antirez/redis/tarball/2.2.0-rc2
tar -xzvf antirez-redis-2.2.0-rc2-0-g0540df2.tar.gz
cd antirez-redis-b703b5d
make
sudo make install&lt;/pre&gt;
&lt;h3&gt;客户端&lt;/h3&gt;
&lt;pre&gt;
redis-cli&lt;/pre&gt;
&lt;h3&gt;调试&lt;/h3&gt;
&lt;p&gt;运行客户端后，输入命令&lt;/p&gt;
&lt;pre&gt;
monitor&lt;/pre&gt;
&lt;h3&gt;注意expire&lt;/h3&gt;
&lt;p&gt;redis的expire命令有限制，执行此命令后，对key进行的任何操作都将先对key进行清空操作，详见 &lt;a href=&quot;http://redis.io/topics/expire&quot;&gt;http://redis.io/topics/expire&lt;/a&gt;&lt;br /&gt;
2.1.3以上版本不存在这个限制，但未正式发布稳定版，2.1正式发布时会更改为2.2版本&lt;/p&gt;
&lt;p&gt;具体表现如下:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;redis&amp;gt; set a 100&lt;br /&gt;
OK&lt;br /&gt;
redis&amp;gt; expire a 600&lt;br /&gt;
(integer) 1&lt;br /&gt;
redis&amp;gt; incr a&lt;br /&gt;
(integer) 1&lt;br /&gt;
redis&amp;gt; get a&lt;br /&gt;
&amp;#8220;1&amp;#8221; #正常来说，应返回101，因为还key还没有过期&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果对这个限制敏感，可以尝试 &lt;a href=&quot;http://redis.io/download&quot;&gt;2.2.0rc2版本&lt;/a&gt;&lt;br /&gt;
&lt;code&gt;make&lt;/code&gt; 之后最好再执行下 &lt;code&gt;make test&lt;/code&gt; 测试是否正常，我试过，确实不再存在上面说的奇怪表现&lt;/p&gt;
&lt;h3&gt;redis-rb&lt;/h3&gt;
&lt;p&gt;redis支持多语言实现的客户端访问，redis-rb是redis的客户端之一，基于ruby语言实现。&lt;br /&gt;
redis-rb中的方法名称与redis的一致&lt;/p&gt;
&lt;h2&gt;Resque&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/redis/resque.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;resque是基于redis的后台任务组件，能把任何类或模块作为任务在后台执行，且自带前台管理功能，方便查看执行情况。&lt;/p&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;p&gt;1. 编写任务&lt;/p&gt;
&lt;pre&gt;
class WorkerClass
  @queue = &quot;demo&quot;
  def self.perform(args)
    sleep 3 
    puts &quot;Doing something complex with  #{args}&quot;
  end
end&lt;/pre&gt;
&lt;p&gt;2. 进入任务队列&lt;/p&gt;
&lt;pre&gt;
require &quot;resque&quot;
Resque.enqueue(WorkerClass, args)&lt;/pre&gt;
&lt;p&gt;3. 运行任务&lt;/p&gt;
&lt;h3&gt;与rails3整合&lt;/h3&gt;
&lt;p&gt;0. 配置redis&lt;br /&gt;
新增 &lt;code&gt;config/redis.yml&lt;/code&gt; 文件，加入以下内容&lt;/p&gt;
&lt;pre&gt;
defaults: &amp;amp;defaults
  host: localhost
  port: 6379

development:
  &amp;lt;&amp;lt;: *defaults

test:
  &amp;lt;&amp;lt;: *defaults

staging:
  &amp;lt;&amp;lt;: *defaults

production:
  &amp;lt;&amp;lt;: *defaults
&lt;/pre&gt;
&lt;p&gt;1. 加载resque&lt;/p&gt;
&lt;pre&gt;
echo &quot;require 'resque'&quot; &amp;gt; config/initializers/load_resque.rb
config = YAML::load(File.open(&quot;#{Rails.root}/config/redis.yml&quot;))[Rails.env]
Resque.redis = Redis.new(:host =&amp;gt; config['host'], :port =&amp;gt; config['port'])&lt;/pre&gt;
&lt;p&gt;2. 由于worker类都放在app/jobs，因此需要指定rails加载此目录&lt;br /&gt;
修改 &lt;code&gt;config/application.rb&lt;/code&gt;，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;config.autoload_paths += %W(#{config.root}/app/jobs)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3. 加入rake任务&lt;br /&gt;
修改 @RakeFile@，加入以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;require &amp;#8216;resque/tasks&amp;#8217;&lt;br /&gt;
task &amp;#8220;resque:setup&amp;#8221; =&amp;gt; :environment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二句指明运行 &lt;code&gt;resque:setup&lt;/code&gt; 前先初始化rails环境&lt;/p&gt;
&lt;h3&gt;运行resque后台任务&lt;/h3&gt;
&lt;pre&gt;
QUEUE=* rake resque:work&lt;/pre&gt;
&lt;h3&gt;查看任务执行情况&lt;/h3&gt;
&lt;pre&gt;
#运行resque前台管理服务器
resque-web -p 8282&lt;/pre&gt;
&lt;p&gt;打开浏览器，访问 &lt;a href=&quot;http://0.0.0.0:8282&quot;&gt;http://0.0.0.0:8282&lt;/a&gt;&lt;br /&gt;
前台可以查看失败的worker及其日志，可以手动执行retry操作&lt;/p&gt;
&lt;h3&gt;定时任务&lt;/h3&gt;
&lt;p&gt;如需定时执行任务，可以使用 &lt;a href=&quot;https://github.com/bvandenbos/resque-scheduler&quot;&gt;resque-scheduler&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;测试&lt;/h3&gt;
&lt;p&gt;在测试的时候我们不需要测试过程与resque是异步的,否则resque执行的时候数据可能已经被清空了,使用resque_spec插件可以让resque worker立即执行&lt;/p&gt;
&lt;p&gt;详情查看 &lt;a href=&quot;https://github.com/leshill/resque_spec&quot;&gt;https://github.com/leshill/resque_spec&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://redis.io/commands&quot;&gt;Resque commands&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/defunkt/resque&quot;&gt;Resque github repository&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.redistogo.com/2010/07/26/resque-with-redis-to-go/&quot;&gt;Resque with redis to go&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://rubylearning.com/blog/2010/11/08/do-you-know-resque/&quot;&gt;Do you know resque&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.llamarada.net/?p=2202&quot;&gt;resque-scheduler, resque, rails integration, redis&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565429/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565429/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565429/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565429/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/rails/2011/01/10/node-js-juggeraut-redis-resque.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565429/6499449</fs:itemid><pubDate>Mon, 10 Jan 2011 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/rails/2011/01/10/node-js-juggeraut-redis-resque</guid></item><item><title>部署rails项目到heroku，并使用mongohq文档数据库</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565430/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/rails/2010/12/23/deploy-rails-app-to-heroku-and-use-mongohq</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;h2&gt;简介&lt;/h2&gt;
&lt;h3&gt;Heroku&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/heroku/heroku.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;heroku作为rails项目的托管商，具有功能完备、操作简单等优点，而且提供免费服务&lt;br /&gt;
免费项目只提供一个应用服务进程(即只同时在线1个)，提供5m免费关系型数据库&lt;/p&gt;
&lt;h3&gt;MongoHQ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/heroku/mongohq.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;mongohq提供mongodb文档数据库的在线存储服务&lt;br /&gt;
免费帐号每个数据库有16m的存储空间，heroku已经支持mongohq，将之纳入addons中&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;因此，想要把迷你型或实验性的项目放到网上，又想免费，heroku是最好的选择了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这几天想要查找域名，需要批量查找5-8位拼音组合的.com域名(四位的已绝迹)&lt;br /&gt;
所以写了个程序批量查找有效域名，放到heroku上。&lt;/p&gt;
&lt;h2&gt;安装heroku&lt;/h2&gt;
&lt;pre&gt;
gem install heroku --no-ri -no-rdoc&lt;/pre&gt;
&lt;h3&gt;安装其他&lt;/h3&gt;
&lt;p&gt;rails3及mongodb等环境的安装，可参考 &lt;a href=&quot;http://github.com/saberma/shopqi&quot;&gt;http://github.com/saberma/shopqi&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;新增项目&lt;/h2&gt;
&lt;h3&gt;新增rails项目&lt;/h3&gt;
&lt;pre&gt;
rails new test_heroku
cd test_heroku
#修改GemFile，加入必要的Gem
#...
#生成mongoid配置文件
rails g mongoid:config
git init
git add .
git commit -m &quot;new app&quot;&lt;/pre&gt;
&lt;h3&gt;新建heroku app&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;先到 &lt;a href=&quot;heroku.com&quot;&gt;heroku.com&lt;/a&gt; 注册帐号&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
heroku create test_heroku
#按提示输入注册时的帐号和密码&lt;/pre&gt;
&lt;h3&gt;加入MongoHQ Addon&lt;/h3&gt;
&lt;pre&gt;
heroku addons:add mongohq:free
#查看新增的数据库信息(MONGOHQ_URL部分)
heroku config --long&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;config/mongoid.yml&lt;/code&gt;, production只留以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;production:&lt;br /&gt;
  uri: &amp;lt;%= &lt;span class=&quot;caps&quot;&gt;ENV&lt;/span&gt;[&amp;#8216;MONGOHQ_URL&amp;#8217;] %&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;mongoid已经支持uri参数了，不需要像mongohq官方文档描述的那样，增加config/initialize/mongo.rb文件&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;部署至heroku&lt;/h3&gt;
&lt;pre&gt;
git push heroku master&lt;/pre&gt;
&lt;h3&gt;测试&lt;/h3&gt;
&lt;p&gt;浏览器访问 &lt;a href=&quot;http://test_heroku.heroku.com&quot;&gt;http://test_heroku.heroku.com&lt;/a&gt; ，看是否显示rails的信息&lt;/p&gt;
&lt;h2&gt;在MongoHQ中查看数据&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;登录 &lt;a href=&quot;https://mongohq.com/databases&quot;&gt;MongoHQ&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;点击右边栏按钮&amp;quot;Add a Remote Connection&amp;quot;&lt;/li&gt;
	&lt;li&gt;输入Name和URI，确定&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;URI为heroku中通过 &lt;code&gt;heroku config --long&lt;/code&gt; 查看到的MONGOHQ_URL内容&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;heroku常用命令&lt;/h2&gt;
&lt;pre&gt;
# 运行rake
heroku rake db:seed
# 运行控制台
# 查看运行进行
heroku ps
# 查看日志
heroku logs
# 查看参数
heroku config --long
# 重命名(子域名)
heroku rename newname
heroku console&lt;/pre&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://docs.heroku.com/&quot;&gt;Heroku Docs&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://docs.mongohq.com/ruby-heroku-addon&quot;&gt;MongoHQ Heroku Addon&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/nbrochu/bulkdom&quot;&gt;Batch Search Domains&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://vimim.googlecode.com/files/fcitx.phrase.pinyin.txt&quot;&gt;Fcitx Phrase Pinyin&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://open-phrase.googlecode.com/files/phrase_pinyin_freq_sc_20090402.txt.bz2&quot;&gt;Pinyin Frequence&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;h2&gt;简介&lt;/h2&gt;
&lt;h3&gt;Heroku&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/heroku/heroku.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;heroku作为rails项目的托管商，具有功能完备、操作简单等优点，而且提供免费服务&lt;br /&gt;
免费项目只提供一个应用服务进程(即只同时在线1个)，提供5m免费关系型数据库&lt;/p&gt;
&lt;h3&gt;MongoHQ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/heroku/mongohq.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;mongohq提供mongodb文档数据库的在线存储服务&lt;br /&gt;
免费帐号每个数据库有16m的存储空间，heroku已经支持mongohq，将之纳入addons中&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;因此，想要把迷你型或实验性的项目放到网上，又想免费，heroku是最好的选择了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这几天想要查找域名，需要批量查找5-8位拼音组合的.com域名(四位的已绝迹)&lt;br /&gt;
所以写了个程序批量查找有效域名，放到heroku上。&lt;/p&gt;
&lt;h2&gt;安装heroku&lt;/h2&gt;
&lt;pre&gt;
gem install heroku --no-ri -no-rdoc&lt;/pre&gt;
&lt;h3&gt;安装其他&lt;/h3&gt;
&lt;p&gt;rails3及mongodb等环境的安装，可参考 &lt;a href=&quot;http://github.com/saberma/shopqi&quot;&gt;http://github.com/saberma/shopqi&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;新增项目&lt;/h2&gt;
&lt;h3&gt;新增rails项目&lt;/h3&gt;
&lt;pre&gt;
rails new test_heroku
cd test_heroku
#修改GemFile，加入必要的Gem
#...
#生成mongoid配置文件
rails g mongoid:config
git init
git add .
git commit -m &quot;new app&quot;&lt;/pre&gt;
&lt;h3&gt;新建heroku app&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;先到 &lt;a href=&quot;heroku.com&quot;&gt;heroku.com&lt;/a&gt; 注册帐号&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
heroku create test_heroku
#按提示输入注册时的帐号和密码&lt;/pre&gt;
&lt;h3&gt;加入MongoHQ Addon&lt;/h3&gt;
&lt;pre&gt;
heroku addons:add mongohq:free
#查看新增的数据库信息(MONGOHQ_URL部分)
heroku config --long&lt;/pre&gt;
&lt;p&gt;修改 &lt;code&gt;config/mongoid.yml&lt;/code&gt;, production只留以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;production:&lt;br /&gt;
  uri: &amp;lt;%= &lt;span class=&quot;caps&quot;&gt;ENV&lt;/span&gt;[&amp;#8216;MONGOHQ_URL&amp;#8217;] %&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;mongoid已经支持uri参数了，不需要像mongohq官方文档描述的那样，增加config/initialize/mongo.rb文件&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;部署至heroku&lt;/h3&gt;
&lt;pre&gt;
git push heroku master&lt;/pre&gt;
&lt;h3&gt;测试&lt;/h3&gt;
&lt;p&gt;浏览器访问 &lt;a href=&quot;http://test_heroku.heroku.com&quot;&gt;http://test_heroku.heroku.com&lt;/a&gt; ，看是否显示rails的信息&lt;/p&gt;
&lt;h2&gt;在MongoHQ中查看数据&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;登录 &lt;a href=&quot;https://mongohq.com/databases&quot;&gt;MongoHQ&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;点击右边栏按钮&amp;quot;Add a Remote Connection&amp;quot;&lt;/li&gt;
	&lt;li&gt;输入Name和URI，确定&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;URI为heroku中通过 &lt;code&gt;heroku config --long&lt;/code&gt; 查看到的MONGOHQ_URL内容&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;heroku常用命令&lt;/h2&gt;
&lt;pre&gt;
# 运行rake
heroku rake db:seed
# 运行控制台
# 查看运行进行
heroku ps
# 查看日志
heroku logs
# 查看参数
heroku config --long
# 重命名(子域名)
heroku rename newname
heroku console&lt;/pre&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://docs.heroku.com/&quot;&gt;Heroku Docs&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://docs.mongohq.com/ruby-heroku-addon&quot;&gt;MongoHQ Heroku Addon&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/nbrochu/bulkdom&quot;&gt;Batch Search Domains&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://vimim.googlecode.com/files/fcitx.phrase.pinyin.txt&quot;&gt;Fcitx Phrase Pinyin&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://open-phrase.googlecode.com/files/phrase_pinyin_freq_sc_20090402.txt.bz2&quot;&gt;Pinyin Frequence&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565430/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565430/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565430/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565430/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/rails/2010/12/23/deploy-rails-app-to-heroku-and-use-mongohq.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565430/6499449</fs:itemid><pubDate>Thu, 23 Dec 2010 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/rails/2010/12/23/deploy-rails-app-to-heroku-and-use-mongohq</guid></item><item><title>在Ubuntu环境下安装最土团购开源php程序</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565431/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/php/2010/12/18/zuitu-tuangou-php-install-in-ubuntu</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;h2&gt;下载&lt;/h2&gt;
&lt;p&gt;在最土官网下载&lt;br /&gt;
&lt;a href=&quot;http://notice.zuitu.com/down/ZuituGo_V1.6.tar.gz&quot;&gt;http://notice.zuitu.com/down/ZuituGo_V1.6.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;安装mysql数据库&lt;/h2&gt;
&lt;p&gt;sudo apt-get install mysql-server&lt;/p&gt;
&lt;h2&gt;安装php环境&lt;/h2&gt;
&lt;pre&gt;
#apache
sudo apt-get install apache2
#php5(默认带有mbstring组件)
sudo apt-get install php5
#配置APACHE+PHP
sudo apt-get install libapache2-mod-php5
sudo /etc/init.d/apache2 restart
#mysql相关
sudo apt-get install libapache2-mod-auth-mysql
sudo apt-get install php5-mysql
sudo /etc/init.d/apache2 restart&lt;/pre&gt;
&lt;h2&gt;安装程序&lt;/h2&gt;
&lt;p&gt;将压缩包中的wwwroot下的内容解压至/var/www目录下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如需修改apache webroot黙认路径，请修改/etc/apache2/sites-enabled/000-default文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
#修改目录归属于当前用户saberma
chown saberma /var/www
#修改目录可写权限
chmod a+w static/user
chmod a+w static/team
chmod a+w include/compiled
chmod a+w include/configure
chmod a+w include/data/
chmod a+w include/template/&lt;/pre&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;p&gt;浏览器打开 &lt;code&gt;http://localhost/install.php&lt;/code&gt;&lt;br /&gt;
输入数据库密码后点击安装即可&lt;/p&gt;
&lt;p&gt;安装完成后需要手动删除install.php&lt;/p&gt;
&lt;pre&gt;
rm /var/www/install.php&lt;/pre&gt;
&lt;h2&gt;调试&lt;/h2&gt;
&lt;h3&gt;打开日志&lt;/h3&gt;
&lt;p&gt;为方便初期调试错误，需要打开错误日志输出功能&lt;br /&gt;
修改 &lt;code&gt;/etc/php5/apache2/php.ini&lt;/code&gt; 的以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;error_reporting = E_ALL&lt;br /&gt;
display_error = on&lt;br /&gt;
html_errors = on&lt;br /&gt;
log_errors = off&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;查看php环境信息&lt;/h3&gt;
&lt;p&gt;在网站根目录中新增phpinfo.php文件，内容如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;?php phpinfo()?&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;浏览器打开phpinfo.php，即可看到环境信息&lt;/p&gt;
&lt;h2&gt;部署&lt;/h2&gt;
&lt;p&gt;一般情况下，PHP的虚拟空间只能使用ftp，而项目代码使用git进行版本控制&lt;br /&gt;
为了让git管理下的项目代码能够直接发送至ftp，需要安装 &lt;a href=&quot;http://github.com/resmo/git-ftp&quot;&gt;git-ftp&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;
#ubuntu10.04下的安装过程
sudo -s
add-apt-repository ppa:resmo/git-ftp
aptitude update
aptitude install git-ftp
exit&lt;/pre&gt;
&lt;p&gt;配置ftp地址、用户名及密码&lt;/p&gt;
&lt;pre&gt;
git config git-ftp.user saberma
git config git-ftp.url ftp.example.com
git config git-ftp.password secr3t&lt;/pre&gt;
&lt;p&gt;修改文件后，使用以下命令部署&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;git ftp push&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.zuitu.com/download_new.html&quot;&gt;最土官网下载说明&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;h2&gt;下载&lt;/h2&gt;
&lt;p&gt;在最土官网下载&lt;br /&gt;
&lt;a href=&quot;http://notice.zuitu.com/down/ZuituGo_V1.6.tar.gz&quot;&gt;http://notice.zuitu.com/down/ZuituGo_V1.6.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;安装mysql数据库&lt;/h2&gt;
&lt;p&gt;sudo apt-get install mysql-server&lt;/p&gt;
&lt;h2&gt;安装php环境&lt;/h2&gt;
&lt;pre&gt;
#apache
sudo apt-get install apache2
#php5(默认带有mbstring组件)
sudo apt-get install php5
#配置APACHE+PHP
sudo apt-get install libapache2-mod-php5
sudo /etc/init.d/apache2 restart
#mysql相关
sudo apt-get install libapache2-mod-auth-mysql
sudo apt-get install php5-mysql
sudo /etc/init.d/apache2 restart&lt;/pre&gt;
&lt;h2&gt;安装程序&lt;/h2&gt;
&lt;p&gt;将压缩包中的wwwroot下的内容解压至/var/www目录下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如需修改apache webroot黙认路径，请修改/etc/apache2/sites-enabled/000-default文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;
#修改目录归属于当前用户saberma
chown saberma /var/www
#修改目录可写权限
chmod a+w static/user
chmod a+w static/team
chmod a+w include/compiled
chmod a+w include/configure
chmod a+w include/data/
chmod a+w include/template/&lt;/pre&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;p&gt;浏览器打开 &lt;code&gt;http://localhost/install.php&lt;/code&gt;&lt;br /&gt;
输入数据库密码后点击安装即可&lt;/p&gt;
&lt;p&gt;安装完成后需要手动删除install.php&lt;/p&gt;
&lt;pre&gt;
rm /var/www/install.php&lt;/pre&gt;
&lt;h2&gt;调试&lt;/h2&gt;
&lt;h3&gt;打开日志&lt;/h3&gt;
&lt;p&gt;为方便初期调试错误，需要打开错误日志输出功能&lt;br /&gt;
修改 &lt;code&gt;/etc/php5/apache2/php.ini&lt;/code&gt; 的以下内容&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;error_reporting = E_ALL&lt;br /&gt;
display_error = on&lt;br /&gt;
html_errors = on&lt;br /&gt;
log_errors = off&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;查看php环境信息&lt;/h3&gt;
&lt;p&gt;在网站根目录中新增phpinfo.php文件，内容如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;?php phpinfo()?&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;浏览器打开phpinfo.php，即可看到环境信息&lt;/p&gt;
&lt;h2&gt;部署&lt;/h2&gt;
&lt;p&gt;一般情况下，PHP的虚拟空间只能使用ftp，而项目代码使用git进行版本控制&lt;br /&gt;
为了让git管理下的项目代码能够直接发送至ftp，需要安装 &lt;a href=&quot;http://github.com/resmo/git-ftp&quot;&gt;git-ftp&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;
#ubuntu10.04下的安装过程
sudo -s
add-apt-repository ppa:resmo/git-ftp
aptitude update
aptitude install git-ftp
exit&lt;/pre&gt;
&lt;p&gt;配置ftp地址、用户名及密码&lt;/p&gt;
&lt;pre&gt;
git config git-ftp.user saberma
git config git-ftp.url ftp.example.com
git config git-ftp.password secr3t&lt;/pre&gt;
&lt;p&gt;修改文件后，使用以下命令部署&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;git ftp push&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.zuitu.com/download_new.html&quot;&gt;最土官网下载说明&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565431/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565431/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565431/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565431/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/php/2010/12/18/zuitu-tuangou-php-install-in-ubuntu.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565431/6499449</fs:itemid><pubDate>Sat, 18 Dec 2010 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/php/2010/12/18/zuitu-tuangou-php-install-in-ubuntu</guid></item><item><title>开发iphone游戏确实能赚钱</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565432/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/iphone/2010/11/26/iphone-game-developer-do-to-make-money</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;h2&gt;收到iphone汇过来的美元了&lt;/h2&gt;
&lt;p&gt;上个月，我发现我的信用卡帐号多了164.62美元(显示-164.62)，难道苹果结算了，想想应该不可能，我那小游戏没那么快能卖够150美元的，再说了要是结了总会给我发邮件通知吧。&lt;/p&gt;
&lt;p&gt;所以我就想是不是银行出错了，就在我犹豫着是用了再说，还是主动报告给银行的时候，我登录了 &lt;a href=&quot;https://itunesconnect.apple.com&quot;&gt;https://itunesconnect.apple.com&lt;/a&gt; (之前都是用 &lt;a href=&quot;appannie.com&quot;&gt;appannie.com&lt;/a&gt; 看报表，直观很多)，咦:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/iphone/payment.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;图片显示在9月2日apple确实汇了美元过来了:)，根据apple开发协议，都是月初结账，150美元起才会汇款&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开发这个小游戏的初衷就是想了解下iphone程序及游戏的开发流程，所以能不能赚钱、赚多赚少都没有关系&lt;br /&gt;
现在出乎我意料的是，竟然不会亏钱了，之前加入apple会员时，交纳的99美元年费也回来了，所以结论是：&lt;/p&gt;
&lt;p&gt;&lt;b&gt;如果你专注iphone游戏开发，绝对是可以赚到钱的&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;我在6月份辞职后就不再花精力在iphone app的开发上了，专注于 &lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;shopqi独立网店平台&lt;/a&gt; 的开发，因为人的精力有限，要把事情做好的话，同一时间只能做一件事&lt;/p&gt;
&lt;h2&gt;如果您准备进入iphone开发领域，我给点小建议:&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;创意不是最重要的，有创意最好，没创意就先做点小的，掌握技术、市场，熟悉这些后一有创意就可以快速开发出来了，关注是能不能做到精致&lt;/li&gt;
	&lt;li&gt;宣传很重要，一定要在各大iphone论坛发贴介绍，特别是国内的 &lt;a href=&quot;http://www.cocoachina.com&quot;&gt;cocoachina.com&lt;/a&gt; ，发放推广码求review&lt;/li&gt;
	&lt;li&gt;一定要经常更新，记住敏捷开发中的 &lt;code&gt;小步快进&lt;/code&gt; 原则，apple的推广码有数量限制，每次更新，推广码数量也会重新起算&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;游戏的主页: &lt;a href=&quot;http://www.55xiaoyou.com&quot;&gt;http://www.55xiaoyou.com&lt;/a&gt;&lt;br /&gt;
游戏源代码地址: &lt;a href=&quot;http://github.com/saberma/BrainShot&quot;&gt;http://github.com/saberma/BrainShot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;BrainShot具有以下特征&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;基于cocos2d开发(&lt;a href=&quot;http://www.cocos2d-iphone.org/&quot;&gt;http://www.cocos2d-iphone.org&lt;/a&gt;)&lt;/li&gt;
	&lt;li&gt;兼容iphone,ipad&lt;/li&gt;
	&lt;li&gt;兼容免费版、收费版，用户下载的免费版可以直接升级至收费版(即应用了In App Purchases)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;对初学者还是有点参考价值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;说说在此之前的另一个iphone app&lt;/h2&gt;
&lt;p&gt;如果您有iphone，但没有mac机，可以参考我之前写的文章 &lt;a href=&quot;/2010/02/24/iphone-development.html&quot;&gt;在ubuntu上开发iphone app&lt;/a&gt;&lt;br /&gt;
相应的程序源代码地址: &lt;a href=&quot;http://github.com/saberma/iphone&quot;&gt;http://github.com/saberma/iphone&lt;/a&gt;&lt;br /&gt;
此demo程序实现以下功能：&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;显示客户用户名等信息的列表，可进行增删改操作&lt;/li&gt;
	&lt;li&gt;可以给客户拍照，并保存&lt;/li&gt;
	&lt;li&gt;即时将客户信息无线上传至远程服务端&lt;/li&gt;
	&lt;li&gt;支持mac平台下开发、ubuntu环境下开发&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个程序是以前公司安排的demo开发任务，给意向客户演示用的，demo包括两个后台服务端和iphone客户端两部分，难度很大。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;之前没有接触过mac操作系统、开发环境 &lt;code&gt;XCode&lt;/code&gt; 不懂、开发语言 &lt;code&gt;Object C&lt;/code&gt; 、相应的开发框架 &lt;code&gt;cocos2d&lt;/code&gt; 也不了解&lt;/li&gt;
	&lt;li&gt;时间很紧，就10天，白天上班还得开发另一个项目(进度也很急)的工作流引擎，只能晚上做&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;但是，最后还是做出来了，每天晚上做到12点左右，累是很累(之后连续半年肚脐对应的后背颈椎老痛)，却很开心，这是我最喜欢的项目之一。&lt;br /&gt;
现在每每回想起来，都会对我的领导谢总和张总心存感激之情，给了我太多的实践机会。&lt;/p&gt;</content><content:encoded>&lt;h2&gt;收到iphone汇过来的美元了&lt;/h2&gt;
&lt;p&gt;上个月，我发现我的信用卡帐号多了164.62美元(显示-164.62)，难道苹果结算了，想想应该不可能，我那小游戏没那么快能卖够150美元的，再说了要是结了总会给我发邮件通知吧。&lt;/p&gt;
&lt;p&gt;所以我就想是不是银行出错了，就在我犹豫着是用了再说，还是主动报告给银行的时候，我登录了 &lt;a href=&quot;https://itunesconnect.apple.com&quot;&gt;https://itunesconnect.apple.com&lt;/a&gt; (之前都是用 &lt;a href=&quot;appannie.com&quot;&gt;appannie.com&lt;/a&gt; 看报表，直观很多)，咦:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/article/iphone/payment.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;图片显示在9月2日apple确实汇了美元过来了:)，根据apple开发协议，都是月初结账，150美元起才会汇款&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开发这个小游戏的初衷就是想了解下iphone程序及游戏的开发流程，所以能不能赚钱、赚多赚少都没有关系&lt;br /&gt;
现在出乎我意料的是，竟然不会亏钱了，之前加入apple会员时，交纳的99美元年费也回来了，所以结论是：&lt;/p&gt;
&lt;p&gt;&lt;b&gt;如果你专注iphone游戏开发，绝对是可以赚到钱的&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;我在6月份辞职后就不再花精力在iphone app的开发上了，专注于 &lt;a href=&quot;https://github.com/saberma/shopqi&quot;&gt;shopqi独立网店平台&lt;/a&gt; 的开发，因为人的精力有限，要把事情做好的话，同一时间只能做一件事&lt;/p&gt;
&lt;h2&gt;如果您准备进入iphone开发领域，我给点小建议:&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;创意不是最重要的，有创意最好，没创意就先做点小的，掌握技术、市场，熟悉这些后一有创意就可以快速开发出来了，关注是能不能做到精致&lt;/li&gt;
	&lt;li&gt;宣传很重要，一定要在各大iphone论坛发贴介绍，特别是国内的 &lt;a href=&quot;http://www.cocoachina.com&quot;&gt;cocoachina.com&lt;/a&gt; ，发放推广码求review&lt;/li&gt;
	&lt;li&gt;一定要经常更新，记住敏捷开发中的 &lt;code&gt;小步快进&lt;/code&gt; 原则，apple的推广码有数量限制，每次更新，推广码数量也会重新起算&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;游戏的主页: &lt;a href=&quot;http://www.55xiaoyou.com&quot;&gt;http://www.55xiaoyou.com&lt;/a&gt;&lt;br /&gt;
游戏源代码地址: &lt;a href=&quot;http://github.com/saberma/BrainShot&quot;&gt;http://github.com/saberma/BrainShot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;BrainShot具有以下特征&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;基于cocos2d开发(&lt;a href=&quot;http://www.cocos2d-iphone.org/&quot;&gt;http://www.cocos2d-iphone.org&lt;/a&gt;)&lt;/li&gt;
	&lt;li&gt;兼容iphone,ipad&lt;/li&gt;
	&lt;li&gt;兼容免费版、收费版，用户下载的免费版可以直接升级至收费版(即应用了In App Purchases)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;对初学者还是有点参考价值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;说说在此之前的另一个iphone app&lt;/h2&gt;
&lt;p&gt;如果您有iphone，但没有mac机，可以参考我之前写的文章 &lt;a href=&quot;/2010/02/24/iphone-development.html&quot;&gt;在ubuntu上开发iphone app&lt;/a&gt;&lt;br /&gt;
相应的程序源代码地址: &lt;a href=&quot;http://github.com/saberma/iphone&quot;&gt;http://github.com/saberma/iphone&lt;/a&gt;&lt;br /&gt;
此demo程序实现以下功能：&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;显示客户用户名等信息的列表，可进行增删改操作&lt;/li&gt;
	&lt;li&gt;可以给客户拍照，并保存&lt;/li&gt;
	&lt;li&gt;即时将客户信息无线上传至远程服务端&lt;/li&gt;
	&lt;li&gt;支持mac平台下开发、ubuntu环境下开发&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个程序是以前公司安排的demo开发任务，给意向客户演示用的，demo包括两个后台服务端和iphone客户端两部分，难度很大。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;之前没有接触过mac操作系统、开发环境 &lt;code&gt;XCode&lt;/code&gt; 不懂、开发语言 &lt;code&gt;Object C&lt;/code&gt; 、相应的开发框架 &lt;code&gt;cocos2d&lt;/code&gt; 也不了解&lt;/li&gt;
	&lt;li&gt;时间很紧，就10天，白天上班还得开发另一个项目(进度也很急)的工作流引擎，只能晚上做&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;但是，最后还是做出来了，每天晚上做到12点左右，累是很累(之后连续半年肚脐对应的后背颈椎老痛)，却很开心，这是我最喜欢的项目之一。&lt;br /&gt;
现在每每回想起来，都会对我的领导谢总和张总心存感激之情，给了我太多的实践机会。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565432/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565432/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565432/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565432/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/iphone/2010/11/26/iphone-game-developer-do-to-make-money.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565432/6499449</fs:itemid><pubDate>Fri, 26 Nov 2010 16:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/iphone/2010/11/26/iphone-game-developer-do-to-make-money</guid></item><item><title>应用gitflow建立代码开发标准化流程</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565433/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/git/2010/10/25/git-flow</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;我们已经使用git进行版本管理，为更好地进行协同开发工作，需要对流程进行规范&lt;br /&gt;
&lt;strong&gt;&lt;a href=&quot;http://github.com/saberma/shopqi&quot;&gt;shopqi网店平台&lt;/a&gt; 产品开发将遵循此流程&lt;/strong&gt;, 以下对git的开发流程进行描述&lt;/p&gt;
&lt;h2&gt;开发流程&lt;/h2&gt;
&lt;p&gt;在开发的过程中存在以下情况:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;情况1: 开发新特性&lt;br /&gt;
情况2: 紧急修正生产环境中报告的Bug&lt;br /&gt;
情况3: 支援其他成员，帮忙调试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;假如我们在master主分支中进行新特性的开发，这时如果发生情况2，处理起来比较麻烦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;正确的实践应该是:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;master主分支保致与对外发布的版本同步&lt;/li&gt;
	&lt;li&gt;每个新特性(feature)都有独立的分支&lt;/li&gt;
	&lt;li&gt;将多个新特性(feature)分支合并至发布(release)分支&lt;/li&gt;
	&lt;li&gt;待发布(release)分支完成后再合并至master主分支，正式对外发布&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;应用gitflow&lt;/h2&gt;
&lt;p&gt;gitflow是开源的标准化git流程协助工具，项目地址在 &lt;a href=&quot;http://github.com/nvie/gitflow&quot;&gt;http://github.com/nvie/gitflow&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;安装(Ubuntu环境)&lt;/h3&gt;
&lt;pre&gt;
wget -qO- --no-check-certificate http://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | sudo sh
sudo apt-get install opt&lt;/pre&gt;
&lt;p&gt;其他操作系统安装gitflow请参考 &lt;a href=&quot;http://github.com/nvie/gitflow&quot;&gt;http://github.com/nvie/gitflow&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;使用方法&lt;/h3&gt;
&lt;pre&gt;
#初始化(提问时回车就好)
git flow init&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;开发新特征&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow feature start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow feature finish &amp;lt;name&amp;gt;
#列出新特征分支
git flow feature&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;准备发布版本&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow release start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow release finish &amp;lt;name&amp;gt;
#列出发布分支
git flow release&lt;/pre&gt;
&lt;p&gt;&amp;lt; base &amp;gt;是位于develop分支的commit&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正紧急Bug&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow hotfix start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow hotfix finish &amp;lt;name&amp;gt;
#列出修正分支
git flow hotfix&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;支援其他成员工作&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow support start &amp;lt;name&amp;gt; &amp;lt;base&amp;gt;
#没有finish?(待实践)
#列出支援分支
git flow support&lt;/pre&gt;
&lt;p&gt;&amp;lt; base &amp;gt;是位于master分支的commit&lt;/p&gt;
&lt;h2&gt;结合github&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;上传未完成的feature分支&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
#git push REMOTENAME BRANCHNAME
#一般情况下REMOTENAME即为origin, BRANCHNAME为以feature/为前缀的分支名称
git push origin feature/orders&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意:对于develop分支，由于所有成员的本地库中都有，所以不能上传&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;http://nvie.com/posts/a-successful-git-branching-model/&quot;&gt;A successful Git branching model&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/&quot;&gt;Why aren&amp;#8217;t you using git-flow?&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://help.github.com/remotes/&quot;&gt;github remotes&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content><content:encoded>&lt;p&gt;我们已经使用git进行版本管理，为更好地进行协同开发工作，需要对流程进行规范&lt;br /&gt;
&lt;strong&gt;&lt;a href=&quot;http://github.com/saberma/shopqi&quot;&gt;shopqi网店平台&lt;/a&gt; 产品开发将遵循此流程&lt;/strong&gt;, 以下对git的开发流程进行描述&lt;/p&gt;
&lt;h2&gt;开发流程&lt;/h2&gt;
&lt;p&gt;在开发的过程中存在以下情况:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;情况1: 开发新特性&lt;br /&gt;
情况2: 紧急修正生产环境中报告的Bug&lt;br /&gt;
情况3: 支援其他成员，帮忙调试&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;假如我们在master主分支中进行新特性的开发，这时如果发生情况2，处理起来比较麻烦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;正确的实践应该是:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;master主分支保致与对外发布的版本同步&lt;/li&gt;
	&lt;li&gt;每个新特性(feature)都有独立的分支&lt;/li&gt;
	&lt;li&gt;将多个新特性(feature)分支合并至发布(release)分支&lt;/li&gt;
	&lt;li&gt;待发布(release)分支完成后再合并至master主分支，正式对外发布&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;应用gitflow&lt;/h2&gt;
&lt;p&gt;gitflow是开源的标准化git流程协助工具，项目地址在 &lt;a href=&quot;http://github.com/nvie/gitflow&quot;&gt;http://github.com/nvie/gitflow&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;安装(Ubuntu环境)&lt;/h3&gt;
&lt;pre&gt;
wget -qO- --no-check-certificate http://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | sudo sh
sudo apt-get install opt&lt;/pre&gt;
&lt;p&gt;其他操作系统安装gitflow请参考 &lt;a href=&quot;http://github.com/nvie/gitflow&quot;&gt;http://github.com/nvie/gitflow&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;使用方法&lt;/h3&gt;
&lt;pre&gt;
#初始化(提问时回车就好)
git flow init&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;开发新特征&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow feature start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow feature finish &amp;lt;name&amp;gt;
#列出新特征分支
git flow feature&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;准备发布版本&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow release start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow release finish &amp;lt;name&amp;gt;
#列出发布分支
git flow release&lt;/pre&gt;
&lt;p&gt;&amp;lt; base &amp;gt;是位于develop分支的commit&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正紧急Bug&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow hotfix start &amp;lt;name&amp;gt; [&amp;lt;base&amp;gt;]
git flow hotfix finish &amp;lt;name&amp;gt;
#列出修正分支
git flow hotfix&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;支援其他成员工作&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
git flow support start &amp;lt;name&amp;gt; &amp;lt;base&amp;gt;
#没有finish?(待实践)
#列出支援分支
git flow support&lt;/pre&gt;
&lt;p&gt;&amp;lt; base &amp;gt;是位于master分支的commit&lt;/p&gt;
&lt;h2&gt;结合github&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;上传未完成的feature分支&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
#git push REMOTENAME BRANCHNAME
#一般情况下REMOTENAME即为origin, BRANCHNAME为以feature/为前缀的分支名称
git push origin feature/orders&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意:对于develop分支，由于所有成员的本地库中都有，所以不能上传&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;http://nvie.com/posts/a-successful-git-branching-model/&quot;&gt;A successful Git branching model&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/&quot;&gt;Why aren&amp;#8217;t you using git-flow?&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://help.github.com/remotes/&quot;&gt;github remotes&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565433/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565433/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565433/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565433/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/git/2010/10/25/git-flow.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565433/6499449</fs:itemid><pubDate>Mon, 25 Oct 2010 15:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/git/2010/10/25/git-flow</guid></item><item><title>应用jekyll构建基于github page的博客</title><link>http://item.feedsky.com/~feedsky/saberma/~8395768/490565434/6499449/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">http://saberma.me/other/2010/09/20/saberma-github-page-blog-build-with-jekyll</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;基于github page的博客好处:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;简单至极，且完全免费&lt;br /&gt;
可以支持rss订阅，评论功能&lt;br /&gt;
依赖于git，文章原生支持版本控制(对比)，更有利于知识库类文章&lt;br /&gt;
可以使用vim编写文章，写的时候像在写代码，更符合程序员的习惯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本博客此次除了启用全新个人域名saberma.me，将做以下调整&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;美化网站风格，更加的清新:)&lt;br /&gt;
页面布局调整为html5、css3架构&lt;br /&gt;
文章可按分类显示&lt;br /&gt;
代码增加高亮显示&lt;br /&gt;
增加rss feed输出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;挑个新的博客模板&lt;/h2&gt;
&lt;p&gt;要求是基于html5、css3的免费模板，google之，发现个好地方: &lt;a href=&quot;http://freehtml5templates.com&quot;&gt;http://freehtml5templates.com&lt;/a&gt;&lt;br /&gt;
一页一页的挑吧，总会找到自己喜欢的，可以根据右下角的Tag Cloud进行筛选，现在看到本站的新样子就是找好久才看中的模板&lt;/p&gt;
&lt;h2&gt;绑定独立域名&lt;/h2&gt;
&lt;p&gt;在godaddy中注册 &lt;a href=&quot;http://saberma.em&quot;&gt;saberma.me&lt;/a&gt; 域名，.me专用于博客类型，但比.com贵一些，且没有优惠&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;注册完域名后，在域名管理中增加A record并指向207.97.227.245&lt;/li&gt;
	&lt;li&gt;在你的github项目下增加CNAME文件，内容为你的域名，如 &lt;a href=&quot;http://github.com/saberma/saberma.github.com/blob/master/CNAME&quot;&gt;http://github.com/saberma/saberma.github.com/blob/master/&lt;span class=&quot;caps&quot;&gt;CNAME&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体参考 &lt;a href=&quot;http://pages.github.com&quot;&gt;http://pages.github.com&lt;/a&gt; 中 &lt;code&gt;Custom Domains&lt;/code&gt; 部分的内容&lt;/p&gt;
&lt;h2&gt;pygments代码高亮&lt;/h2&gt;
&lt;h3&gt;安装pygments&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# On Ubuntu 安装&lt;/span&gt;
sudo apt-get install python-pygments
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/install&quot;&gt;完整安装说明&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;生成高亮显示的css文件&lt;/h3&gt;
&lt;p&gt;选择喜欢的样式，记下名称&lt;br /&gt;
&lt;a href=&quot;http://pygments.org/demo/6622&quot;&gt;http://pygments.org/demo/6622&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我选择的是fruity style，作为pygmentize命令style的参数值&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# 生成相应的css&lt;/span&gt;
pygmentize -S fruity -f html &amp;gt; stylesheets/syntax.css
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://pygments.org/docs/quickstart/&quot;&gt;参考pygments Command line usage&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;如何使用&lt;/h3&gt;
&lt;p&gt;语法高亮的代码段&lt;/p&gt;
&lt;pre&gt;
{% highlight ruby %}
def foo
  puts 'foo'
end
{% endhighlight %}
&lt;/pre&gt;
&lt;p&gt;highlight后面第一个参数为language，如php，也可以是ruby控制台irb，更多lanuages可以查询 &lt;a href=&quot;http://pygments.org/docs/lexers/&quot;&gt;http://pygments.org/docs/lexers/&lt;/a&gt;&lt;br /&gt;
第一个参数为必填，不填会导致_site目录生成不了相应的html文件，第二个参数显示行号&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/liquid-extensions&quot;&gt;参考jekyll说明&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Markdown标记与Liquid逻辑处理&lt;/h2&gt;
&lt;h3&gt;两个知识点&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;为避免直接编写html代码，编写文章时，内容需要加入标记信息，即Markdown&lt;/li&gt;
	&lt;li&gt;博客中都是需要经过处理的，比如逻辑判断处理、循环处理，jekyll应用liquid模板语言进行这些处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Markdown&lt;/h3&gt;
&lt;p&gt;标记语言有很多种，如textile&lt;br /&gt;
这些标记语言会被标记引擎转换，输出成相应的目标格式（大部分情况是输出成html）&lt;br /&gt;
引擎也有很多种，不同的编程语言有不同的实现，ruby常用的引擎有RedCloth&lt;/p&gt;
&lt;h3&gt;Liquid&lt;/h3&gt;
&lt;p&gt;简单来说，凡是看到{{}}或者{% %}包含的内容都是会被Liquid引擎处理的&lt;/p&gt;
&lt;p&gt;比如*将日期格式化*的liquid语句&lt;/p&gt;
&lt;pre&gt;
Liquid error: undefined method `strftime' for &quot;{{ post.date | date_to_string&quot;:String }}
&lt;/pre&gt;
&lt;p&gt;除了标记的Liquid语法外，jekyll还扩展出了几个便利的方法，其中有上面介绍的highlight方法&lt;br /&gt;
&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/liquid-extensions&quot;&gt;jekyll liquid扩展&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/tobi/liquid/wiki/Liquid-for-Designers&quot;&gt;liquid参考资料&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;整合评论&lt;/h2&gt;
&lt;p&gt;由于github page最终生成的都是静态html页面，所以是没有评论功能呢&lt;br /&gt;
但我们利用disqus实现在线评论功能，先到 &lt;a href=&quot;http://disqus.com&quot;&gt;http://disqus.com&lt;/a&gt; 注册帐号(免费)&lt;br /&gt;
注册成功后，为简单起见，只要把 &lt;code&gt;_includes/post.html&lt;/code&gt; 中的saberma替换为你的注册帐号就行了(disqus_url输入你实际的域名)&lt;/p&gt;
&lt;h2&gt;整合rss订阅&lt;/h2&gt;
&lt;p&gt;因为jekyll可以生成blogs列表，所以我们可以编写atom.xml，由jekyll生成最终xml结果&lt;br /&gt;
&lt;a href=&quot;/atom.xml&quot;&gt;这是我的atom.xml文件&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;将生成的xml地址提交至 &lt;a href=&quot;http://www.feedsky.com&quot;&gt;feedsky.com&lt;/a&gt; ，由feedsky进行管理和美化&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://elemel.se/2009/01/25/setting-up-an-atom-feed-at-github-pages.html&quot;&gt;Setting Up an Atom Feed at GitHub Pages&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;你也想弄一个github page博客?&lt;/h2&gt;
&lt;p&gt;最快的做法是 &lt;a href=&quot;http://github.com/saberma/saberma.github.com&quot;&gt;fork我的博客&lt;/a&gt; ，git clone到你的电脑&lt;br /&gt;
然后修改成你的，具体需要调整的地方是:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;删除_posts中的文章&lt;/li&gt;
	&lt;li&gt;按上面介绍的[整合评论]修改 &lt;code&gt;_includes/post.htm&lt;/code&gt; 文件&lt;/li&gt;
	&lt;li&gt;按上面介绍的[整合rss]修改 &lt;code&gt;atom.xml&lt;/code&gt; 文件&lt;/li&gt;
	&lt;li&gt;修改CNAME的内容为你的独立域名&lt;/li&gt;
	&lt;li&gt;运行jekyll，看看效果&lt;/li&gt;
	&lt;li&gt;上传!ok，访问你的blog地址看看&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.envylabs.com/2009/08/publishing-a-blog-with-github-pages-and-jekyll/&quot;&gt;publishing-a-blog-with-github-pages-and-jekyll&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/mojombo/jekyll/wiki&quot;&gt;jekyll wiki&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://pages.github.com&quot;&gt;http://pages.github.com&lt;/a&gt;&lt;/p&gt;</content><content:encoded>&lt;p&gt;基于github page的博客好处:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;简单至极，且完全免费&lt;br /&gt;
可以支持rss订阅，评论功能&lt;br /&gt;
依赖于git，文章原生支持版本控制(对比)，更有利于知识库类文章&lt;br /&gt;
可以使用vim编写文章，写的时候像在写代码，更符合程序员的习惯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本博客此次除了启用全新个人域名saberma.me，将做以下调整&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;美化网站风格，更加的清新:)&lt;br /&gt;
页面布局调整为html5、css3架构&lt;br /&gt;
文章可按分类显示&lt;br /&gt;
代码增加高亮显示&lt;br /&gt;
增加rss feed输出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;挑个新的博客模板&lt;/h2&gt;
&lt;p&gt;要求是基于html5、css3的免费模板，google之，发现个好地方: &lt;a href=&quot;http://freehtml5templates.com&quot;&gt;http://freehtml5templates.com&lt;/a&gt;&lt;br /&gt;
一页一页的挑吧，总会找到自己喜欢的，可以根据右下角的Tag Cloud进行筛选，现在看到本站的新样子就是找好久才看中的模板&lt;/p&gt;
&lt;h2&gt;绑定独立域名&lt;/h2&gt;
&lt;p&gt;在godaddy中注册 &lt;a href=&quot;http://saberma.em&quot;&gt;saberma.me&lt;/a&gt; 域名，.me专用于博客类型，但比.com贵一些，且没有优惠&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;注册完域名后，在域名管理中增加A record并指向207.97.227.245&lt;/li&gt;
	&lt;li&gt;在你的github项目下增加CNAME文件，内容为你的域名，如 &lt;a href=&quot;http://github.com/saberma/saberma.github.com/blob/master/CNAME&quot;&gt;http://github.com/saberma/saberma.github.com/blob/master/&lt;span class=&quot;caps&quot;&gt;CNAME&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体参考 &lt;a href=&quot;http://pages.github.com&quot;&gt;http://pages.github.com&lt;/a&gt; 中 &lt;code&gt;Custom Domains&lt;/code&gt; 部分的内容&lt;/p&gt;
&lt;h2&gt;pygments代码高亮&lt;/h2&gt;
&lt;h3&gt;安装pygments&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# On Ubuntu 安装&lt;/span&gt;
sudo apt-get install python-pygments
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/install&quot;&gt;完整安装说明&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;生成高亮显示的css文件&lt;/h3&gt;
&lt;p&gt;选择喜欢的样式，记下名称&lt;br /&gt;
&lt;a href=&quot;http://pygments.org/demo/6622&quot;&gt;http://pygments.org/demo/6622&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我选择的是fruity style，作为pygmentize命令style的参数值&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# 生成相应的css&lt;/span&gt;
pygmentize -S fruity -f html &amp;gt; stylesheets/syntax.css
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://pygments.org/docs/quickstart/&quot;&gt;参考pygments Command line usage&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;如何使用&lt;/h3&gt;
&lt;p&gt;语法高亮的代码段&lt;/p&gt;
&lt;pre&gt;
{% highlight ruby %}
def foo
  puts 'foo'
end
{% endhighlight %}
&lt;/pre&gt;
&lt;p&gt;highlight后面第一个参数为language，如php，也可以是ruby控制台irb，更多lanuages可以查询 &lt;a href=&quot;http://pygments.org/docs/lexers/&quot;&gt;http://pygments.org/docs/lexers/&lt;/a&gt;&lt;br /&gt;
第一个参数为必填，不填会导致_site目录生成不了相应的html文件，第二个参数显示行号&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/liquid-extensions&quot;&gt;参考jekyll说明&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Markdown标记与Liquid逻辑处理&lt;/h2&gt;
&lt;h3&gt;两个知识点&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;为避免直接编写html代码，编写文章时，内容需要加入标记信息，即Markdown&lt;/li&gt;
	&lt;li&gt;博客中都是需要经过处理的，比如逻辑判断处理、循环处理，jekyll应用liquid模板语言进行这些处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Markdown&lt;/h3&gt;
&lt;p&gt;标记语言有很多种，如textile&lt;br /&gt;
这些标记语言会被标记引擎转换，输出成相应的目标格式（大部分情况是输出成html）&lt;br /&gt;
引擎也有很多种，不同的编程语言有不同的实现，ruby常用的引擎有RedCloth&lt;/p&gt;
&lt;h3&gt;Liquid&lt;/h3&gt;
&lt;p&gt;简单来说，凡是看到{{}}或者{% %}包含的内容都是会被Liquid引擎处理的&lt;/p&gt;
&lt;p&gt;比如*将日期格式化*的liquid语句&lt;/p&gt;
&lt;pre&gt;
Liquid error: undefined method `strftime' for &quot;{{ post.date | date_to_string&quot;:String }}
&lt;/pre&gt;
&lt;p&gt;除了标记的Liquid语法外，jekyll还扩展出了几个便利的方法，其中有上面介绍的highlight方法&lt;br /&gt;
&lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/liquid-extensions&quot;&gt;jekyll liquid扩展&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/tobi/liquid/wiki/Liquid-for-Designers&quot;&gt;liquid参考资料&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;整合评论&lt;/h2&gt;
&lt;p&gt;由于github page最终生成的都是静态html页面，所以是没有评论功能呢&lt;br /&gt;
但我们利用disqus实现在线评论功能，先到 &lt;a href=&quot;http://disqus.com&quot;&gt;http://disqus.com&lt;/a&gt; 注册帐号(免费)&lt;br /&gt;
注册成功后，为简单起见，只要把 &lt;code&gt;_includes/post.html&lt;/code&gt; 中的saberma替换为你的注册帐号就行了(disqus_url输入你实际的域名)&lt;/p&gt;
&lt;h2&gt;整合rss订阅&lt;/h2&gt;
&lt;p&gt;因为jekyll可以生成blogs列表，所以我们可以编写atom.xml，由jekyll生成最终xml结果&lt;br /&gt;
&lt;a href=&quot;/atom.xml&quot;&gt;这是我的atom.xml文件&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;将生成的xml地址提交至 &lt;a href=&quot;http://www.feedsky.com&quot;&gt;feedsky.com&lt;/a&gt; ，由feedsky进行管理和美化&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://elemel.se/2009/01/25/setting-up-an-atom-feed-at-github-pages.html&quot;&gt;Setting Up an Atom Feed at GitHub Pages&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;你也想弄一个github page博客?&lt;/h2&gt;
&lt;p&gt;最快的做法是 &lt;a href=&quot;http://github.com/saberma/saberma.github.com&quot;&gt;fork我的博客&lt;/a&gt; ，git clone到你的电脑&lt;br /&gt;
然后修改成你的，具体需要调整的地方是:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;删除_posts中的文章&lt;/li&gt;
	&lt;li&gt;按上面介绍的[整合评论]修改 &lt;code&gt;_includes/post.htm&lt;/code&gt; 文件&lt;/li&gt;
	&lt;li&gt;按上面介绍的[整合rss]修改 &lt;code&gt;atom.xml&lt;/code&gt; 文件&lt;/li&gt;
	&lt;li&gt;修改CNAME的内容为你的独立域名&lt;/li&gt;
	&lt;li&gt;运行jekyll，看看效果&lt;/li&gt;
	&lt;li&gt;上传!ok，访问你的blog地址看看&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;参考资源&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.envylabs.com/2009/08/publishing-a-blog-with-github-pages-and-jekyll/&quot;&gt;publishing-a-blog-with-github-pages-and-jekyll&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://github.com/mojombo/jekyll/wiki&quot;&gt;jekyll wiki&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://pages.github.com&quot;&gt;http://pages.github.com&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/490565434/saberma/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/saberma/~8395768/490565434/6499449/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/saberma/490565434/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/saberma/490565434/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><fs:srclink>http://saberma.me/other/2010/09/20/saberma-github-page-blog-build-with-jekyll.html</fs:srclink><fs:srcfeed>http://saberma.me/atom.xml</fs:srcfeed><fs:itemid>feedsky/saberma/~8395768/490565434/6499449</fs:itemid><pubDate>Mon, 20 Sep 2010 15:00:00 +0800</pubDate><guid isPermaLink="false">http://saberma.me/other/2010/09/20/saberma-github-page-blog-build-with-jekyll</guid></item></channel></rss>
