<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LetRails &#187; 部署</title>
	<atom:link href="http://www.letrails.cn/archives/category/rails_deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.letrails.cn</link>
	<description>为Ruby on Rails在中文社区的枝繁叶茂贡献点滴</description>
	<lastBuildDate>Sat, 04 Sep 2010 08:24:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>自定义capistrano维护页面</title>
		<link>http://www.letrails.cn/archives/customize-capistrano-maintenance-page/</link>
		<comments>http://www.letrails.cn/archives/customize-capistrano-maintenance-page/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 06:48:22 +0000</pubDate>
		<dc:creator>yuanyi</dc:creator>
				<category><![CDATA[部署]]></category>

		<guid isPermaLink="false">http://www.letrails.cn/archives/customize-capistrano-maintenance-page</guid>
		<description><![CDATA[capistrano是目前最为流行的Rails部署工具，不过一旦进入产品阶段，我们可能希望在部署时显示一个“站点正在维护中”的页面，而不是正在升级中的应用，当前版本（2.5）的capistrano提供了两个内置任务来完成这一工作，它们就是deploy:web:disable和 deploy:web:enable，如果你仔细查看capistrano的部署目录，会在current/public目录下发现一个system目录，它是一个指向shared/system的链接，因此我们首先需要在shared目录下建立system目录，capistrano使用它来存放维护页面。 server$ mkdir deploy/shared 现在如果我们执行cap deploy:web:disable，capistrano会通过sftp上传一个默认的站点维护页面到shared/system /maintenance.html，而deploy:web:enable则会将这个页面删除，但是这个任务本身并不能将应用屏蔽掉，我们需要修改前端服务器的rewrite规则。 如果你使用nginx，那么加入下面几行到你的nginx.conf： server { &#160;&#160;root /current/deploy/path/public; &#160;&#160;if (-f $document_root/system/maintenance.html) { &#160;&#160;&#160;&#160;set $maintenance 1; &#160;&#160;} &#160;&#160;if ($request_uri ~* (jpg&#124;jpeg&#124;gif&#124;js&#124;css)$) { &#160;&#160;&#160;&#160;set $maintenance 0; &#160;&#160;} &#160;&#160;if ($maintenance) { &#160;&#160;&#160;&#160;rewrite ^(.*)$ /system/maintenance.html last; &#160;&#160;&#160;&#160;break; &#160;&#160;} &#160;&#160;location / { &#160;&#160;&#160;&#160;.... 这样nginx会首先判断维护页面是否存在，如果存在，则将所有清除都转向维护页面，如果使用apache，则需要修改.htaccess（未验证）： RewriteCond %{REQUEST_URI} !\.(css&#124;jpg&#124;js&#124;gif&#124;png)$ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ [...]]]></description>
			<content:encoded><![CDATA[<p>capistrano是目前最为流行的Rails部署工具，不过一旦进入产品阶段，我们可能希望在部署时显示一个“站点正在维护中”的页面，而不是正在升级中的应用，当前版本（2.5）的capistrano提供了两个内置任务来完成这一工作，它们就是deploy:web:disable和 deploy:web:enable，如果你仔细查看capistrano的部署目录，会在current/public目录下发现一个system目录，它是一个指向shared/system的链接，因此我们首先需要在shared目录下建立system目录，capistrano使用它来存放维护页面。</p>
<p>server$ mkdir deploy/shared</p>
<p>现在如果我们执行cap deploy:web:disable，capistrano会通过sftp上传一个默认的站点维护页面到shared/system /maintenance.html，而deploy:web:enable则会将这个页面删除，但是这个任务本身并不能将应用屏蔽掉，我们需要修改前端服务器的rewrite规则。</p>
<p>如果你使用nginx，那么加入下面几行到你的nginx.conf：</p>
<p class="code"><code><br />
server {<br />
&nbsp;&nbsp;root /current/deploy/path/public;<br />
&nbsp;&nbsp;if (-f $document_root/system/maintenance.html) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;set $maintenance 1;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;if ($request_uri ~* (jpg|jpeg|gif|js|css)$) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;set $maintenance 0;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;if ($maintenance) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;rewrite  ^(.*)$  /system/maintenance.html last;<br />
&nbsp;&nbsp;&nbsp;&nbsp;break;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;location / {<br />
&nbsp;&nbsp;&nbsp;&nbsp;....</code></p>
<p>这样nginx会首先判断维护页面是否存在，如果存在，则将所有清除都转向维护页面，如果使用apache，则需要修改.htaccess（未验证）：</p>
<p>RewriteCond %{REQUEST_URI} !\.(css|jpg|js|gif|png)$<br />
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f<br />
RewriteCond %{SCRIPT_FILENAME} !maintenance.html<br />
RewriteRule ^.*$ /system/maintenance.html [L]</p>
<p>如果你想要这一切自动进行，那么你可以将这两个任务加入deploy任务：</p>
<p class="code"><code class="ruby"><br />
namespace :deploy do<br />
&nbsp;&nbsp;desc "Default deploy will update the code without migrate the database and restart the servers"<br />
&nbsp;&nbsp;task :default do<br />
&nbsp;&nbsp;&nbsp;&nbsp;# put up the maintenance screen<br />
&nbsp;&nbsp;&nbsp;&nbsp;web.disable<br />
&nbsp;&nbsp;&nbsp;&nbsp;transaction do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update_code<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symlink<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy_configs<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;restart<br />
&nbsp;&nbsp;&nbsp;&nbsp;# remove the maintenance screen<br />
&nbsp;&nbsp;&nbsp;&nbsp;web.enable<br />
&nbsp;&nbsp;end<br />
end</code></p>
<p>如果你想要自定义维护页面，可以通过覆盖默认的deploy:web:disable任务实现：</p>
<p class="code"><code class="ruby"><br />
namespace :deploy do<br />
&nbsp;&nbsp;namespace :web do<br />
&nbsp;&nbsp;&nbsp;&nbsp;task :disable do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on_rollback { delete "#{shared_path}/system/maintenance.html" }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'rubygems'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'haml'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template = File.read("./app/views/layouts/maintenance.html.haml")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;haml = Haml::Engine.new(template)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maintenance = haml.render(Object.new,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:deadline =&gt; ENV['UNTIL'],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:reason =&gt; ENV['REASON'])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;put maintenance, "#{shared_path}/system/maintenance.html",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mode =&gt; 0644<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
end</code></p>
<p>这段代码渲染了layouts/maintenance.html.haml，你可以根据自己的需要定义它，这里我们传入了两个变量，一个指定原因，一个指定恢复时间:</p>
<p class="code"><code><br />
%h1<br />
&nbsp;&nbsp;We're currently down for<br />
&nbsp;&nbsp;= reason ? reason : "maintenance"<br />
&nbsp;&nbsp;as of<br />
&nbsp;&nbsp;= Time.now.strftime("%H:%M %Z")<br />
%p<br />
&nbsp;&nbsp;Sorry for the inconvenience. We'll be back<br />
&nbsp;&nbsp;= deadline ? "by #{deadline}" : "shortly"<br />
&nbsp;&nbsp;Please email us if you need to get in touch.</code></p>
<p>你可以在执行deploy:web:disable之前设定这两个变量：</p>
<p>UNTIL=&#8221;16:00 MST&#8221; REASON=&#8221;a database upgrade&#8221; cap disable_web</p>
<p>参考：</p>
<ul>
<li><a href="http://clarkware.com/cgi/blosxom/2007/01/05">http://clarkware.com/cgi/blosxom/2007/01/05</a></li>
<li><a href="http://www.ruby-forum.com/topic/113740">http://www.ruby-forum.com/topic/113740</a></li>
<li><a href="http://www.mail-archive.com/haml@googlegroups.com/msg02726.html">http://www.mail-archive.com/haml@googlegroups.com/msg02726.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.letrails.cn/archives/customize-capistrano-maintenance-page/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>nginx+mongrel cluster配置指南</title>
		<link>http://www.letrails.cn/archives/nginx_mongrel_cluster_deployment/</link>
		<comments>http://www.letrails.cn/archives/nginx_mongrel_cluster_deployment/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 12:46:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[部署]]></category>

		<guid isPermaLink="false">http://www.letrails.cn/archives/66</guid>
		<description><![CDATA[准备工作 安装PCRE库: $ ftp ftp.csx.cam.ac.uk username: anonymous &#62; cd pub/software/programming/pcre/ &#62; get pcre-7.4.tar.bz2 &#62; quit $ tar -jxvf pcre-7.4.tar.bz2 $ cd pcre-7.4 $ ./configure $ make 不需要安装它，只是编译nginx时需要用到而已。 安装nginx $ wget http://sysoev.ru/nginx/nginx-0.5.32.tar.gz $ tar -zxvf nginx-0.5.32.tar.gz $ cd nginx-0.5.32 $ ./configure --with-pcre=../pcre-7.4 $ make $ sudo make install 配置nginx 修改/usr/local/nginx/conf/nginx.conf: user someuser; worker_processes 1; error_log logs/error.log [...]]]></description>
			<content:encoded><![CDATA[<h2>准备工作</h2>
<p>安装<a href="http://www.pcre.org/" title="PCRE" id="g3.m">PCRE</a>库:</p>
<p class="code"><code>$ ftp ftp.csx.cam.ac.uk<br />
username: anonymous<br />
&gt; cd pub/software/programming/pcre/<br />
&gt; get pcre-7.4.tar.bz2</p>
<p>&gt; quit<br />
$ tar -jxvf pcre-7.4.tar.bz2<br />
$ cd pcre-7.4<br />
$ ./configure<br />
$ make</code></p>
<p>不需要安装它，只是编译nginx时需要用到而已。</p>
<h2>安装nginx</h2>
<p class="code"><code>$ wget http://sysoev.ru/nginx/nginx-0.5.32.tar.gz</p>
<p>$ tar -zxvf nginx-0.5.32.tar.gz<br />
$ cd nginx-0.5.32<br />
$ ./configure --with-pcre=../pcre-7.4<br />
$ make<br />
$ sudo make install</code></p>
<h2>配置nginx</h2>
<p>修改/usr/local/nginx/conf/nginx.conf:</p>
<pre>user  someuser;
worker_processes  1;

error_log logs/error.log  notice;

pid logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       conf/mime.types;
    default_type  application/octet-stream;

    access_log  logs/access.log;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;
    gzip_min_length  1100;
    gzip_buffers     4 8k;
    gzip_types       text/plain;

    upstream mongrel {
        server 127.0.0.1:8100;
        server 127.0.0.1:8101;
        server 127.0.0.1:8102;
        server 127.0.0.1:8103;
    }

    server {
        listen       80;
        server_name  your.server.com;
        location / {
            proxy_pass http://mongrel;
        }

        root /home/your/app/path;

        access_log  off;
        rewrite_log on;

        location ~ ^/$ {
            if (-f /index.html){
                rewrite (.*) /index.html last;
            }
            proxy_pass  http://mongrel;
            proxy_set_header   Host             $host;
        }

        location / {
            if (!-f $request_filename.html) {
                proxy_pass  http://mongrel;
            }
            rewrite (.*) $1.html last;
        }

        location ~ .html {
            root /home/your/app/path;
        }

        location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|
                                 exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov)$ {
            root /home/your/app/path;
        }
        location / {
            proxy_pass  http://mongrel;
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
    }
}</pre>
<h2>启动 nginx</h2>
<p class="code"><code>$ sudo /usr/local/nginx/sbin/nginx</code></p>
<h2>配置启动 mongrel cluster</h2>
<p class="code"><code>$ cd /home/your/app/path<br />
$ sudo mongrel_rails cluster::configure -e production \<br />
-p 8100 -N 4 -c /home/your/app/path -a 127.0.0.1 \<br />
--user mongrel --group mongrel<br />
$ sudo mongrel_rails cluster::start</code></p>
<h2>配置 HTTP 认证</h2>
<p>添加以下行到 nginx.conf:</p>
<pre>location  /  {
    auth_basic            "Restricted";
    auth_basic_user_file  conf/htpasswd;
}</pre>
<p>要生成htpasswd文件, 使用Apache附带的htpasswd命令:</p>
<p class="code"><code>$ sudo htpasswd -bc conf/htpasswd user pass</code></p>
<p>关于htpasswd命令的使用，可使用&#8217;htpasswd -h&#8217;察看帮助。</p>
<h2>清理工作</h2>
<p class="code"><code>$ rm -rf pcre-7.4<br />
$ rm -rf nginx-0.5.32</code></p>
<p>更新：如果遇到redirect_to重定向问题，请检查你的nginx版本，老版本使用$http_host变量，因此应该对proxy_set_header做相应修改：</p>
<pre>    proxy_set_header   Host             $host;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.letrails.cn/archives/nginx_mongrel_cluster_deployment/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails部署艺术</title>
		<link>http://www.letrails.cn/archives/4/</link>
		<comments>http://www.letrails.cn/archives/4/#comments</comments>
		<pubDate>Sat, 02 Jun 2007 09:44:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[部署]]></category>

		<guid isPermaLink="false">http://www.letrails.cn/?p=4</guid>
		<description><![CDATA[翻译自：Ezra Zygmuntowicz， “Xen and the Art of Rails Deployment” 听到Rails部署这两词，可能你首先想到的是下面这堆东西： CGI Apache1.3/mod_fastcgi Lighttpd/fcgi Apache2/mod_fcgid Lighttpd/SCGI Lightspeed 但时代已经变了，新时代需要新思维 Mongrel：The year of the dog Mongrel是由Zed Shaw完成的一个HTTP Server，它： 使用Ragel + C的快速HTTP解析 使用C的快速URI过滤器 堆栈式请求处理 配置灵活 安全同时兼容RFC的HTTP解析器 Mongrel就足够了？ 答案是：不够，因为： Rails请求分发需要使用互斥锁 一个Mongrel实例只能同时处理一个请求 需要使用Mongrel_cluster创建多个实例来获取可伸缩性 因此，你仍然需要一个前端HTTP Server，幸好有一大堆： Pen，Pound，Balance，Haproxy（不支持静态文件，只是代理） Lightspeed，支持静态文件和代理 Apache2.2.x/mod_proxy_balancer，同上 这就搞定了？还不行： Pen（不支持SSL，不能限制连接速率） Pound（不支持高负载，不能限制链接速率） Haproxy（可限制连接速率，性能非常高，不支持静态文件 Lightspeed，免费版功能严重残缺 Apache2.2.x，没什么不好，就是：太臃肿了 那怎么办？ Nginx：From Russia, with Love Nginx有什么好处： 专为性能优化而开发，性能是其最重要的考量 [...]]]></description>
			<content:encoded><![CDATA[<p>翻译自：<a href="http://brainspl.at/">Ezra Zygmuntowicz</a>， “Xen and the Art of Rails Deployment”</p>
<p>听到Rails部署这两词，可能你首先想到的是下面这堆东西：</p>
<ul>
<li>CGI</li>
<li>Apache1.3/mod_fastcgi</li>
<li>Lighttpd/fcgi</li>
<li>Apache2/mod_fcgid</li>
<li>Lighttpd/SCGI</li>
<li>Lightspeed</li>
</ul>
<p>但时代已经变了，新时代需要新思维</p>
<h2>Mongrel：The year of the dog</h2>
<p>Mongrel是由Zed Shaw完成的一个HTTP Server，它：</p>
<ul>
<li>使用Ragel + C的快速HTTP解析</li>
<li>使用C的快速URI过滤器</li>
<li>堆栈式请求处理</li>
<li>配置灵活</li>
<li>安全同时兼容RFC的HTTP解析器</li>
</ul>
<p>Mongrel就足够了？</p>
<p>答案是：不够，因为：</p>
<ul>
<li>Rails请求分发需要使用互斥锁</li>
<li>一个Mongrel实例只能同时处理一个请求</li>
<li>需要使用Mongrel_cluster创建多个实例来获取可伸缩性</li>
</ul>
<p>因此，你仍然需要一个前端HTTP Server，幸好有一大堆：</p>
<ul>
<li>Pen，Pound，Balance，Haproxy（不支持静态文件，只是代理）</li>
<li>Lightspeed，支持静态文件和代理</li>
<li>Apache2.2.x/mod_proxy_balancer，同上</li>
</ul>
<p>这就搞定了？还不行：</p>
<ul>
<li>Pen（不支持SSL，不能限制连接速率）</li>
<li>Pound（不支持高负载，不能限制链接速率）</li>
<li>Haproxy（可限制连接速率，性能非常高，不支持静态文件</li>
<li>Lightspeed，免费版功能严重残缺</li>
<li>Apache2.2.x，没什么不好，就是：太臃肿了</li>
</ul>
<p>那怎么办？</p>
<h2>Nginx：From Russia, with Love</h2>
<p>Nginx有什么好处：</p>
<ul>
<li>专为性能优化而开发，性能是其最重要的考量</li>
<li>非常小的资源占用</li>
<li>经过考验的高负载支持，没有内存泄漏</li>
<li>杀手级的Rewrite及Proxy模块</li>
<li>平易近人的作者以及快速扩大的社区</li>
</ul>
<p>答案有了：Nginx + Mongrel，现在</p>
<ul>
<li>Apache很清闲了，它只需要负责mod_dav_svn就可以了</li>
<li>灵活的nginx.conf语法可以很轻易的搞定Rails Cache及动态请求</li>
<li>还有就是：快，快，快</li>
<li>我有说过快吗？</li>
</ul>
<p>当然还有一些问题：</p>
<ul>
<li>Nginx会自动缓冲文件上传，因此将失去mongrel_upload_progress支持</li>
<li>Proxy模块暂时还不支持链接速率限制</li>
</ul>
<p>完美的部署就这样产生了：</p>
<ul>
<li>Linux</li>
<li>Nginx</li>
<li>Mongrel(Mongrel_cluster)</li>
<li>Monit</li>
</ul>
<p>就这么完了？还有一点，上面讲到过Mongrel的问题：</p>
<ul>
<li>不能同时处理多个请求</li>
<li>Rails分发需要取得互斥锁，</li>
<li>还有多线程切换</li>
</ul>
<p>这些都会损耗性能，因此我们需要新思维</p>
<h2>Swiftiply: Evented Mongrel</h2>
<p>Swiftply事实上是Mongrel的修订版，那么它对Mongrel做了什么：</p>
<ul>
<li>去除了Mongrel中对线程和Socket的处理</li>
<li>使用EventMachine的事件循环来代替</li>
<li>Mongrel成了单线程，事件驱动</li>
<li>显著的速度及IO吞吐量提升</li>
<li>即使高并发，也没有不良症状（性能下降及内存泄漏）</li>
</ul>
<p>你可能疑惑为何单线程会优于多线程，这是因为：</p>
<ul>
<li>Ruby的绿色线程进行上下文切换时需要拷贝大量的状态信息</li>
<li>互斥锁非常昂贵</li>
<li>单个进程的IO吞吐量有限</li>
<li>事件驱动意味着更紧凑的循环已经回调处理</li>
<li>由于节省了进程切换的时间，因此单线程可以将更多的精力集中到网络IO上。</li>
</ul>
<p>Swiftiply还有一个好处：它可以启动多个Mongrel，但只使用一个端口。</p>
<p>总算结束了，原文还有一部分是关于虚拟机和磁盘阵列的，对这部分不是很熟悉，所以没有翻，有兴趣的可以看原文：<a href="http://brainspl.at/xen_and_the_art_of_rails_deployment.pdf">Xen and the Art of Rails Deployment</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.letrails.cn/archives/4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
