<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://blog.designrecipe.jp/</id>
  <title>Design Recipe 別館 Blog - Home</title>
  <updated>2012-03-24T09:45:00Z</updated>
  <link rel="alternate" href="http://blog.designrecipe.jp/"/>
  <link rel="self" href="http://blog.designrecipe.jp/feed/atom.xml"/>
  <author>
    <name>Design Recipe</name>
    <uri>http://blog.designrecipe.jp</uri>
  </author>
  <entry>
    <id>tag:blog.designrecipe.jp,2012-03-24:/2012/03/24/nodejs-install-in-ubuntu/</id>
    <title type="html">node.js のインストール - Ubuntu 10.04 編</title>
    <published>2012-03-24T09:45:00Z</published>
    <updated>2012-03-24T09:45:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2012/03/24/nodejs-install-in-ubuntu/"/>
    <content type="html">&lt;p&gt;Ubuntu 10.04 への &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; のインストールメモ。&lt;/p&gt;

&lt;p&gt;apt repository を新規に追加してインストール。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get -y update
$ sudo apt-get -y install nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これだけ。。&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;Ubuntu 10.04 への &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; のインストールメモ。&lt;/p&gt;

&lt;p&gt;apt repository を新規に追加してインストール。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get -y update
$ sudo apt-get -y install nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これだけ。。&lt;/p&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2012-03-20:/2012/03/20/awesome-print-memo/</id>
    <title type="html">irb でのオブジェクトの表示を更に見易く - awesome print</title>
    <published>2012-03-20T14:50:00Z</published>
    <updated>2012-03-20T14:50:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2012/03/20/awesome-print-memo/"/>
    <content type="html">&lt;p&gt;環境を整理していていたついでにメモを残しておく。&lt;/p&gt;

&lt;p&gt;irb でシンタックスハイライトなどを行うには Wirble など便利な gem があるが、&lt;a href="https://github.com/michaeldv/awesome_print"&gt;awesome_print&lt;/a&gt; はオブジェクトのデータ構造もわかりやすくインデントして表示してくれる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/michaeldv/awesome_print"&gt;michaeldv/awesome_print · GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Awesome Print is a Ruby library that pretty prints Ruby objects in full color exposing their internal structure with proper indentation. Rails ActiveRecord objects and usage within Rails templates are supported via included mixins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id="irb-"&gt;インストールと irb でのお試し&lt;/h3&gt;

&lt;p&gt;インストール。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ gem install awesome_print
Fetching: awesome_print-1.0.2.gem (100%)
Successfully installed awesome_print-1.0.2
1 gem installed
Installing ri documentation for awesome_print-1.0.2...
Installing RDoc documentation for awesome_print-1.0.2...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;irb で試してみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ irb
1.9.3-p125 :001 &amp;gt; require 'awesome_print'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; data = [ false, 42, %w(forty two), { :now =&amp;gt; Time.now, :class =&amp;gt; Time.now.class, :distance =&amp;gt; 42e42 } ]
 =&amp;gt; [false, 42, ["forty", "two"], {:now=&amp;gt;2012-03-20 14:11:20 +0900, :class=&amp;gt;Time, :distance=&amp;gt;4.2e+43}] 
1.9.3-p125 :003 &amp;gt; ap data
[
    [0] false,
    [1] 42,
    [2] [
        [0] "forty",
        [1] "two"
    ],
    [3] {
             :now =&amp;gt; 2012-03-20 14:11:20 +0900,
           :class =&amp;gt; Time &amp;lt; Object,
        :distance =&amp;gt; 4.2e+43
    }
]
 =&amp;gt; [false, 42, ["forty", "two"], {:now=&amp;gt;2012-03-20 14:11:20 +0900, :class=&amp;gt;Time, :distance=&amp;gt;4.2e+43}] 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;awesome_print&lt;/code&gt; を require 後に、ap メソッドに &lt;code&gt;awesome_print&lt;/code&gt; で表示させてたいオブジェクトを預ける。&lt;/p&gt;

&lt;p&gt;実際のコンソールの画面も貼りつけておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/awesome_print-1-w500.png" alt="awesome_print-1" /&gt;&lt;/p&gt;

&lt;h3 id="irb--awesomeprint-"&gt;irb での出力を常に awesome_print で&lt;/h3&gt;

&lt;p&gt;先ほどの確認では、&lt;code&gt;awesome_print&lt;/code&gt; を使って表示するためには &lt;code&gt;ap&lt;/code&gt; にオブジェクトを預ける必要があったが、&lt;code&gt;ap&lt;/code&gt; の入力なしに常に &lt;code&gt;awesome_print&lt;/code&gt; で表示が行えるようにする。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$HOME/.irbrc&lt;/code&gt; に以下を追記。&lt;br /&gt;
($HOME はユーザアカウントの HOME 直下。)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$HOME/.irbrc&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# load libraries
require 'rubygems'
require "awesome_print"

unless IRB.version.include?('DietRB')
  IRB::Irb.class_eval do
    def output_value
      ap @context.last_value
    end
  end
else # MacRuby
  IRB.formatter = Class.new(IRB::Formatter) do
    def inspect_object(object)
      object.ai
    end
  end.new
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;試してみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ irb
1.9.3-p125 :001 &amp;gt; data = [ false, 42, %w(forty two), { :now =&amp;gt; Time.now, :class =&amp;gt; Time.now.class, :distance =&amp;gt; 42e42 } ]
[
    [0] false,
    [1] 42,
    [2] [
        [0] "forty",
        [1] "two"
    ],
    [3] {
             :now =&amp;gt; 2012-03-20 14:17:37 +0900,
           :class =&amp;gt; Time &amp;lt; Object,
        :distance =&amp;gt; 4.2e+43
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-2-w500.png" alt="awesome_print-2" /&gt;&lt;/p&gt;

&lt;h3 id="rails-console--awesomeprint"&gt;rails console でも &lt;code&gt;awesome_print&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Rails の console でも &lt;code&gt;awesome_print&lt;/code&gt; を使いたくなる。&lt;/p&gt;

&lt;p&gt;Rails アプリケーションの &lt;code&gt;Gemfile&lt;/code&gt; に &lt;code&gt;awesome_print&lt;/code&gt; を追加してロードできるようにしておく。
開発環境とテスト環境のみで利用可能に。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$RAILS_HOME/Gemfile&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;group :development, :test do
  gem 'awesome_print', '~&amp;gt; 1.0.2'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bundler でインストールしておく。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以下は Refinery CMS で使用した例。&lt;/p&gt;

&lt;p&gt;モデルオブジェクトを見てみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ rails c
Loading development environment (Rails 3.2.2)
1.9.3p125 :001 &amp;gt; Refinery::Page
class Refinery::Page &amp;lt; Refinery::Core::BaseModel {
                     :id =&amp;gt; :integer,
              :parent_id =&amp;gt; :integer,
                   :path =&amp;gt; :string,
                   :slug =&amp;gt; :string,
           :show_in_menu =&amp;gt; :boolean,
               :link_url =&amp;gt; :string,
             :menu_match =&amp;gt; :string,
              :deletable =&amp;gt; :boolean,
                  :draft =&amp;gt; :boolean,
    :skip_to_first_child =&amp;gt; :boolean,
                    :lft =&amp;gt; :integer,
                    :rgt =&amp;gt; :integer,
                  :depth =&amp;gt; :integer,
          :view_template =&amp;gt; :string,
        :layout_template =&amp;gt; :string,
             :created_at =&amp;gt; :datetime,
             :updated_at =&amp;gt; :datetime
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-3-w500.png" alt="awesome_print-3" /&gt;&lt;/p&gt;

&lt;p&gt;検索結果は以下のような感じ。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;1.9.3p125 :002 &amp;gt; Refinery::Page.find(:first)
  Refinery::Page Load (0.5ms)  SELECT "refinery_pages".* FROM "refinery_pages" LIMIT 1
  Refinery::Page::Translation Load (0.3ms)  SELECT "refinery_page_translations".* FROM "refinery_page_translations" WHERE "refinery_page_translations"."refinery_page_id" = 1
#&amp;lt;Refinery::Page:0xa3f780c&amp;gt; {
                     :id =&amp;gt; 1,
              :parent_id =&amp;gt; nil,
                   :path =&amp;gt; "Home",
                   :slug =&amp;gt; "home",
           :show_in_menu =&amp;gt; true,
               :link_url =&amp;gt; "/",
             :menu_match =&amp;gt; "^/$",
              :deletable =&amp;gt; false,
                  :draft =&amp;gt; false,
    :skip_to_first_child =&amp;gt; false,
                    :lft =&amp;gt; 1,
                    :rgt =&amp;gt; 4,
                  :depth =&amp;gt; 0,
          :view_template =&amp;gt; nil,
        :layout_template =&amp;gt; nil,
             :created_at =&amp;gt; Sun, 18 Mar 2012 04:20:54 UTC +00:00,
             :updated_at =&amp;gt; Sun, 18 Mar 2012 12:27:27 UTC +00:00
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-4-w500.png" alt="awesome_print-4" /&gt;&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;環境を整理していていたついでにメモを残しておく。&lt;/p&gt;

&lt;p&gt;irb でシンタックスハイライトなどを行うには Wirble など便利な gem があるが、&lt;a href="https://github.com/michaeldv/awesome_print"&gt;awesome_print&lt;/a&gt; はオブジェクトのデータ構造もわかりやすくインデントして表示してくれる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/michaeldv/awesome_print"&gt;michaeldv/awesome_print · GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Awesome Print is a Ruby library that pretty prints Ruby objects in full color exposing their internal structure with proper indentation. Rails ActiveRecord objects and usage within Rails templates are supported via included mixins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id="irb-"&gt;インストールと irb でのお試し&lt;/h3&gt;

&lt;p&gt;インストール。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ gem install awesome_print
Fetching: awesome_print-1.0.2.gem (100%)
Successfully installed awesome_print-1.0.2
1 gem installed
Installing ri documentation for awesome_print-1.0.2...
Installing RDoc documentation for awesome_print-1.0.2...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;irb で試してみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ irb
1.9.3-p125 :001 &amp;gt; require 'awesome_print'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; data = [ false, 42, %w(forty two), { :now =&amp;gt; Time.now, :class =&amp;gt; Time.now.class, :distance =&amp;gt; 42e42 } ]
 =&amp;gt; [false, 42, ["forty", "two"], {:now=&amp;gt;2012-03-20 14:11:20 +0900, :class=&amp;gt;Time, :distance=&amp;gt;4.2e+43}] 
1.9.3-p125 :003 &amp;gt; ap data
[
    [0] false,
    [1] 42,
    [2] [
        [0] "forty",
        [1] "two"
    ],
    [3] {
             :now =&amp;gt; 2012-03-20 14:11:20 +0900,
           :class =&amp;gt; Time &amp;lt; Object,
        :distance =&amp;gt; 4.2e+43
    }
]
 =&amp;gt; [false, 42, ["forty", "two"], {:now=&amp;gt;2012-03-20 14:11:20 +0900, :class=&amp;gt;Time, :distance=&amp;gt;4.2e+43}] 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;awesome_print&lt;/code&gt; を require 後に、ap メソッドに &lt;code&gt;awesome_print&lt;/code&gt; で表示させてたいオブジェクトを預ける。&lt;/p&gt;

&lt;p&gt;実際のコンソールの画面も貼りつけておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/awesome_print-1-w500.png" alt="awesome_print-1" /&gt;&lt;/p&gt;

&lt;h3 id="irb--awesomeprint-"&gt;irb での出力を常に awesome_print で&lt;/h3&gt;

&lt;p&gt;先ほどの確認では、&lt;code&gt;awesome_print&lt;/code&gt; を使って表示するためには &lt;code&gt;ap&lt;/code&gt; にオブジェクトを預ける必要があったが、&lt;code&gt;ap&lt;/code&gt; の入力なしに常に &lt;code&gt;awesome_print&lt;/code&gt; で表示が行えるようにする。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$HOME/.irbrc&lt;/code&gt; に以下を追記。&lt;br /&gt;
($HOME はユーザアカウントの HOME 直下。)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$HOME/.irbrc&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# load libraries
require 'rubygems'
require "awesome_print"

unless IRB.version.include?('DietRB')
  IRB::Irb.class_eval do
    def output_value
      ap @context.last_value
    end
  end
else # MacRuby
  IRB.formatter = Class.new(IRB::Formatter) do
    def inspect_object(object)
      object.ai
    end
  end.new
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;試してみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ irb
1.9.3-p125 :001 &amp;gt; data = [ false, 42, %w(forty two), { :now =&amp;gt; Time.now, :class =&amp;gt; Time.now.class, :distance =&amp;gt; 42e42 } ]
[
    [0] false,
    [1] 42,
    [2] [
        [0] "forty",
        [1] "two"
    ],
    [3] {
             :now =&amp;gt; 2012-03-20 14:17:37 +0900,
           :class =&amp;gt; Time &amp;lt; Object,
        :distance =&amp;gt; 4.2e+43
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-2-w500.png" alt="awesome_print-2" /&gt;&lt;/p&gt;

&lt;h3 id="rails-console--awesomeprint"&gt;rails console でも &lt;code&gt;awesome_print&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Rails の console でも &lt;code&gt;awesome_print&lt;/code&gt; を使いたくなる。&lt;/p&gt;

&lt;p&gt;Rails アプリケーションの &lt;code&gt;Gemfile&lt;/code&gt; に &lt;code&gt;awesome_print&lt;/code&gt; を追加してロードできるようにしておく。
開発環境とテスト環境のみで利用可能に。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$RAILS_HOME/Gemfile&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;group :development, :test do
  gem 'awesome_print', '~&amp;gt; 1.0.2'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bundler でインストールしておく。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以下は Refinery CMS で使用した例。&lt;/p&gt;

&lt;p&gt;モデルオブジェクトを見てみる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ rails c
Loading development environment (Rails 3.2.2)
1.9.3p125 :001 &amp;gt; Refinery::Page
class Refinery::Page &amp;lt; Refinery::Core::BaseModel {
                     :id =&amp;gt; :integer,
              :parent_id =&amp;gt; :integer,
                   :path =&amp;gt; :string,
                   :slug =&amp;gt; :string,
           :show_in_menu =&amp;gt; :boolean,
               :link_url =&amp;gt; :string,
             :menu_match =&amp;gt; :string,
              :deletable =&amp;gt; :boolean,
                  :draft =&amp;gt; :boolean,
    :skip_to_first_child =&amp;gt; :boolean,
                    :lft =&amp;gt; :integer,
                    :rgt =&amp;gt; :integer,
                  :depth =&amp;gt; :integer,
          :view_template =&amp;gt; :string,
        :layout_template =&amp;gt; :string,
             :created_at =&amp;gt; :datetime,
             :updated_at =&amp;gt; :datetime
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-3-w500.png" alt="awesome_print-3" /&gt;&lt;/p&gt;

&lt;p&gt;検索結果は以下のような感じ。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;1.9.3p125 :002 &amp;gt; Refinery::Page.find(:first)
  Refinery::Page Load (0.5ms)  SELECT "refinery_pages".* FROM "refinery_pages" LIMIT 1
  Refinery::Page::Translation Load (0.3ms)  SELECT "refinery_page_translations".* FROM "refinery_page_translations" WHERE "refinery_page_translations"."refinery_page_id" = 1
#&amp;lt;Refinery::Page:0xa3f780c&amp;gt; {
                     :id =&amp;gt; 1,
              :parent_id =&amp;gt; nil,
                   :path =&amp;gt; "Home",
                   :slug =&amp;gt; "home",
           :show_in_menu =&amp;gt; true,
               :link_url =&amp;gt; "/",
             :menu_match =&amp;gt; "^/$",
              :deletable =&amp;gt; false,
                  :draft =&amp;gt; false,
    :skip_to_first_child =&amp;gt; false,
                    :lft =&amp;gt; 1,
                    :rgt =&amp;gt; 4,
                  :depth =&amp;gt; 0,
          :view_template =&amp;gt; nil,
        :layout_template =&amp;gt; nil,
             :created_at =&amp;gt; Sun, 18 Mar 2012 04:20:54 UTC +00:00,
             :updated_at =&amp;gt; Sun, 18 Mar 2012 12:27:27 UTC +00:00
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;実際のコンソールの画面。
&lt;img src="/assets/images/ruby-misc/awesome_print-4-w500.png" alt="awesome_print-4" /&gt;&lt;/p&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2012-03-18:/2012/03/18/refinerycms-v2-changelog/</id>
    <title type="html">Refinery CMS v2 変更点</title>
    <published>2012-03-18T14:30:00Z</published>
    <updated>2012-03-18T14:30:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2012/03/18/refinerycms-v2-changelog/"/>
    <content type="html">&lt;p&gt;2月後半に Refinery CMS のメジャーバージョンアップがされている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://refinerycms.com/blog/refinery-cms-2-0-0-released"&gt;Refinery CMS 2.0.0 released - Refinery CMS (2012/02/29)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Refinery 2.0 makes a number of very important updates to the project. Chief amongst these, Refinery now supports Rails 3.2 and the asset pipeline, and is now mountable as a Rails engine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rails 3.2 への対応が行われており、Ruby は 1.9.3 が推奨となっている。&lt;/p&gt;

&lt;p&gt;Refinery CMS 自体の仕組みでは、軽く触ってみたところ、名前空間の扱い、設定情報の扱いが大きく変わっていた。
&lt;a href="https://github.com/resolve/refinerycms/wiki/Changelog"&gt;Changelog - resolve/refinerycms Wiki - GitHub&lt;/a&gt; から変更点をまとめておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ワークフローの変更
    &lt;ul&gt;
      &lt;li&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要&lt;/li&gt;
      &lt;li&gt;設定情報 (Settings) は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; ディレクトリでカスマイズする(admin 機能でない)&lt;/li&gt;
      &lt;li&gt;Settings extension は Refiney Core には含まれなくなった&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Extensions の変更
    &lt;ul&gt;
      &lt;li&gt;extension の生成書式の変更&lt;/li&gt;
      &lt;li&gt;Settings (設定情報) は &lt;code&gt;RefinerySetting&lt;/code&gt; で扱われなくなった&lt;/li&gt;
      &lt;li&gt;公式(デフォルトで組み込まれている)の extension のネームスペースの変更&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;ワークフローの変更&lt;/h3&gt;

&lt;h4 id="extension-rake-dbseed-"&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要&lt;/h4&gt;

&lt;p&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要となっている。
extension を作成する際の適切なワークフロー以下の通りとなる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# Add extension to your Gemfile
rails g refinery:&amp;lt;your_extension&amp;gt;
rake db:migrate
rake db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="settings-configinitializersrefinery-admin-"&gt;設定情報 (Settings) は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; ディレクトリでカスマイズする(admin 機能でない)&lt;/h4&gt;

&lt;p&gt;Refinery アプリケーションの全ての設定は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; 内で行われる。
extension を作成した際には、上記ディレクトリ内にテンプレートから作成された設定がコピーされる。&lt;/p&gt;

&lt;h4 id="settings-extension--refiney-core-"&gt;Settings extension は Refiney Core には含まれなくなった&lt;/h4&gt;

&lt;p&gt;これまで Settings extension は Refinery Core に含まれてきていたが、Core から外れた。
別途 extension として導入は可能。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/parndt/refinerycms-settings"&gt;parndt/refinerycms-settings GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="extensions-"&gt;Extensions の変更&lt;/h3&gt;

&lt;h4 id="extension-"&gt;extension の生成書式の変更&lt;/h4&gt;

&lt;p&gt;v2.0 からは以下の書式で生成。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;rails generate refinery:engine &amp;lt;model_name&amp;gt; field:type field:type field:type
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;より詳細なオプションは、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;rails generate refinery:engine
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;で確認できる。&lt;/p&gt;

&lt;h4 id="settings---refinerysetting-"&gt;Settings (設定情報) は &lt;code&gt;RefinerySetting&lt;/code&gt; で扱われなくなった&lt;/h4&gt;

&lt;p&gt;Settings (設定情報)は &lt;code&gt;RefinerySetting&lt;/code&gt; からアクセスしていたが、使用されなくなり、代わりに &lt;code&gt;Refinery::&amp;lt;ExtensionNamespace&amp;gt;.value&lt;/code&gt; でアクセスする。&lt;/p&gt;

&lt;p&gt;例えば、&lt;code&gt;Prtfolio&lt;/code&gt; extension では、&lt;code&gt;Refinery::Portfolio.approximate_ascii_for_i18n&lt;/code&gt; でアクセスを行う。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;I18n&lt;/code&gt; などでも、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;&amp;gt; Refinery::I18n.default_locale
 =&amp;gt; :ja 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;という感じ。&lt;/p&gt;

&lt;p&gt;設定情報は、内部的には 2つの別のファイルの extension 内で扱われている。&lt;br /&gt;
1つは、&lt;code&gt;lib/refinery/&amp;lt;extension_name&amp;gt;/configuration.rb&lt;/code&gt; の中でデフォルトの値が宣言されており、
もう1つは、extension 生成時に generator から読み取られる &lt;code&gt;lib/generators/refinery/&amp;lt;extension_name&amp;gt;/templates/config/initializers/&amp;lt;extension_name&amp;gt;.rb.erb&lt;/code&gt; 内にテンプレートが記載されている。&lt;/p&gt;

&lt;p&gt;例えば、&lt;code&gt;I18n&lt;/code&gt; の場合は、&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;lib/refinery/i18n/configuration.rb&lt;/code&gt;(デフォルト値の設定):&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;module Refinery
  module I18n
    include ActiveSupport::Configurable

    config_accessor :current_locale, :default_locale, :default_frontend_locale,
                    :enabled, :frontend_locales, :locales

    self.enabled = true
    self.default_locale = :en
    self.default_frontend_locale = self.default_locale
    self.current_locale = self.default_locale
    self.frontend_locales = [self.default_frontend_locale]
    self.locales = self.built_in_locales
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;lib/generators/refinery/templates/config/initializers/refinery/i18n.rb.erb&lt;/code&gt;(テンプレートの設定):&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# encoding: utf-8

Refinery::I18n.configure do |config|
  # config.enabled = &amp;lt;%= Refinery::I18n.config.enabled.inspect %&amp;gt;

  # config.default_locale = &amp;lt;%= Refinery::I18n.config.default_locale.inspect %&amp;gt;

  # config.current_locale = &amp;lt;%= Refinery::I18n.config.current_locale.inspect %&amp;gt;

  # config.default_frontend_locale = &amp;lt;%= Refinery::I18n.config.default_frontend_locale.inspect %&amp;gt;

  # config.frontend_locales = &amp;lt;%= Refinery::I18n.config.frontend_locales.inspect %&amp;gt;

  # config.locales = &amp;lt;%= Refinery::I18n.config.locales.inspect %&amp;gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;となっている。&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;2月後半に Refinery CMS のメジャーバージョンアップがされている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://refinerycms.com/blog/refinery-cms-2-0-0-released"&gt;Refinery CMS 2.0.0 released - Refinery CMS (2012/02/29)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Refinery 2.0 makes a number of very important updates to the project. Chief amongst these, Refinery now supports Rails 3.2 and the asset pipeline, and is now mountable as a Rails engine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rails 3.2 への対応が行われており、Ruby は 1.9.3 が推奨となっている。&lt;/p&gt;

&lt;p&gt;Refinery CMS 自体の仕組みでは、軽く触ってみたところ、名前空間の扱い、設定情報の扱いが大きく変わっていた。
&lt;a href="https://github.com/resolve/refinerycms/wiki/Changelog"&gt;Changelog - resolve/refinerycms Wiki - GitHub&lt;/a&gt; から変更点をまとめておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ワークフローの変更
    &lt;ul&gt;
      &lt;li&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要&lt;/li&gt;
      &lt;li&gt;設定情報 (Settings) は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; ディレクトリでカスマイズする(admin 機能でない)&lt;/li&gt;
      &lt;li&gt;Settings extension は Refiney Core には含まれなくなった&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Extensions の変更
    &lt;ul&gt;
      &lt;li&gt;extension の生成書式の変更&lt;/li&gt;
      &lt;li&gt;Settings (設定情報) は &lt;code&gt;RefinerySetting&lt;/code&gt; で扱われなくなった&lt;/li&gt;
      &lt;li&gt;公式(デフォルトで組み込まれている)の extension のネームスペースの変更&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;ワークフローの変更&lt;/h3&gt;

&lt;h4 id="extension-rake-dbseed-"&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要&lt;/h4&gt;

&lt;p&gt;extension のインストールには、&lt;code&gt;rake db:seed&lt;/code&gt; の実行が必要となっている。
extension を作成する際の適切なワークフロー以下の通りとなる。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# Add extension to your Gemfile
rails g refinery:&amp;lt;your_extension&amp;gt;
rake db:migrate
rake db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="settings-configinitializersrefinery-admin-"&gt;設定情報 (Settings) は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; ディレクトリでカスマイズする(admin 機能でない)&lt;/h4&gt;

&lt;p&gt;Refinery アプリケーションの全ての設定は、&lt;code&gt;config/initializers/refinery&lt;/code&gt; 内で行われる。
extension を作成した際には、上記ディレクトリ内にテンプレートから作成された設定がコピーされる。&lt;/p&gt;

&lt;h4 id="settings-extension--refiney-core-"&gt;Settings extension は Refiney Core には含まれなくなった&lt;/h4&gt;

&lt;p&gt;これまで Settings extension は Refinery Core に含まれてきていたが、Core から外れた。
別途 extension として導入は可能。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/parndt/refinerycms-settings"&gt;parndt/refinerycms-settings GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="extensions-"&gt;Extensions の変更&lt;/h3&gt;

&lt;h4 id="extension-"&gt;extension の生成書式の変更&lt;/h4&gt;

&lt;p&gt;v2.0 からは以下の書式で生成。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;rails generate refinery:engine &amp;lt;model_name&amp;gt; field:type field:type field:type
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;より詳細なオプションは、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;rails generate refinery:engine
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;で確認できる。&lt;/p&gt;

&lt;h4 id="settings---refinerysetting-"&gt;Settings (設定情報) は &lt;code&gt;RefinerySetting&lt;/code&gt; で扱われなくなった&lt;/h4&gt;

&lt;p&gt;Settings (設定情報)は &lt;code&gt;RefinerySetting&lt;/code&gt; からアクセスしていたが、使用されなくなり、代わりに &lt;code&gt;Refinery::&amp;lt;ExtensionNamespace&amp;gt;.value&lt;/code&gt; でアクセスする。&lt;/p&gt;

&lt;p&gt;例えば、&lt;code&gt;Prtfolio&lt;/code&gt; extension では、&lt;code&gt;Refinery::Portfolio.approximate_ascii_for_i18n&lt;/code&gt; でアクセスを行う。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;I18n&lt;/code&gt; などでも、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;&amp;gt; Refinery::I18n.default_locale
 =&amp;gt; :ja 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;という感じ。&lt;/p&gt;

&lt;p&gt;設定情報は、内部的には 2つの別のファイルの extension 内で扱われている。&lt;br /&gt;
1つは、&lt;code&gt;lib/refinery/&amp;lt;extension_name&amp;gt;/configuration.rb&lt;/code&gt; の中でデフォルトの値が宣言されており、
もう1つは、extension 生成時に generator から読み取られる &lt;code&gt;lib/generators/refinery/&amp;lt;extension_name&amp;gt;/templates/config/initializers/&amp;lt;extension_name&amp;gt;.rb.erb&lt;/code&gt; 内にテンプレートが記載されている。&lt;/p&gt;

&lt;p&gt;例えば、&lt;code&gt;I18n&lt;/code&gt; の場合は、&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;lib/refinery/i18n/configuration.rb&lt;/code&gt;(デフォルト値の設定):&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;module Refinery
  module I18n
    include ActiveSupport::Configurable

    config_accessor :current_locale, :default_locale, :default_frontend_locale,
                    :enabled, :frontend_locales, :locales

    self.enabled = true
    self.default_locale = :en
    self.default_frontend_locale = self.default_locale
    self.current_locale = self.default_locale
    self.frontend_locales = [self.default_frontend_locale]
    self.locales = self.built_in_locales
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;lib/generators/refinery/templates/config/initializers/refinery/i18n.rb.erb&lt;/code&gt;(テンプレートの設定):&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;# encoding: utf-8

Refinery::I18n.configure do |config|
  # config.enabled = &amp;lt;%= Refinery::I18n.config.enabled.inspect %&amp;gt;

  # config.default_locale = &amp;lt;%= Refinery::I18n.config.default_locale.inspect %&amp;gt;

  # config.current_locale = &amp;lt;%= Refinery::I18n.config.current_locale.inspect %&amp;gt;

  # config.default_frontend_locale = &amp;lt;%= Refinery::I18n.config.default_frontend_locale.inspect %&amp;gt;

  # config.frontend_locales = &amp;lt;%= Refinery::I18n.config.frontend_locales.inspect %&amp;gt;

  # config.locales = &amp;lt;%= Refinery::I18n.config.locales.inspect %&amp;gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;となっている。&lt;/p&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2012-03-11:/2012/03/11/nginx-configuration-summary/</id>
    <title type="html">Nginx の設定概要</title>
    <published>2012-03-11T04:30:00Z</published>
    <updated>2012-03-11T04:30:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2012/03/11/nginx-configuration-summary/"/>
    <content type="html">&lt;p&gt;&lt;a href="http://wiki.nginx.org/Main"&gt;Nginx&lt;/a&gt; に関して、とりあえず最初の一歩としてこれだけ知っておけば何とかなる、という内容をまとめておきたくメモを残すことにした。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; のページがとてもよくまとめられていたので、このページの内容をベースに書かせてもらった。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;全体的な構成&lt;/li&gt;
  &lt;li&gt;グローバルな設定&lt;/li&gt;
  &lt;li&gt;サーバの設定 - &lt;code&gt;server&lt;/code&gt; ディレクティブ
    &lt;ul&gt;
      &lt;li&gt;listen ポートの設定 - &lt;code&gt;listen&lt;/code&gt; ディレクティブ&lt;/li&gt;
      &lt;li&gt;バーチャルホストの設定 - &lt;code&gt;server_name&lt;/code&gt; ディレクティブ&lt;/li&gt;
      &lt;li&gt;リソース(ロケーション)の設定 - &lt;code&gt;location&lt;/code&gt; ディレクティブ&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;設定ファイルの管理&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;全体的な構成&lt;/h3&gt;

&lt;p&gt;Nginx の設定に関しては、まずは、&lt;strong&gt;ディレクティブ&lt;/strong&gt;、&lt;strong&gt;ブロック&lt;/strong&gt;、&lt;strong&gt;コンテキスト&lt;/strong&gt;という言葉をおさえておく。&lt;/p&gt;

&lt;p&gt;Nginx はインストール直後ですぐに使える状態になっており、設定は &lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; に記載されている。(&lt;code&gt;$NGINX_ROOT&lt;/code&gt;は Nginx がインストールされているルートディレクトリに読み替えること。)&lt;/p&gt;

&lt;p&gt;その設定ファイル内のざっくりとした構成は以下のような感じになっている。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;#user  nobody;
worker_processes  1;
...
events {
  ...
}

http {
  ...
  server {
    ...
    location / {
      ...
    }
    ...
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;worker_processes&lt;/code&gt;、&lt;code&gt;events&lt;/code&gt;、&lt;code&gt;http&lt;/code&gt;、&lt;code&gt;server&lt;/code&gt;、&lt;code&gt;ocation&lt;/code&gt; というのが&lt;strong&gt;ディレクティブ&lt;/strong&gt;であり、&lt;code&gt;events&lt;/code&gt;、&lt;code&gt;http&lt;/code&gt;、&lt;code&gt;server&lt;/code&gt;、&lt;code&gt;location&lt;/code&gt; などは&lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt; (中括弧)で囲まれた&lt;strong&gt;ブロック&lt;/strong&gt;を引数に持っている。
この&lt;strong&gt;ブロック&lt;/strong&gt;を含めた&lt;strong&gt;ディレクティブ&lt;/strong&gt;の引数に Nginx で記載可能なシンタックスを使用して条件文などを混じえて&lt;strong&gt;ディレクティブ&lt;/strong&gt;を記載していく。&lt;/p&gt;

&lt;p&gt;Nginx はネストされた&lt;strong&gt;ブロック&lt;/strong&gt;の構文を使用でき、上記のように &lt;code&gt;http&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;に &lt;code&gt;server&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;がネストされている構文をとれる。この時、&lt;code&gt;server&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;は &lt;code&gt;http&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;の&lt;strong&gt;コンテキスト&lt;/strong&gt;にあると言う。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ディレクティブ&lt;/strong&gt;は、&lt;strong&gt;コンテキスト&lt;/strong&gt;によって使えるもの、使えないものとがあるので、ドキュメント &lt;a href="http://wiki.nginx.org/Modules"&gt;Modules&lt;/a&gt; で確認する。&lt;br /&gt;
ドキュメントの記載は以下のように、ディレクティブ名、シンタックス、デフォルト動作、コンテキストの記載があり、その後にそのディレクティブの詳細説明が続く構成となっている。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; location
 
 syntax: location [=|~|~*|^~|@] /uri/ { ... }
 
 default: no
 
 context: server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;インストール時のオプション、パッケージマネージャー等で多少の違いはあるが、インストール直後の &lt;code&gt;$NGINX_ROOT&lt;/code&gt; ディレクトリ配下は以下の構成となっている。(&lt;code&gt;include&lt;/code&gt; ディレクティブでは起点が &lt;code&gt;nginx.conf&lt;/code&gt; の存在するディレクトリになる。後述。)&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ll
total 42
drwx------  2 nginx root 4096 2012-03-04 15:21 client_body_temp
drwxr-xr-x  4 root  root 4096 2012-03-10 14:46 conf
drwx------  2 nginx root 4096 2012-03-04 15:21 fastcgi_temp
drwxr-xr-x  2 root  root 4096 2012-03-04 15:14 html
drwxr-xr-x  2 nginx root 4096 2012-03-10 17:22 logs
drwx------  5 nginx root 4096 2012-03-05 22:30 proxy_temp
drwxr-xr-x  2 root  root 4096 2012-03-04 15:14 sbin
drwx------  2 nginx root 4096 2012-03-04 15:21 scgi_temp
drwx------  2 nginx root 4096 2012-03-04 15:21 uwsgi_temp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設定内でのパスの指定には、絶対パスと相対パスが使えるが、相対パスを使った場合の起点は、&lt;code&gt;$NGINX_ROOT&lt;/code&gt; となる。&lt;/p&gt;

&lt;p&gt;デフォルトの設定ファイルは、 &lt;code&gt;$NGINX_ROOT/conf/nginx.conf.default&lt;/code&gt; として残されており、このファイルを読みながら、Nginx の設定の概要を掴むことにする。&lt;/p&gt;

&lt;h3 id="section-1"&gt;グローバルな設定&lt;/h3&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記の記載で &lt;code&gt;nginx.conf.default&lt;/code&gt; は始まっている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;#&lt;/code&gt; で始まる行はコメントなので解釈されない。&lt;/li&gt;
  &lt;li&gt;ディレクティブは変数(例: &lt;code&gt;worker_processes&lt;/code&gt;, &lt;code&gt;pid&lt;/code&gt;)で始まり、その引数(1, &lt;code&gt;logs/nginx.pid&lt;/code&gt;)、または、連続した引数(&lt;code&gt;logs/error.log  notice&lt;/code&gt;)を含む。&lt;/li&gt;
  &lt;li&gt;全てのディレクティブは &lt;code&gt;;&lt;/code&gt; (セミコロン)で終える。&lt;/li&gt;
  &lt;li&gt;ディレクティブにはサブディレクティブを含む(ネストする)ことができる。(上記の &lt;code&gt;events&lt;/code&gt; のように。)&lt;br /&gt;
これらのサブディレクティブは &lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt; を使って、コンテキストとスコープを定義する。&lt;/li&gt;
  &lt;li&gt;スペースは無視されるので、インデントをうまく使って可読性を上げることができる。&lt;/li&gt;
  &lt;li&gt;Nginx は、1つのマスタープロセスと実際にリクエストを処理する複数のワーカープロセスで動作する。ワーカープロセスは非特権ユーザで動作するが、&lt;code&gt;user&lt;/code&gt; ディレクティブにはそのユーザを指定できる。&lt;code&gt;worker_processes&lt;/code&gt; には、動作させるワーカープロセスのプロセス数を指定する。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;さらに読み進める。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;http&lt;/code&gt; ディレクティブのブロック(&lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt;)が書かれている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;include&lt;/code&gt; ディレクティブは &lt;code&gt;mime.types&lt;/code&gt; ファイルをインクルードしている。相対パスでの記述になっており、この設定ファイルと同じディレクトリに &lt;code&gt;mime.types&lt;/code&gt; ファイルが存在する。通常、設定ファイルに記載される相対パスは、&lt;code&gt;$NGINX_ROOT&lt;/code&gt; が起点となるが、&lt;code&gt;include&lt;/code&gt; ディレクティブの場合は、&lt;code&gt;nginx.conf&lt;/code&gt; ファイルの存在するディレクトリが起点となる。(Since version 0.6.7 &lt;a href="http://wiki.nginx.org/CoreModule#include"&gt;CoreModule::include&lt;/a&gt;)&lt;br /&gt;
このように設定ファイルを外出して &lt;code&gt;include&lt;/code&gt; ステートメントで読み込むことができるので、設定ファイルの可動性はあがり、管理し易くなっている。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;log_format&lt;/code&gt; をコメントアウトし、要件に合わせたログフォーマットに変更することができる。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;gzip&lt;/code&gt; ディレクティブはラストマイル環境がよくない場合など効果を発揮するコンテンツの圧縮をオンザフライで実行する。Apache でいうところの &lt;code&gt;mod_deflate&lt;/code&gt; の機能。細かな設定が行えるので、詳細は &lt;a href="http://wiki.nginx.org/HttpGzipModule"&gt;HttpGzipModule&lt;/a&gt; を参照のこと。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;access_log&lt;/code&gt; ディレクティブの設定サンプルを見てみる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;access_log logs/example.access.log;
access_log /srv/http/example.org/logs/access.log;
access_log /var/log/nginx/access/example.org;
access_log off;
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;最初の例では、相対パスになっているので、この場合は、ログは&lt;code&gt;$NGINX_ROOT/logs/example.access.log&lt;/code&gt;に記録される。&lt;/li&gt;
  &lt;li&gt;続く2つ目、3つ目の例では、&lt;code&gt;access.log&lt;/code&gt; へのフルパスでの指定を行っている。&lt;/li&gt;
  &lt;li&gt;ログを残したく無い場合、4つ目の例のようにオフにすることも可能。(あまりやらないだろうが・・・)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="server-"&gt;サーバの設定 - server ディレクティブ&lt;/h3&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記の &lt;code&gt;server&lt;/code&gt; ディレクティブは、&lt;code&gt;http&lt;/code&gt; ディレクティブに内包されている(&lt;code&gt;http&lt;/code&gt; ディレクティブのコンテキストにある)。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;server&lt;/code&gt; ディレクティブのブロックはそれぞれのサーバ自体の設定を行うところとなる。&lt;/p&gt;

&lt;h4 id="listen----listen-"&gt;listen ポートの設定 - &lt;code&gt;listen&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;まず &lt;code&gt;listen&lt;/code&gt; ディレクティブだが、上記は 80 番ポートで待機していることを意味する。更に柔軟な記載が行えるようになっているので、詳細は、&lt;a href="http://wiki.nginx.org/HttpCoreModule#listen"&gt;HttpCoreModule::listen&lt;/a&gt; を参照のこと。&lt;/p&gt;

&lt;h4 id="servername-"&gt;バーチャルホストの設定 - &lt;code&gt;server_name&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt; ディレクティブは、名前ベースのバーチャルホストを実現する。&lt;br /&gt;
1つの IP アドレスで待機しているサーバは、リクエストヘッダーの HOST 名に基づいて、複数のドメインのホスティングを行える。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# サンプル1
server_name   example.com;
# サンプル2
server_name   example.com www.example.com;
# サンプル3
server_name   *.example.com;
# サンプル4
server_name   .example.com;
# サンプル5
server_name   example.*;
# サンプル6
server_name   example.com exmaple.net example.org;
# サンプル7
server_name   localhost example1 example2;
# サンプル8
server_name   "";
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記サンプルは、&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic#sph_server-configuration"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; の例から使わせてもらっている。&lt;/p&gt;

&lt;p&gt;個々の名前は、スペース区切りで記述できる。Nginx はサーバに対して１つ以上の名前を持たせることができ、特定の &lt;code&gt;server_name&lt;/code&gt; ディレクティブは1つ以上の名前のリクエストに応答する。また、ワイルドカードの定義や、正規表現での定義も行える。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;最初のサンプルは、&lt;code&gt;server_name&lt;/code&gt; に &lt;code&gt;example.com&lt;/code&gt; を定義している。これにより、&lt;code&gt;http://example.com&lt;/code&gt; にはこのサーバが応答する。&lt;/li&gt;
  &lt;li&gt;2つ目の例の &lt;code&gt;example.com www.example.com&lt;/code&gt; の場合、&lt;code&gt;http://example.com&lt;/code&gt; と &lt;code&gt;http://www.example.com&lt;/code&gt; に応答する。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;*.example.com&lt;/code&gt; と &lt;code&gt;.example.com&lt;/code&gt; の記述の意味は等しい。また、この記述の場合、サブドメインも全てハンドリングする。例えば、&lt;code&gt;www.example.com&lt;/code&gt;、&lt;code&gt;img.example.com&lt;/code&gt;、&lt;code&gt;search.example.com&lt;/code&gt; など。&lt;/li&gt;
  &lt;li&gt;5つ目の例の &lt;code&gt;example.*&lt;/code&gt; の記述は、&lt;code&gt;example&lt;/code&gt; で始まる全てのドメインへのリクエストをハンドルする。
例えば、&lt;code&gt;example.com&lt;/code&gt;、&lt;code&gt;example.net&lt;/code&gt;、&lt;code&gt;example.org&lt;/code&gt; など。&lt;code&gt;example.wao.com&lt;/code&gt;、&lt;code&gt;example.hello.com&lt;/code&gt; も同様。&lt;/li&gt;
  &lt;li&gt;6つ目の &lt;code&gt;example.com exmaple.net example.org&lt;/code&gt; は3つのドメイン全てへのリクエストをハンドルする。&lt;/li&gt;
  &lt;li&gt;Nginx は無効なドメイン名でもバーチャルホストとして定義できる。7つ目の例の &lt;code&gt;localhost example1 example2&lt;/code&gt; の場合、ホスト名となっているが、Nginx はリクエストの HTTP のヘッダのみを見てリクエストを処理するので、有効なドメイン名である必要はない。ただし、この場合は、hosts ファイルにホスト名が定義されている必要がある。&lt;/li&gt;
  &lt;li&gt;最後の &lt;code&gt;""&lt;/code&gt; の定義では、Nginx は全てのリクエストを処理することを意味する。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id="location-"&gt;リソース(ロケーション)の設定 - &lt;code&gt;location&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;次に &lt;code&gt;location&lt;/code&gt; ディレクティブ。&lt;code&gt;location&lt;/code&gt; ディレクティブは、クライアントによってリクエストされたロケーションに対する振舞いを定義する。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;location&lt;/code&gt; ディレクティブは、そのブロックの前に適用するパターンを記載する。シンタックスは以下の通りとなっており、まずはこの動作概要を掴んでおくことが必要。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;location [=|~|~*|^~|@] pattern { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic#sph_server-configuration"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; の例を利用させていただき、その動作を理解する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# パターングループ1
location / { }
location /images/ { }
location /blog/ { }
location /planet/ { }
location /planet/blog/ { }

# パターングループ2
location ~ IndexPage\.php$ { }
location ~ ^/BlogPlanet(/|/index\.php)$ { }

# パターングループ3
location ~* \.(pl|cgi|perl|prl)$ { }
location ~* \.(md|mdwn|txt|mkdn)$ { }

# パターングループ4
location ^~ /images/IndexPage/ { }
location ^~ /blog/BlogPlanet/ { }

# パターングループ5
location = / { }
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;最初の5つのサンプルはリテラル文字列マッチと言われるもの。ホスト名に続くリクエストの最初のパートにマッチする。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;server_name&lt;/code&gt; に &lt;code&gt;example.com&lt;/code&gt; が設定されており、&lt;code&gt;http://example.com/&lt;/code&gt; へのリクエストがあったとする。この時、”&lt;code&gt;location /&lt;/code&gt;” ディレクティブはこのリクエストにマッチする。Nginx は “most specific match” でリクエストの条件を満たす。&lt;code&gt;http://example.com/planet/blog/&lt;/code&gt; と &lt;code&gt;http://example.com/planet/blog/about&lt;/code&gt; へのリクエストは、”&lt;code&gt;location /planet/blog/&lt;/code&gt;” で満たされる。当然、”&lt;code&gt;location /planet/&lt;/code&gt;” でも満たされることになる。&lt;/li&gt;
  &lt;li&gt;2つ目のグループの &lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; (チルダ)に続くサンプルでは、Nginx は正規表現での適用を行う。これらの &lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; だけのマッチ表現は case-sensive (大文字小文字を区別する) になる。最初の例では、&lt;code&gt;IndexPage.php&lt;/code&gt; はマッチするが、&lt;code&gt;indexpage.php&lt;/code&gt; はマッチしない。また、&lt;code&gt;/BlogPlanet&lt;/code&gt;、&lt;code&gt;/blogplanet/&lt;/code&gt;、&lt;code&gt;/blogplanet/index.php&lt;/code&gt; もマッチしない。Nginx は Perl Compatible Regular Expressions (PCRE) を使用している。&lt;/li&gt;
  &lt;li&gt;3つ目のグループの &lt;strong&gt;&lt;code&gt;~*&lt;/code&gt;&lt;/strong&gt; の表現は、&lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; の場合と同じく正規表現でのマッチで、case-insentive (大文字小文字を区別しない)になる。ここでの表現では、特定の拡張子で終わるファイル名に対してどう処理するのかを定義している。最初の例では、.pl、.PL、.cgi、.CGI、.perl、.Perl、.prl、.PrL、何れの拡張子のファイルにも適用される。&lt;/li&gt;
  &lt;li&gt;4つ目のグループの &lt;strong&gt;&lt;code&gt;^~&lt;/code&gt;&lt;/strong&gt; の表現は、最初のグループの&lt;strong&gt;リテラル文字列マッチのように動作する&lt;/strong&gt;。注意点として、&lt;strong&gt;このマッチ文が適用されると Nginx はパターンの検索を中止する&lt;/strong&gt;。”&lt;code&gt;^~ /images/IndexPage/&lt;/code&gt;“、”&lt;code&gt;^~ /blog/BlogPlanet/&lt;/code&gt;” パターンでの &lt;code&gt;location&lt;/code&gt; ディレクティブは、仮に他にマッチする &lt;code&gt;location&lt;/code&gt; ディレクティブが他にあったとしても、このパターンがマッチした時点で使用される。&lt;/li&gt;
  &lt;li&gt;最後の &lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt; の表現は、リクエストされたパスに完全一致した場合に適用され、&lt;strong&gt;マッチした時点で他のパターンの検索を中止する&lt;/strong&gt;。例えば、最後のサンプルは、&lt;code&gt;http://example.com/&lt;/code&gt; にはマッチするが、&lt;code&gt;http://example.com/index.html&lt;/code&gt; にはマッチしない。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ここまでの記述だけでは、&lt;code&gt;location&lt;/code&gt; ディレクティブの全体の適用順がイマイチ掴みきれない。&lt;code&gt;location&lt;/code&gt; ディレクティブのパターン適用ルールは以下の通りとなる。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;完全一致(&lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt;)が最初に処理される。マッチするものが見つかった場合、Nginx はそこでパターンの検索を中止し、リクエストを実行する。&lt;/li&gt;
  &lt;li&gt;次に残りのリテラル文字列ディレクティブが処理される。もし、&lt;strong&gt;&lt;code&gt;^~&lt;/code&gt;&lt;/strong&gt; が使用されていれば、Nginx はそこでパターンの検索を中止し、リクエストを実行する。それ以外の場合は、Nginx は &lt;code&gt;location&lt;/code&gt; ディレクティブを処理し続ける。&lt;/li&gt;
  &lt;li&gt;正規表現で定義された(&lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;~*&lt;/code&gt;&lt;/strong&gt;)全ての &lt;code&gt;location&lt;/code&gt; ディレクティブが処理される。正規表現がマッチしたら、Nginx はそこでパターンの検索を中止し、リクエストを実行する。&lt;/li&gt;
  &lt;li&gt;正規表現がない、または、正規表現がマッチしなかったときは、最も適切なリテラル文字列のパターンが使用される。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;一旦 Nginx が特定のリクエストに対してリソースを提供する “&lt;code&gt;location&lt;/code&gt;” を選択したら、このリクエストに対するレスポンスは、”&lt;code&gt;location&lt;/code&gt;” ディレクティブのブロックによって定義される。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;location / {
    root   html;
    index  index.html index.htm;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ドキュメントルートは、&lt;code&gt;root&lt;/code&gt; ディレクティブによって、html ディレクトリに定義されている。上記は相対パスでの指定なので、実際のディレクトリは、&lt;code&gt;$NGINX_ROOT/html&lt;/code&gt; となる。&lt;code&gt;/blog/includes/style.css&lt;/code&gt; へのリクエストは、他の &lt;code&gt;location&lt;/code&gt; ディレクティブがマッチしていないと想定した場合、&lt;code&gt;$NGINX_ROOT/html/blog/includes/style.css&lt;/code&gt; にあるファイルがリソースの対象となる。&lt;code&gt;root&lt;/code&gt; ディレクティブには絶対パスを指定することもできる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index&lt;/code&gt; ディレクティブはリクエストがファイル名を含んでいない場合に、ファイルシステムのどのファイルが使用されるべきかを指定する。&lt;code&gt;http://example.com/&lt;/code&gt; へのリクエストは、&lt;code&gt;$NGINX_ROOT/http/index.html&lt;/code&gt; のファイルがリソースの対象となる。複数のファイル名指定されている場合、Nginx は順にそのリストを処理し、存在するファイルにリクエストを適用する。上記の例の場合、&lt;code&gt;index.html&lt;/code&gt; が存在しなければ、&lt;code&gt;index.htm&lt;/code&gt; が使用される。仮にどちらも存在しない場合には、404 メッセーが送出される。&lt;/p&gt;

&lt;h3 id="section-2"&gt;設定ファイルの管理&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;include&lt;/code&gt; ディレクティブを活用し、ベースとなる &lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; には必要最低限の記述のみを行い、各サーバ毎の固有の設定は別ファイルに切り出しておくとメンテナンス性があがる。&lt;/p&gt;

&lt;p&gt;例えば、以下のような書き方。&lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; の内容は至ってシンプルになる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;user nginx;
worker_processes 4;
pid /var/run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最後の &lt;code&gt;include&lt;/code&gt; ディレクティブによって、個々のバーチャルホスト毎の設定は別ファイルに定義を行っている。&lt;/p&gt;

&lt;h3 id="section-3"&gt;参考情報&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://wiki.nginx.org/Modules"&gt;Nginx Modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <summary type="html">&lt;p&gt;&lt;a href="http://wiki.nginx.org/Main"&gt;Nginx&lt;/a&gt; に関して、とりあえず最初の一歩としてこれだけ知っておけば何とかなる、という内容をまとめておきたくメモを残すことにした。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; のページがとてもよくまとめられていたので、このページの内容をベースに書かせてもらった。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;全体的な構成&lt;/li&gt;
  &lt;li&gt;グローバルな設定&lt;/li&gt;
  &lt;li&gt;サーバの設定 - &lt;code&gt;server&lt;/code&gt; ディレクティブ
    &lt;ul&gt;
      &lt;li&gt;listen ポートの設定 - &lt;code&gt;listen&lt;/code&gt; ディレクティブ&lt;/li&gt;
      &lt;li&gt;バーチャルホストの設定 - &lt;code&gt;server_name&lt;/code&gt; ディレクティブ&lt;/li&gt;
      &lt;li&gt;リソース(ロケーション)の設定 - &lt;code&gt;location&lt;/code&gt; ディレクティブ&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;設定ファイルの管理&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;全体的な構成&lt;/h3&gt;

&lt;p&gt;Nginx の設定に関しては、まずは、&lt;strong&gt;ディレクティブ&lt;/strong&gt;、&lt;strong&gt;ブロック&lt;/strong&gt;、&lt;strong&gt;コンテキスト&lt;/strong&gt;という言葉をおさえておく。&lt;/p&gt;

&lt;p&gt;Nginx はインストール直後ですぐに使える状態になっており、設定は &lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; に記載されている。(&lt;code&gt;$NGINX_ROOT&lt;/code&gt;は Nginx がインストールされているルートディレクトリに読み替えること。)&lt;/p&gt;

&lt;p&gt;その設定ファイル内のざっくりとした構成は以下のような感じになっている。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;#user  nobody;
worker_processes  1;
...
events {
  ...
}

http {
  ...
  server {
    ...
    location / {
      ...
    }
    ...
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;worker_processes&lt;/code&gt;、&lt;code&gt;events&lt;/code&gt;、&lt;code&gt;http&lt;/code&gt;、&lt;code&gt;server&lt;/code&gt;、&lt;code&gt;ocation&lt;/code&gt; というのが&lt;strong&gt;ディレクティブ&lt;/strong&gt;であり、&lt;code&gt;events&lt;/code&gt;、&lt;code&gt;http&lt;/code&gt;、&lt;code&gt;server&lt;/code&gt;、&lt;code&gt;location&lt;/code&gt; などは&lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt; (中括弧)で囲まれた&lt;strong&gt;ブロック&lt;/strong&gt;を引数に持っている。
この&lt;strong&gt;ブロック&lt;/strong&gt;を含めた&lt;strong&gt;ディレクティブ&lt;/strong&gt;の引数に Nginx で記載可能なシンタックスを使用して条件文などを混じえて&lt;strong&gt;ディレクティブ&lt;/strong&gt;を記載していく。&lt;/p&gt;

&lt;p&gt;Nginx はネストされた&lt;strong&gt;ブロック&lt;/strong&gt;の構文を使用でき、上記のように &lt;code&gt;http&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;に &lt;code&gt;server&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;がネストされている構文をとれる。この時、&lt;code&gt;server&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;は &lt;code&gt;http&lt;/code&gt; &lt;strong&gt;ディレクティブ&lt;/strong&gt;の&lt;strong&gt;コンテキスト&lt;/strong&gt;にあると言う。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ディレクティブ&lt;/strong&gt;は、&lt;strong&gt;コンテキスト&lt;/strong&gt;によって使えるもの、使えないものとがあるので、ドキュメント &lt;a href="http://wiki.nginx.org/Modules"&gt;Modules&lt;/a&gt; で確認する。&lt;br /&gt;
ドキュメントの記載は以下のように、ディレクティブ名、シンタックス、デフォルト動作、コンテキストの記載があり、その後にそのディレクティブの詳細説明が続く構成となっている。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; location
 
 syntax: location [=|~|~*|^~|@] /uri/ { ... }
 
 default: no
 
 context: server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;インストール時のオプション、パッケージマネージャー等で多少の違いはあるが、インストール直後の &lt;code&gt;$NGINX_ROOT&lt;/code&gt; ディレクトリ配下は以下の構成となっている。(&lt;code&gt;include&lt;/code&gt; ディレクティブでは起点が &lt;code&gt;nginx.conf&lt;/code&gt; の存在するディレクトリになる。後述。)&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ll
total 42
drwx------  2 nginx root 4096 2012-03-04 15:21 client_body_temp
drwxr-xr-x  4 root  root 4096 2012-03-10 14:46 conf
drwx------  2 nginx root 4096 2012-03-04 15:21 fastcgi_temp
drwxr-xr-x  2 root  root 4096 2012-03-04 15:14 html
drwxr-xr-x  2 nginx root 4096 2012-03-10 17:22 logs
drwx------  5 nginx root 4096 2012-03-05 22:30 proxy_temp
drwxr-xr-x  2 root  root 4096 2012-03-04 15:14 sbin
drwx------  2 nginx root 4096 2012-03-04 15:21 scgi_temp
drwx------  2 nginx root 4096 2012-03-04 15:21 uwsgi_temp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設定内でのパスの指定には、絶対パスと相対パスが使えるが、相対パスを使った場合の起点は、&lt;code&gt;$NGINX_ROOT&lt;/code&gt; となる。&lt;/p&gt;

&lt;p&gt;デフォルトの設定ファイルは、 &lt;code&gt;$NGINX_ROOT/conf/nginx.conf.default&lt;/code&gt; として残されており、このファイルを読みながら、Nginx の設定の概要を掴むことにする。&lt;/p&gt;

&lt;h3 id="section-1"&gt;グローバルな設定&lt;/h3&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記の記載で &lt;code&gt;nginx.conf.default&lt;/code&gt; は始まっている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;#&lt;/code&gt; で始まる行はコメントなので解釈されない。&lt;/li&gt;
  &lt;li&gt;ディレクティブは変数(例: &lt;code&gt;worker_processes&lt;/code&gt;, &lt;code&gt;pid&lt;/code&gt;)で始まり、その引数(1, &lt;code&gt;logs/nginx.pid&lt;/code&gt;)、または、連続した引数(&lt;code&gt;logs/error.log  notice&lt;/code&gt;)を含む。&lt;/li&gt;
  &lt;li&gt;全てのディレクティブは &lt;code&gt;;&lt;/code&gt; (セミコロン)で終える。&lt;/li&gt;
  &lt;li&gt;ディレクティブにはサブディレクティブを含む(ネストする)ことができる。(上記の &lt;code&gt;events&lt;/code&gt; のように。)&lt;br /&gt;
これらのサブディレクティブは &lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt; を使って、コンテキストとスコープを定義する。&lt;/li&gt;
  &lt;li&gt;スペースは無視されるので、インデントをうまく使って可読性を上げることができる。&lt;/li&gt;
  &lt;li&gt;Nginx は、1つのマスタープロセスと実際にリクエストを処理する複数のワーカープロセスで動作する。ワーカープロセスは非特権ユーザで動作するが、&lt;code&gt;user&lt;/code&gt; ディレクティブにはそのユーザを指定できる。&lt;code&gt;worker_processes&lt;/code&gt; には、動作させるワーカープロセスのプロセス数を指定する。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;さらに読み進める。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;http&lt;/code&gt; ディレクティブのブロック(&lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt;)が書かれている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;include&lt;/code&gt; ディレクティブは &lt;code&gt;mime.types&lt;/code&gt; ファイルをインクルードしている。相対パスでの記述になっており、この設定ファイルと同じディレクトリに &lt;code&gt;mime.types&lt;/code&gt; ファイルが存在する。通常、設定ファイルに記載される相対パスは、&lt;code&gt;$NGINX_ROOT&lt;/code&gt; が起点となるが、&lt;code&gt;include&lt;/code&gt; ディレクティブの場合は、&lt;code&gt;nginx.conf&lt;/code&gt; ファイルの存在するディレクトリが起点となる。(Since version 0.6.7 &lt;a href="http://wiki.nginx.org/CoreModule#include"&gt;CoreModule::include&lt;/a&gt;)&lt;br /&gt;
このように設定ファイルを外出して &lt;code&gt;include&lt;/code&gt; ステートメントで読み込むことができるので、設定ファイルの可動性はあがり、管理し易くなっている。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;log_format&lt;/code&gt; をコメントアウトし、要件に合わせたログフォーマットに変更することができる。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;gzip&lt;/code&gt; ディレクティブはラストマイル環境がよくない場合など効果を発揮するコンテンツの圧縮をオンザフライで実行する。Apache でいうところの &lt;code&gt;mod_deflate&lt;/code&gt; の機能。細かな設定が行えるので、詳細は &lt;a href="http://wiki.nginx.org/HttpGzipModule"&gt;HttpGzipModule&lt;/a&gt; を参照のこと。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;access_log&lt;/code&gt; ディレクティブの設定サンプルを見てみる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;access_log logs/example.access.log;
access_log /srv/http/example.org/logs/access.log;
access_log /var/log/nginx/access/example.org;
access_log off;
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;最初の例では、相対パスになっているので、この場合は、ログは&lt;code&gt;$NGINX_ROOT/logs/example.access.log&lt;/code&gt;に記録される。&lt;/li&gt;
  &lt;li&gt;続く2つ目、3つ目の例では、&lt;code&gt;access.log&lt;/code&gt; へのフルパスでの指定を行っている。&lt;/li&gt;
  &lt;li&gt;ログを残したく無い場合、4つ目の例のようにオフにすることも可能。(あまりやらないだろうが・・・)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="server-"&gt;サーバの設定 - server ディレクティブ&lt;/h3&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記の &lt;code&gt;server&lt;/code&gt; ディレクティブは、&lt;code&gt;http&lt;/code&gt; ディレクティブに内包されている(&lt;code&gt;http&lt;/code&gt; ディレクティブのコンテキストにある)。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;server&lt;/code&gt; ディレクティブのブロックはそれぞれのサーバ自体の設定を行うところとなる。&lt;/p&gt;

&lt;h4 id="listen----listen-"&gt;listen ポートの設定 - &lt;code&gt;listen&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;まず &lt;code&gt;listen&lt;/code&gt; ディレクティブだが、上記は 80 番ポートで待機していることを意味する。更に柔軟な記載が行えるようになっているので、詳細は、&lt;a href="http://wiki.nginx.org/HttpCoreModule#listen"&gt;HttpCoreModule::listen&lt;/a&gt; を参照のこと。&lt;/p&gt;

&lt;h4 id="servername-"&gt;バーチャルホストの設定 - &lt;code&gt;server_name&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt; ディレクティブは、名前ベースのバーチャルホストを実現する。&lt;br /&gt;
1つの IP アドレスで待機しているサーバは、リクエストヘッダーの HOST 名に基づいて、複数のドメインのホスティングを行える。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# サンプル1
server_name   example.com;
# サンプル2
server_name   example.com www.example.com;
# サンプル3
server_name   *.example.com;
# サンプル4
server_name   .example.com;
# サンプル5
server_name   example.*;
# サンプル6
server_name   example.com exmaple.net example.org;
# サンプル7
server_name   localhost example1 example2;
# サンプル8
server_name   "";
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記サンプルは、&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic#sph_server-configuration"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; の例から使わせてもらっている。&lt;/p&gt;

&lt;p&gt;個々の名前は、スペース区切りで記述できる。Nginx はサーバに対して１つ以上の名前を持たせることができ、特定の &lt;code&gt;server_name&lt;/code&gt; ディレクティブは1つ以上の名前のリクエストに応答する。また、ワイルドカードの定義や、正規表現での定義も行える。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;最初のサンプルは、&lt;code&gt;server_name&lt;/code&gt; に &lt;code&gt;example.com&lt;/code&gt; を定義している。これにより、&lt;code&gt;http://example.com&lt;/code&gt; にはこのサーバが応答する。&lt;/li&gt;
  &lt;li&gt;2つ目の例の &lt;code&gt;example.com www.example.com&lt;/code&gt; の場合、&lt;code&gt;http://example.com&lt;/code&gt; と &lt;code&gt;http://www.example.com&lt;/code&gt; に応答する。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;*.example.com&lt;/code&gt; と &lt;code&gt;.example.com&lt;/code&gt; の記述の意味は等しい。また、この記述の場合、サブドメインも全てハンドリングする。例えば、&lt;code&gt;www.example.com&lt;/code&gt;、&lt;code&gt;img.example.com&lt;/code&gt;、&lt;code&gt;search.example.com&lt;/code&gt; など。&lt;/li&gt;
  &lt;li&gt;5つ目の例の &lt;code&gt;example.*&lt;/code&gt; の記述は、&lt;code&gt;example&lt;/code&gt; で始まる全てのドメインへのリクエストをハンドルする。
例えば、&lt;code&gt;example.com&lt;/code&gt;、&lt;code&gt;example.net&lt;/code&gt;、&lt;code&gt;example.org&lt;/code&gt; など。&lt;code&gt;example.wao.com&lt;/code&gt;、&lt;code&gt;example.hello.com&lt;/code&gt; も同様。&lt;/li&gt;
  &lt;li&gt;6つ目の &lt;code&gt;example.com exmaple.net example.org&lt;/code&gt; は3つのドメイン全てへのリクエストをハンドルする。&lt;/li&gt;
  &lt;li&gt;Nginx は無効なドメイン名でもバーチャルホストとして定義できる。7つ目の例の &lt;code&gt;localhost example1 example2&lt;/code&gt; の場合、ホスト名となっているが、Nginx はリクエストの HTTP のヘッダのみを見てリクエストを処理するので、有効なドメイン名である必要はない。ただし、この場合は、hosts ファイルにホスト名が定義されている必要がある。&lt;/li&gt;
  &lt;li&gt;最後の &lt;code&gt;""&lt;/code&gt; の定義では、Nginx は全てのリクエストを処理することを意味する。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id="location-"&gt;リソース(ロケーション)の設定 - &lt;code&gt;location&lt;/code&gt; ディレクティブ&lt;/h4&gt;

&lt;p&gt;次に &lt;code&gt;location&lt;/code&gt; ディレクティブ。&lt;code&gt;location&lt;/code&gt; ディレクティブは、クライアントによってリクエストされたロケーションに対する振舞いを定義する。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;location&lt;/code&gt; ディレクティブは、そのブロックの前に適用するパターンを記載する。シンタックスは以下の通りとなっており、まずはこの動作概要を掴んでおくことが必要。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;location [=|~|~*|^~|@] pattern { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic#sph_server-configuration"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt; の例を利用させていただき、その動作を理解する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# パターングループ1
location / { }
location /images/ { }
location /blog/ { }
location /planet/ { }
location /planet/blog/ { }

# パターングループ2
location ~ IndexPage\.php$ { }
location ~ ^/BlogPlanet(/|/index\.php)$ { }

# パターングループ3
location ~* \.(pl|cgi|perl|prl)$ { }
location ~* \.(md|mdwn|txt|mkdn)$ { }

# パターングループ4
location ^~ /images/IndexPage/ { }
location ^~ /blog/BlogPlanet/ { }

# パターングループ5
location = / { }
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;最初の5つのサンプルはリテラル文字列マッチと言われるもの。ホスト名に続くリクエストの最初のパートにマッチする。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;server_name&lt;/code&gt; に &lt;code&gt;example.com&lt;/code&gt; が設定されており、&lt;code&gt;http://example.com/&lt;/code&gt; へのリクエストがあったとする。この時、”&lt;code&gt;location /&lt;/code&gt;” ディレクティブはこのリクエストにマッチする。Nginx は “most specific match” でリクエストの条件を満たす。&lt;code&gt;http://example.com/planet/blog/&lt;/code&gt; と &lt;code&gt;http://example.com/planet/blog/about&lt;/code&gt; へのリクエストは、”&lt;code&gt;location /planet/blog/&lt;/code&gt;” で満たされる。当然、”&lt;code&gt;location /planet/&lt;/code&gt;” でも満たされることになる。&lt;/li&gt;
  &lt;li&gt;2つ目のグループの &lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; (チルダ)に続くサンプルでは、Nginx は正規表現での適用を行う。これらの &lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; だけのマッチ表現は case-sensive (大文字小文字を区別する) になる。最初の例では、&lt;code&gt;IndexPage.php&lt;/code&gt; はマッチするが、&lt;code&gt;indexpage.php&lt;/code&gt; はマッチしない。また、&lt;code&gt;/BlogPlanet&lt;/code&gt;、&lt;code&gt;/blogplanet/&lt;/code&gt;、&lt;code&gt;/blogplanet/index.php&lt;/code&gt; もマッチしない。Nginx は Perl Compatible Regular Expressions (PCRE) を使用している。&lt;/li&gt;
  &lt;li&gt;3つ目のグループの &lt;strong&gt;&lt;code&gt;~*&lt;/code&gt;&lt;/strong&gt; の表現は、&lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt; の場合と同じく正規表現でのマッチで、case-insentive (大文字小文字を区別しない)になる。ここでの表現では、特定の拡張子で終わるファイル名に対してどう処理するのかを定義している。最初の例では、.pl、.PL、.cgi、.CGI、.perl、.Perl、.prl、.PrL、何れの拡張子のファイルにも適用される。&lt;/li&gt;
  &lt;li&gt;4つ目のグループの &lt;strong&gt;&lt;code&gt;^~&lt;/code&gt;&lt;/strong&gt; の表現は、最初のグループの&lt;strong&gt;リテラル文字列マッチのように動作する&lt;/strong&gt;。注意点として、&lt;strong&gt;このマッチ文が適用されると Nginx はパターンの検索を中止する&lt;/strong&gt;。”&lt;code&gt;^~ /images/IndexPage/&lt;/code&gt;“、”&lt;code&gt;^~ /blog/BlogPlanet/&lt;/code&gt;” パターンでの &lt;code&gt;location&lt;/code&gt; ディレクティブは、仮に他にマッチする &lt;code&gt;location&lt;/code&gt; ディレクティブが他にあったとしても、このパターンがマッチした時点で使用される。&lt;/li&gt;
  &lt;li&gt;最後の &lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt; の表現は、リクエストされたパスに完全一致した場合に適用され、&lt;strong&gt;マッチした時点で他のパターンの検索を中止する&lt;/strong&gt;。例えば、最後のサンプルは、&lt;code&gt;http://example.com/&lt;/code&gt; にはマッチするが、&lt;code&gt;http://example.com/index.html&lt;/code&gt; にはマッチしない。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ここまでの記述だけでは、&lt;code&gt;location&lt;/code&gt; ディレクティブの全体の適用順がイマイチ掴みきれない。&lt;code&gt;location&lt;/code&gt; ディレクティブのパターン適用ルールは以下の通りとなる。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;完全一致(&lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt;)が最初に処理される。マッチするものが見つかった場合、Nginx はそこでパターンの検索を中止し、リクエストを実行する。&lt;/li&gt;
  &lt;li&gt;次に残りのリテラル文字列ディレクティブが処理される。もし、&lt;strong&gt;&lt;code&gt;^~&lt;/code&gt;&lt;/strong&gt; が使用されていれば、Nginx はそこでパターンの検索を中止し、リクエストを実行する。それ以外の場合は、Nginx は &lt;code&gt;location&lt;/code&gt; ディレクティブを処理し続ける。&lt;/li&gt;
  &lt;li&gt;正規表現で定義された(&lt;strong&gt;&lt;code&gt;~&lt;/code&gt;&lt;/strong&gt;、&lt;strong&gt;&lt;code&gt;~*&lt;/code&gt;&lt;/strong&gt;)全ての &lt;code&gt;location&lt;/code&gt; ディレクティブが処理される。正規表現がマッチしたら、Nginx はそこでパターンの検索を中止し、リクエストを実行する。&lt;/li&gt;
  &lt;li&gt;正規表現がない、または、正規表現がマッチしなかったときは、最も適切なリテラル文字列のパターンが使用される。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;一旦 Nginx が特定のリクエストに対してリソースを提供する “&lt;code&gt;location&lt;/code&gt;” を選択したら、このリクエストに対するレスポンスは、”&lt;code&gt;location&lt;/code&gt;” ディレクティブのブロックによって定義される。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;location / {
    root   html;
    index  index.html index.htm;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ドキュメントルートは、&lt;code&gt;root&lt;/code&gt; ディレクティブによって、html ディレクトリに定義されている。上記は相対パスでの指定なので、実際のディレクトリは、&lt;code&gt;$NGINX_ROOT/html&lt;/code&gt; となる。&lt;code&gt;/blog/includes/style.css&lt;/code&gt; へのリクエストは、他の &lt;code&gt;location&lt;/code&gt; ディレクティブがマッチしていないと想定した場合、&lt;code&gt;$NGINX_ROOT/html/blog/includes/style.css&lt;/code&gt; にあるファイルがリソースの対象となる。&lt;code&gt;root&lt;/code&gt; ディレクティブには絶対パスを指定することもできる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index&lt;/code&gt; ディレクティブはリクエストがファイル名を含んでいない場合に、ファイルシステムのどのファイルが使用されるべきかを指定する。&lt;code&gt;http://example.com/&lt;/code&gt; へのリクエストは、&lt;code&gt;$NGINX_ROOT/http/index.html&lt;/code&gt; のファイルがリソースの対象となる。複数のファイル名指定されている場合、Nginx は順にそのリストを処理し、存在するファイルにリクエストを適用する。上記の例の場合、&lt;code&gt;index.html&lt;/code&gt; が存在しなければ、&lt;code&gt;index.htm&lt;/code&gt; が使用される。仮にどちらも存在しない場合には、404 メッセーが送出される。&lt;/p&gt;

&lt;h3 id="section-2"&gt;設定ファイルの管理&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;include&lt;/code&gt; ディレクティブを活用し、ベースとなる &lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; には必要最低限の記述のみを行い、各サーバ毎の固有の設定は別ファイルに切り出しておくとメンテナンス性があがる。&lt;/p&gt;

&lt;p&gt;例えば、以下のような書き方。&lt;code&gt;$NGINX_ROOT/conf/nginx.conf&lt;/code&gt; の内容は至ってシンプルになる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;user nginx;
worker_processes 4;
pid /var/run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最後の &lt;code&gt;include&lt;/code&gt; ディレクティブによって、個々のバーチャルホスト毎の設定は別ファイルに定義を行っている。&lt;/p&gt;

&lt;h3 id="section-3"&gt;参考情報&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://library.linode.com/web-servers/nginx/configuration/basic"&gt;Basic Nginx Configuration – Linode Library&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://wiki.nginx.org/Modules"&gt;Nginx Modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-08-14:/2011/08/14/koans/</id>
    <title type="html">マスターの導きを受けつつ、TDD で Ruby を学びながら悟りを開く - Koans</title>
    <published>2011-08-14T14:55:00Z</published>
    <updated>2011-08-14T14:55:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/08/14/koans/"/>
    <content type="html">&lt;h3 id="koans-"&gt;Koans とは&lt;/h3&gt;

&lt;p&gt;クイズ形式で Ruby を学ぶ Koans。その手法がなかなか凝っている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/koans-w500.png" alt="koans" /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://rubykoans.com/"&gt;Learn Ruby with the EdgeCase Ruby Koans&lt;/a&gt;&lt;br /&gt;
ここでは上記からダウンロードできる 2010/12/23 日版を利用した。
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="https://github.com/edgecase/ruby_koans"&gt;edgecase/ruby_koans - GitHub&lt;/a&gt;&lt;br /&gt;
GitHub でソースは管理されている。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;The goal is to learn the Ruby language, syntax, structure, and some common functions and libraries. We also teach you culture. Testing is not just something we pay lip service to, but something we live. It is essential in your quest to learn and do great things in the language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Koans は Ruby 言語の文法、構造、そして、幾つかの共通関数やライブラリを学ぶことをゴールとしたもので、TDD の手法を用いてそれを実現している。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; というファイルを起動することで、あるテストケースがカルマにダメージを与えたとのメッセージが表示され、マスターから助言を授かることになる。&lt;br /&gt;
表示されるメッセージを頼りにテストケースをパスするように修正していくことで、次の新たな設問(新たなカルマへのダメージ)へと進み、30ちょっとのカテゴリの計272問(2010/12/23版)の設問をクリアすることで悟りをひらけることになる。&lt;/p&gt;

&lt;p&gt;設問をクリアしていく過程は以下のようになる。&lt;br /&gt;
例えば2番目の設問は以下の通りとなっている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/koans2-w500.png" alt="koans2" /&gt;&lt;/p&gt;

&lt;p&gt;マスターが「君はまだ悟りをひらいていない」と言っている。”The answers you seek…” ということで “This shoud be true – Please fix this” とある。&lt;br /&gt;
「please meditate on the following code:」ということで、&lt;code&gt;about_asserts.rb:16:in &lt;/code&gt;test_assert_with_message’` が指定されているので、該当ファイルの該当行を確認すると、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;  # Enlightenment may be more easily achieved with appropriate
  # messages.
  def test_assert_with_message
    assert false, "This should be true -- Please fix this"  # line: 16
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;assert&lt;/code&gt; が false となっている。当然これではテストは通らないので、true に書き変えて保存する。&lt;/p&gt;

&lt;p&gt;再度 &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動してあげると、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ ruby path_to_enlightenment.rb 
AboutAsserts#test_assert_truth has expanded your awareness.
AboutAsserts#test_assert_with_message has expanded your awareness.
AboutAsserts#test_assert_equality has damaged your karma.

The Master says:
  You have not yet reached enlightenment.
  You are progressing. Excellent. 2 completed.

The answers you seek...
  Failed assertion, no message given.

Please meditate on the following code:
  /home/hoge/Dropbox/work/koans/about_asserts.rb:25:in `test_assert_equality'

learn the rules so you know how to break them properly
your path thus far [.X________________________________________________] 2/274
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;次の設問へと続く。&lt;/p&gt;

&lt;p&gt;基本は、テストケースのアサーションの期待値を埋めていくことで設問に答えていくことになる。&lt;/p&gt;

&lt;p&gt;メッセージ(“The ansers you seek…“)に既に答えが出てしまってはいるが、そこはじっくり読まずに、テストケースとテストメソッド名の方に集中して何を学ばせようとしているのか頭の片隅に置きながら期待値を考えていると、よく考えられた設問になっているなぁと感心してしまう。&lt;/p&gt;

&lt;p&gt;最初の方こそ上記のようなホントに初歩的な設問だが、徐々に内容が濃くなってくるので、なかなか良い復習、勉強になる。&lt;/p&gt;

&lt;p&gt;また、一気に 274 問実施するのは流石にキツイので、できる時間に少しづつ実施することが可能な作りになっているのもうれしい。何問目まで回答できているかは &lt;code&gt;.path_progress&lt;/code&gt; というファイルが覚えておいてくれているので、特に意識することなく、&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動すれば前回の設問から続きを行うことができる。&lt;/p&gt;

&lt;h3 id="watchr-"&gt;watchr を使って回答に集中&lt;/h3&gt;

&lt;p&gt;設問に答えては &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動するというのはメンドイ。&lt;br /&gt;
自動化しておく。&lt;/p&gt;

&lt;p&gt;watchr gem を使うとファイルを監視下におき、編集された際に実行させたいことを定義することができる。
回答を記述するファイルを編集するたびに自動的に &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; が実行されるようにしておく。&lt;/p&gt;

&lt;p&gt;watchr をインストールしていない場合はインストールしておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ sudo gem install watchr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; と同じディレクトリに以下のファイルを用意しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;koans.watchr&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;def run
  system("clear; ruby path_to_enlightenment.rb")
end

watch('.*\.rb$') { run }
run
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;watchr を起動しておく。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ watchr koans.watchr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これで回答を行うファイルを編集する度にコンソールがリフレッシュされ &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; の結果を確認することができる。&lt;/p&gt;

&lt;h3 id="trianglerb"&gt;&lt;code&gt;triangle.rb&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;大半は assertion の期待値を埋めていくのだが、テストケースを通す為の関数を書く設問もある。&lt;/p&gt;

&lt;p&gt;以下の2問。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;設問その1：&lt;strong&gt;&lt;code&gt;about_triangle_project.rb&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class AboutTriangleProject &amp;lt; EdgeCase::Koan
  def test_equilateral_triangles_have_equal_sides
    assert_equal :equilateral, triangle(2, 2, 2)
    assert_equal :equilateral, triangle(10, 10, 10)
  end

  def test_isosceles_triangles_have_exactly_two_sides_equal
    assert_equal :isosceles, triangle(3, 4, 4)
    assert_equal :isosceles, triangle(4, 3, 4)
    assert_equal :isosceles, triangle(4, 4, 3)
    assert_equal :isosceles, triangle(10, 10, 2)
  end

  def test_scalene_triangles_have_no_equal_sides
    assert_equal :scalene, triangle(3, 4, 5)
    assert_equal :scalene, triangle(10, 11, 12)
    assert_equal :scalene, triangle(5, 4, 2)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;設問その2：&lt;strong&gt;&lt;code&gt;about_triangle_project_2.rb&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class AboutTriangleProject2 &amp;lt; EdgeCase::Koan
  # The first assignment did not talk about how to handle errors.
  # Let's handle that part now.
  def test_illegal_triangles_throw_exceptions
    assert_raise(TriangleError) do triangle(0, 0, 0) end
    assert_raise(TriangleError) do triangle(3, 4, -5) end
    assert_raise(TriangleError) do triangle(1, 1, 3) end
    assert_raise(TriangleError) do triangle(2, 4, 2) end
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設問その1のテストの要件を満たす関数を用意し、かつ、設問その2の制約もパスする必要がある。&lt;/p&gt;

&lt;p&gt;答えは提供されていない(見つけられなかった。。)ので、ベストアンサーかどうかはわからないが、以下の関数を書くことでテストをパスしている。&lt;br /&gt;
ツッコミありましたらご指摘願いたい。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;triangle.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;def triangle(a, b, c)
  raise TriangleError.new if [a, b, c].any? { |e| e &amp;lt;= 0 }
  raise TriangleError.new if ((a + b) &amp;lt;= c) || ((a + c) &amp;lt;= b) || ((b + c ) &amp;lt;= a)

  case [a, b, c].uniq.size
    when 1 then :equilateral
    when 2 then :isosceles
    else :scalene
  end
end
&lt;/code&gt;&lt;/pre&gt;
</content>
    <summary type="html">&lt;h3 id="koans-"&gt;Koans とは&lt;/h3&gt;

&lt;p&gt;クイズ形式で Ruby を学ぶ Koans。その手法がなかなか凝っている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/koans-w500.png" alt="koans" /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://rubykoans.com/"&gt;Learn Ruby with the EdgeCase Ruby Koans&lt;/a&gt;&lt;br /&gt;
ここでは上記からダウンロードできる 2010/12/23 日版を利用した。
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="https://github.com/edgecase/ruby_koans"&gt;edgecase/ruby_koans - GitHub&lt;/a&gt;&lt;br /&gt;
GitHub でソースは管理されている。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;The goal is to learn the Ruby language, syntax, structure, and some common functions and libraries. We also teach you culture. Testing is not just something we pay lip service to, but something we live. It is essential in your quest to learn and do great things in the language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Koans は Ruby 言語の文法、構造、そして、幾つかの共通関数やライブラリを学ぶことをゴールとしたもので、TDD の手法を用いてそれを実現している。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; というファイルを起動することで、あるテストケースがカルマにダメージを与えたとのメッセージが表示され、マスターから助言を授かることになる。&lt;br /&gt;
表示されるメッセージを頼りにテストケースをパスするように修正していくことで、次の新たな設問(新たなカルマへのダメージ)へと進み、30ちょっとのカテゴリの計272問(2010/12/23版)の設問をクリアすることで悟りをひらけることになる。&lt;/p&gt;

&lt;p&gt;設問をクリアしていく過程は以下のようになる。&lt;br /&gt;
例えば2番目の設問は以下の通りとなっている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/koans2-w500.png" alt="koans2" /&gt;&lt;/p&gt;

&lt;p&gt;マスターが「君はまだ悟りをひらいていない」と言っている。”The answers you seek…” ということで “This shoud be true – Please fix this” とある。&lt;br /&gt;
「please meditate on the following code:」ということで、&lt;code&gt;about_asserts.rb:16:in &lt;/code&gt;test_assert_with_message’` が指定されているので、該当ファイルの該当行を確認すると、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;  # Enlightenment may be more easily achieved with appropriate
  # messages.
  def test_assert_with_message
    assert false, "This should be true -- Please fix this"  # line: 16
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;assert&lt;/code&gt; が false となっている。当然これではテストは通らないので、true に書き変えて保存する。&lt;/p&gt;

&lt;p&gt;再度 &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動してあげると、&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ ruby path_to_enlightenment.rb 
AboutAsserts#test_assert_truth has expanded your awareness.
AboutAsserts#test_assert_with_message has expanded your awareness.
AboutAsserts#test_assert_equality has damaged your karma.

The Master says:
  You have not yet reached enlightenment.
  You are progressing. Excellent. 2 completed.

The answers you seek...
  Failed assertion, no message given.

Please meditate on the following code:
  /home/hoge/Dropbox/work/koans/about_asserts.rb:25:in `test_assert_equality'

learn the rules so you know how to break them properly
your path thus far [.X________________________________________________] 2/274
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;次の設問へと続く。&lt;/p&gt;

&lt;p&gt;基本は、テストケースのアサーションの期待値を埋めていくことで設問に答えていくことになる。&lt;/p&gt;

&lt;p&gt;メッセージ(“The ansers you seek…“)に既に答えが出てしまってはいるが、そこはじっくり読まずに、テストケースとテストメソッド名の方に集中して何を学ばせようとしているのか頭の片隅に置きながら期待値を考えていると、よく考えられた設問になっているなぁと感心してしまう。&lt;/p&gt;

&lt;p&gt;最初の方こそ上記のようなホントに初歩的な設問だが、徐々に内容が濃くなってくるので、なかなか良い復習、勉強になる。&lt;/p&gt;

&lt;p&gt;また、一気に 274 問実施するのは流石にキツイので、できる時間に少しづつ実施することが可能な作りになっているのもうれしい。何問目まで回答できているかは &lt;code&gt;.path_progress&lt;/code&gt; というファイルが覚えておいてくれているので、特に意識することなく、&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動すれば前回の設問から続きを行うことができる。&lt;/p&gt;

&lt;h3 id="watchr-"&gt;watchr を使って回答に集中&lt;/h3&gt;

&lt;p&gt;設問に答えては &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; を起動するというのはメンドイ。&lt;br /&gt;
自動化しておく。&lt;/p&gt;

&lt;p&gt;watchr gem を使うとファイルを監視下におき、編集された際に実行させたいことを定義することができる。
回答を記述するファイルを編集するたびに自動的に &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; が実行されるようにしておく。&lt;/p&gt;

&lt;p&gt;watchr をインストールしていない場合はインストールしておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ sudo gem install watchr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; と同じディレクトリに以下のファイルを用意しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;koans.watchr&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;def run
  system("clear; ruby path_to_enlightenment.rb")
end

watch('.*\.rb$') { run }
run
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;watchr を起動しておく。&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;$ watchr koans.watchr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;これで回答を行うファイルを編集する度にコンソールがリフレッシュされ &lt;code&gt;path_to_enlightenment.rb&lt;/code&gt; の結果を確認することができる。&lt;/p&gt;

&lt;h3 id="trianglerb"&gt;&lt;code&gt;triangle.rb&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;大半は assertion の期待値を埋めていくのだが、テストケースを通す為の関数を書く設問もある。&lt;/p&gt;

&lt;p&gt;以下の2問。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;設問その1：&lt;strong&gt;&lt;code&gt;about_triangle_project.rb&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class AboutTriangleProject &amp;lt; EdgeCase::Koan
  def test_equilateral_triangles_have_equal_sides
    assert_equal :equilateral, triangle(2, 2, 2)
    assert_equal :equilateral, triangle(10, 10, 10)
  end

  def test_isosceles_triangles_have_exactly_two_sides_equal
    assert_equal :isosceles, triangle(3, 4, 4)
    assert_equal :isosceles, triangle(4, 3, 4)
    assert_equal :isosceles, triangle(4, 4, 3)
    assert_equal :isosceles, triangle(10, 10, 2)
  end

  def test_scalene_triangles_have_no_equal_sides
    assert_equal :scalene, triangle(3, 4, 5)
    assert_equal :scalene, triangle(10, 11, 12)
    assert_equal :scalene, triangle(5, 4, 2)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;設問その2：&lt;strong&gt;&lt;code&gt;about_triangle_project_2.rb&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class AboutTriangleProject2 &amp;lt; EdgeCase::Koan
  # The first assignment did not talk about how to handle errors.
  # Let's handle that part now.
  def test_illegal_triangles_throw_exceptions
    assert_raise(TriangleError) do triangle(0, 0, 0) end
    assert_raise(TriangleError) do triangle(3, 4, -5) end
    assert_raise(TriangleError) do triangle(1, 1, 3) end
    assert_raise(TriangleError) do triangle(2, 4, 2) end
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設問その1のテストの要件を満たす関数を用意し、かつ、設問その2の制約もパスする必要がある。&lt;/p&gt;

&lt;p&gt;答えは提供されていない(見つけられなかった。。)ので、ベストアンサーかどうかはわからないが、以下の関数を書くことでテストをパスしている。&lt;br /&gt;
ツッコミありましたらご指摘願いたい。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;triangle.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;def triangle(a, b, c)
  raise TriangleError.new if [a, b, c].any? { |e| e &amp;lt;= 0 }
  raise TriangleError.new if ((a + b) &amp;lt;= c) || ((a + c) &amp;lt;= b) || ((b + c ) &amp;lt;= a)

  case [a, b, c].uniq.size
    when 1 then :equilateral
    when 2 then :isosceles
    else :scalene
  end
end
&lt;/code&gt;&lt;/pre&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-07-30:/2011/07/30/unicorn/</id>
    <title type="html">Rack アプリケーション向けの HTTP サーバ Unicorn の基本操作</title>
    <published>2011-07-30T14:55:00Z</published>
    <updated>2011-07-30T14:55:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/07/30/unicorn/"/>
    <content type="html">&lt;h3 id="unicorn-"&gt;Unicorn とは？&lt;/h3&gt;

&lt;p&gt;Rails、Rack アプリケーションを動作させるコンテナとしては、&lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt;、&lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt;、Mongrel などの選択肢がある。
それ以外にも Unicorn という Rack アプリケーション向けの HTTP サーバがあり、今回試しに使ってみたのでそのメモ。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org"&gt;Unicorn: Rack HTTP server for fast clients and Unix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;設計方針に特徴的な部分があり、以下の記事に詳しい。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/blog/517-unicorn"&gt;Unicorn! - GitHub&lt;/a&gt;&lt;br /&gt;
Unicorn を使用している github の記事&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://d.hatena.ne.jp/tkng/20100707/1278517873"&gt;UnicornでSinatraアプリをデプロイしてみた - 射撃しつつ前転&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;github の記事の結論で書かれているが、&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Passenger is awesome. Mongrel is awesome. Thin is awesome.&lt;/p&gt;

  &lt;p&gt;Use what works best for you. Decide what you need and evaluate the available options based on those needs. Don’t pick a tool because GitHub uses it, pick a tool because it solves the problems you have.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;それぞれの HTTP サーバが良い点を持っており、自身のサービスの用途、目的に応じて適切なものを使用するのがよいでしょうと。&lt;/p&gt;

&lt;p&gt;サーバの良し悪しを測る項目の1項目として ab を使ったベンチなどがよくとられている。
確かにスループットにある程度のレベルのものは要求したいが、それよりも運用に入った際の安定性、信頼性、何か問題が起きた際のリカバリ含めた可用性の部分を気にしていた。&lt;/p&gt;

&lt;p&gt;今回 Unicorn を試してみようと思ったのは、そこにあり、先の記事にも、以下の記載があり、Unicorn を試してみることにした。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Honestly, I don’t care. I want a production environment that can gracefully handle chaos more than I want something that’s screaming fast. I want stability and reliability over raw speed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ここで記載するのは Unicorn を動作させるまでの基本的な設定と Unicorn を操作する基本的なオペレーションのメモになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unicorn のインストールと事前準備&lt;/li&gt;
  &lt;li&gt;Unicorn の設定ファイルを用意する&lt;/li&gt;
  &lt;li&gt;Unicorn サーバを起動する&lt;/li&gt;
  &lt;li&gt;nginx と Unicorn を連携する&lt;/li&gt;
  &lt;li&gt;Unicorn を停止する&lt;/li&gt;
  &lt;li&gt;Unicorn の設定の再読込&lt;/li&gt;
  &lt;li&gt;サービスの提供を止めずにプログラムの再読込&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="unicorn--1"&gt;Unicorn のインストールと事前準備&lt;/h3&gt;

&lt;p&gt;今回のお試し環境は以下の通りとなる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;アプリには簡単な Sinatra Hello World アプリを使用&lt;/li&gt;
  &lt;li&gt;Unicorn サーバのフロントは nginx をリバースプロキシとしてたてる&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unicorn 以外に nginx と Sinatra gem がインストールされている必要がある。&lt;/p&gt;

&lt;p&gt;Unicorn は RubyGems で提供されているので gem コマンドを使用してインストールする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# gem install unicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;動作環境のサンプルとして Sinatra アプリケーションを用意する。&lt;br /&gt;
(Sinatra がインストールされていない場合には、&lt;code&gt;# gem install sinatra&lt;/code&gt; が必要。)&lt;/p&gt;

&lt;p&gt;適当なディレクトリ(&lt;strong&gt;&lt;code&gt;$APP_DIR&lt;/code&gt;&lt;/strong&gt;)に Rack アプリケーションのエントリポイントとなるファイル &lt;code&gt;config.ru&lt;/code&gt; を用意し、簡単な HelloWorld アプリケーションを記述しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$APP_DIR/config.ru&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;require 'rubygems'
require 'sinatra/base'

class HelloApp &amp;lt; Sinatra::Base
  get '/hello' do
    'Hello World'
  end
end

run HelloApp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rack の rackup コマンドを使用して、上記のアプリがきちんと動作することを確認しておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ cd $APP_DIR
$ rackup
[2011-07-30 21:15:38] INFO  WEBrick 1.3.1
[2011-07-30 21:15:38] INFO  ruby 1.9.2 (2011-02-18) [i686-linux]
[2011-07-30 21:15:38] INFO  WEBrick::HTTPServer#start: pid=6260 port=9292
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ブラウザから、&lt;code&gt;http://localhost:9292/hello&lt;/code&gt; の URI で “Hello World” が表示されることを確認しておく。&lt;/p&gt;

&lt;h3 id="unicorn--2"&gt;Unicorn の設定ファイルを用意する&lt;/h3&gt;

&lt;p&gt;Unicorn は unicorn コマンドを使って起動するが、起動時に設定ファイルを指定して起動することができる。&lt;br /&gt;
設定例は、&lt;a href="http://unicorn.bogomips.org/Unicorn/Configurator.html"&gt;Class: Unicorn::Configurator&lt;/a&gt; からリンクのある以下のページで確認できる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org/examples/unicorn.conf.rb"&gt;Sample verbose configuration file for Unicorn&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb"&gt;Minimal sample configuration file for Unicorn (必要最小限の設定例)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記の最低限の設定を設定を流用し、以下の設定ファイルを用意する。&lt;br /&gt;
Unicorn は TCP/IP ソケットでも待機できるが、以下の設定では Unix ドメインソケットを使った設定のみとしている。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$APP_DIR/unicorn.conf&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;worker_processes 2

listen '/tmp/unicorn.sock'

stderr_path File.expand_path('unicorn.log', File.dirname(__FILE__))
stdout_path File.expand_path('unicorn.log', File.dirname(__FILE__))

preload_app true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ログファイルの記載部分を見てもらえるとわかるが、Unicorn の設定ファイルには Ruby の構文が利用可能となっている。&lt;/p&gt;

&lt;h3 id="unicorn--3"&gt;Unicorn サーバを起動する&lt;/h3&gt;

&lt;p&gt;Unicorn サーバを起動する。&lt;br /&gt;
unicorn コマンドを利用して起動することになる。&lt;code&gt;$APP_DIR&lt;/code&gt; に移動して、以下のコマンドで起動する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ unicorn -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;先ほど作成した Unicorn の設定ファイルを &lt;code&gt;-c&lt;/code&gt; オプションで指定し、&lt;code&gt;-D&lt;/code&gt; オプションでデーモン起動を行っている。&lt;/p&gt;

&lt;p&gt;unicorn はデフォルトで &lt;code&gt;config.ru&lt;/code&gt; をアプリケーションのエントリポイントとして認識するので、起動時のディレクトリに存在する Sinatra で書かれた Rack アプリケーションである &lt;code&gt;$APP_DIR/config.ru&lt;/code&gt; が上記のコマンドで読み込まれている。&lt;/p&gt;

&lt;p&gt;ログファイルを確認してみる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ cat unicorn.log
I, [2011-07-30T21:50:47.966116 #6632]  INFO -- : unlinking existing socket=/tmp/unicorn.sock
I, [2011-07-30T21:50:47.966669 #6632]  INFO -- : listening on addr=/tmp/unicorn.sock fd=3
I, [2011-07-30T21:50:47.967666 #6632]  INFO -- : Refreshing Gem list
I, [2011-07-30T21:50:48.343228 #6632]  INFO -- : worker=0 spawning...
I, [2011-07-30T21:50:48.343795 #6632]  INFO -- : worker=1 spawning...
I, [2011-07-30T21:50:48.344260 #6632]  INFO -- : master process ready
I, [2011-07-30T21:50:48.344266 #6635]  INFO -- : worker=0 spawned pid=6635
I, [2011-07-30T21:50:48.344450 #6635]  INFO -- : worker=0 ready
I, [2011-07-30T21:50:48.344672 #6638]  INFO -- : worker=1 spawned pid=6638
I, [2011-07-30T21:50:48.344863 #6638]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;エラーが表示されておらず、上記のようなログが出力されていれば問題なく起動が行えている。
master プロセスが1つ上がり、worker プロセス2つを起動している。&lt;/p&gt;

&lt;h3 id="nginx--unicorn-"&gt;nginx と Unicorn を連携する&lt;/h3&gt;

&lt;p&gt;フロントでリクエストを処理する nginx の設定。&lt;/p&gt;

&lt;p&gt;最低限の設定というところで、以下の設定を記述する。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;upstream&lt;/code&gt; ディレクティブ(ロードバランシングの指定)で &lt;code&gt;unicornapp&lt;/code&gt; というバックエンドサーバを定義し、Unicorn サーバの Unix ドメインソケットを指定しておく。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;location&lt;/code&gt; ディレクティブで &lt;code&gt;upstream&lt;/code&gt; に指定した &lt;code&gt;unicornapp&lt;/code&gt; バックエンドサーバを指定する&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;upstream unicornapp {
  server unix:/tmp/unicorn.sock;
}

server {
        listen   80;
        server_name localhost;

        location / {
               proxy_pass http://unicornapp;
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;nginx 設定ファイルの再読込を行い、ブラウザで &lt;code&gt;http://localhost/hello&lt;/code&gt; の URI を参照すると先ほどの rackup コマンドを使用して確認した “Hello World” と同じメッセージの画面が表示されていることが確認できる。&lt;br /&gt;
(ここで確認している画面は Unicorn で提供されているサービス)&lt;/p&gt;

&lt;p&gt;unicorn のログにもリクエストを処理したメッセージが確認できる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ tail -f unicorn.log
...
I, [2011-07-30T22:13:27.755913 #7306]  INFO -- : worker=1 ready
I, [2011-07-30T22:13:27.756925 #7303]  INFO -- : worker=0 spawned pid=7303
I, [2011-07-30T22:13:27.757150 #7303]  INFO -- : worker=0 ready
127.0.0.1 - - [30/Jul/2011 22:13:39] "GET /hello HTTP/1.0" 200 11 0.0155
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で基本的な設定はおしまい。&lt;/p&gt;

&lt;h3 id="unicorn--4"&gt;Unicorn を停止する&lt;/h3&gt;

&lt;p&gt;Unicorn に対する操作は基本 Unicorn の master プロセスに対してのシグナルでの操作となる。&lt;/p&gt;

&lt;p&gt;まずは停止方法。2つの停止方法がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;プロセスを即座に終了する: &lt;strong&gt;INT/TERM&lt;/strong&gt; シグナルを使用&lt;/li&gt;
  &lt;li&gt;処理を行っているリクエストが完了するのを待ってプロセスを終了する: &lt;strong&gt;QUIT&lt;/strong&gt; シグナルを使用&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7299     1  0 22:13 ?        00:00:04 unicorn master -c unicorn.conf -D
hoge      7303  7299  0 22:13 ?        00:00:03 unicorn worker[0] -c unicorn.conf -D
hoge      7306  7299  0 22:13 ?        00:00:03 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記でわかるように、master プロセスは 7299 のプロセスIDで動作している。master プロセスに対してシグナルを送る。&lt;/p&gt;

&lt;p&gt;Unicorn を gracefully に終了させる場合、&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -QUIT 7299
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;unicorn.log&lt;/code&gt; を確認。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:32:13.866125 #7299]  INFO -- : reaped #&amp;lt;Process::Status: pid 7303 exit 0&amp;gt; worker=0
I, [2011-07-30T23:32:13.866403 #7299]  INFO -- : reaped #&amp;lt;Process::Status: pid 7306 exit 0&amp;gt; worker=1
I, [2011-07-30T23:32:13.866683 #7299]  INFO -- : master complete
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2つの worker プロセスと master プロセスが終了したことがわかる。&lt;/p&gt;

&lt;h3 id="unicorn--5"&gt;Unicorn の設定の再読込&lt;/h3&gt;

&lt;p&gt;Unicorn の設定を再読込させる場合は、master プロセスに &lt;strong&gt;HUP&lt;/strong&gt; シグナルを送る。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -HUP &lt;master のプロセスid=""&gt;


ログを確認してみると、再読みされていることが確認できる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:35:42.261177 #7768]  INFO -- : reloading config_file=unicorn.conf
I, [2011-07-30T23:35:42.272338 #7768]  INFO -- : Refreshing Gem list
I, [2011-07-30T23:35:42.557187 #7768]  INFO -- : done reloading config_file=unicorn.conf
I, [2011-07-30T23:35:42.557362 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7773 exit 0&amp;gt; worker=0
I, [2011-07-30T23:35:42.557432 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7776 exit 0&amp;gt; worker=1
I, [2011-07-30T23:35:42.557545 #7768]  INFO -- : worker=0 spawning...
I, [2011-07-30T23:35:42.558136 #7768]  INFO -- : worker=1 spawning...
I, [2011-07-30T23:35:42.558726 #7782]  INFO -- : worker=0 spawned pid=7782
I, [2011-07-30T23:35:42.558966 #7782]  INFO -- : worker=0 ready
I, [2011-07-30T23:35:42.559173 #7785]  INFO -- : worker=1 spawned pid=7785
I, [2011-07-30T23:35:42.559430 #7785]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

### サービスの提供を止めずにプログラムの再読込 ###

プログラム(ここで言う Sinatra Hello World アプリ)を再配置するときなど、再度プログラムをロードし直す必要がある。  
Unicorn サーバを停止して、再起動でもよいが、サービスの提供を止めずに実施する場合の実施方法は以下の方法となる。

現在のプロセスの状況は以下の通り。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:00 unicorn master -c unicorn.conf -D
hoge      7782  7768  0 23:35 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7785  7768  0 23:35 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

ここで何らかのアプリの改修があり、プログラムを再配置したとする。

Unicorn では、既存のプロセスをそのまま残し、新たな Unicorn サーバのセットをもう一セット作成し、リクエストの処理もそちらに引き継いであげることができる。

まず 現在の master プロセスに USR2 シグナルを送る。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -USR2 7768
&lt;/code&gt;&lt;/pre&gt;

Unicorn のプロセスを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:01 unicorn master (old) -c unicorn.conf -D
hoge      7782  7768  0 23:35 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7785  7768  0 23:35 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
hoge      7822  7768  1 23:43 ?        00:00:00 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

元々あったプロセス(master pid: 7768)に old という表示が入っており、Unicorn サーバのセットがもうワンセット追加されていることがわかる。

新たに生成されたプロセスには、プログラムの更新が反映されている。

この時の Unicorn の動作をログで確認してみると以下の動作になっている。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:43:20.117449 #7822]  INFO -- : executing ["/home/hoge/.rvm/gems/ruby-1.9.2-p180/bin/unicorn", "-c", "unicorn.conf", "-D"] (in /home/hoge/Dropbox/work/unicorn-app-sample)
I, [2011-07-30T23:43:20.117641 #7822]  INFO -- : forked child re-executing...
I, [2011-07-30T23:43:20.798555 #7822]  INFO -- : inherited addr=/tmp/unicorn.sock fd=3
I, [2011-07-30T23:43:20.798829 #7822]  INFO -- : Refreshing Gem list
I, [2011-07-30T23:43:21.165052 #7822]  INFO -- : worker=0 spawning...
I, [2011-07-30T23:43:21.165798 #7822]  INFO -- : worker=1 spawning...
I, [2011-07-30T23:43:21.166209 #7826]  INFO -- : worker=0 spawned pid=7826
I, [2011-07-30T23:43:21.166311 #7822]  INFO -- : master process ready
I, [2011-07-30T23:43:21.166401 #7826]  INFO -- : worker=0 ready
I, [2011-07-30T23:43:21.166635 #7829]  INFO -- : worker=1 spawned pid=7829
I, [2011-07-30T23:43:21.166768 #7829]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

新しいプロセスにリクエストの受付処理は引き継がれているので、古い方のプロセスを落としていく。

まずは、古い方の master プロセスに WINCH シグナルを送り、その worker プロセスを落としてあげる。
WINCH シグナルはその master プロセスの worker プロセスを gracefully に止めてあげる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -WINCH 7768
&lt;/code&gt;&lt;/pre&gt;

プロセスとログを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:01 unicorn master (old) -c unicorn.conf -D
hoge      7822  7768  0 23:43 ?        00:00:01 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:48:45.648299 #7768]  INFO -- : gracefully stopping all workers
I, [2011-07-30T23:48:45.678491 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7782 exit 0&amp;gt; worker=0
I, [2011-07-30T23:48:45.678664 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7785 exit 0&amp;gt; worker=1
&lt;/code&gt;&lt;/pre&gt;

確かに、古い方の Unicorn のプロセスは、master プロセスだけが残り、worker は全て終了している。

一旦ここで念のため、アプリがキチンと動作しているか確認しておく。  
問題無いようであれば、古い master プロセスも止めてあげる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -QUIT 7768
&lt;/code&gt;&lt;/pre&gt;

プロセスとログを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7822     1  0 23:43 ?        00:00:01 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:51:35.694051 #7768]  INFO -- : master complete
&lt;/code&gt;&lt;/pre&gt;

これで、新しいプログラムで Unicorn サーバが動作している状態となる。
&lt;/master&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
    <summary type="html">&lt;h3 id="unicorn-"&gt;Unicorn とは？&lt;/h3&gt;

&lt;p&gt;Rails、Rack アプリケーションを動作させるコンテナとしては、&lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt;、&lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt;、Mongrel などの選択肢がある。
それ以外にも Unicorn という Rack アプリケーション向けの HTTP サーバがあり、今回試しに使ってみたのでそのメモ。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org"&gt;Unicorn: Rack HTTP server for fast clients and Unix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;設計方針に特徴的な部分があり、以下の記事に詳しい。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/blog/517-unicorn"&gt;Unicorn! - GitHub&lt;/a&gt;&lt;br /&gt;
Unicorn を使用している github の記事&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://d.hatena.ne.jp/tkng/20100707/1278517873"&gt;UnicornでSinatraアプリをデプロイしてみた - 射撃しつつ前転&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;github の記事の結論で書かれているが、&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Passenger is awesome. Mongrel is awesome. Thin is awesome.&lt;/p&gt;

  &lt;p&gt;Use what works best for you. Decide what you need and evaluate the available options based on those needs. Don’t pick a tool because GitHub uses it, pick a tool because it solves the problems you have.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;それぞれの HTTP サーバが良い点を持っており、自身のサービスの用途、目的に応じて適切なものを使用するのがよいでしょうと。&lt;/p&gt;

&lt;p&gt;サーバの良し悪しを測る項目の1項目として ab を使ったベンチなどがよくとられている。
確かにスループットにある程度のレベルのものは要求したいが、それよりも運用に入った際の安定性、信頼性、何か問題が起きた際のリカバリ含めた可用性の部分を気にしていた。&lt;/p&gt;

&lt;p&gt;今回 Unicorn を試してみようと思ったのは、そこにあり、先の記事にも、以下の記載があり、Unicorn を試してみることにした。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Honestly, I don’t care. I want a production environment that can gracefully handle chaos more than I want something that’s screaming fast. I want stability and reliability over raw speed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ここで記載するのは Unicorn を動作させるまでの基本的な設定と Unicorn を操作する基本的なオペレーションのメモになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unicorn のインストールと事前準備&lt;/li&gt;
  &lt;li&gt;Unicorn の設定ファイルを用意する&lt;/li&gt;
  &lt;li&gt;Unicorn サーバを起動する&lt;/li&gt;
  &lt;li&gt;nginx と Unicorn を連携する&lt;/li&gt;
  &lt;li&gt;Unicorn を停止する&lt;/li&gt;
  &lt;li&gt;Unicorn の設定の再読込&lt;/li&gt;
  &lt;li&gt;サービスの提供を止めずにプログラムの再読込&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="unicorn--1"&gt;Unicorn のインストールと事前準備&lt;/h3&gt;

&lt;p&gt;今回のお試し環境は以下の通りとなる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;アプリには簡単な Sinatra Hello World アプリを使用&lt;/li&gt;
  &lt;li&gt;Unicorn サーバのフロントは nginx をリバースプロキシとしてたてる&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unicorn 以外に nginx と Sinatra gem がインストールされている必要がある。&lt;/p&gt;

&lt;p&gt;Unicorn は RubyGems で提供されているので gem コマンドを使用してインストールする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# gem install unicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;動作環境のサンプルとして Sinatra アプリケーションを用意する。&lt;br /&gt;
(Sinatra がインストールされていない場合には、&lt;code&gt;# gem install sinatra&lt;/code&gt; が必要。)&lt;/p&gt;

&lt;p&gt;適当なディレクトリ(&lt;strong&gt;&lt;code&gt;$APP_DIR&lt;/code&gt;&lt;/strong&gt;)に Rack アプリケーションのエントリポイントとなるファイル &lt;code&gt;config.ru&lt;/code&gt; を用意し、簡単な HelloWorld アプリケーションを記述しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$APP_DIR/config.ru&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;require 'rubygems'
require 'sinatra/base'

class HelloApp &amp;lt; Sinatra::Base
  get '/hello' do
    'Hello World'
  end
end

run HelloApp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rack の rackup コマンドを使用して、上記のアプリがきちんと動作することを確認しておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ cd $APP_DIR
$ rackup
[2011-07-30 21:15:38] INFO  WEBrick 1.3.1
[2011-07-30 21:15:38] INFO  ruby 1.9.2 (2011-02-18) [i686-linux]
[2011-07-30 21:15:38] INFO  WEBrick::HTTPServer#start: pid=6260 port=9292
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ブラウザから、&lt;code&gt;http://localhost:9292/hello&lt;/code&gt; の URI で “Hello World” が表示されることを確認しておく。&lt;/p&gt;

&lt;h3 id="unicorn--2"&gt;Unicorn の設定ファイルを用意する&lt;/h3&gt;

&lt;p&gt;Unicorn は unicorn コマンドを使って起動するが、起動時に設定ファイルを指定して起動することができる。&lt;br /&gt;
設定例は、&lt;a href="http://unicorn.bogomips.org/Unicorn/Configurator.html"&gt;Class: Unicorn::Configurator&lt;/a&gt; からリンクのある以下のページで確認できる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org/examples/unicorn.conf.rb"&gt;Sample verbose configuration file for Unicorn&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb"&gt;Minimal sample configuration file for Unicorn (必要最小限の設定例)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記の最低限の設定を設定を流用し、以下の設定ファイルを用意する。&lt;br /&gt;
Unicorn は TCP/IP ソケットでも待機できるが、以下の設定では Unix ドメインソケットを使った設定のみとしている。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;$APP_DIR/unicorn.conf&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;worker_processes 2

listen '/tmp/unicorn.sock'

stderr_path File.expand_path('unicorn.log', File.dirname(__FILE__))
stdout_path File.expand_path('unicorn.log', File.dirname(__FILE__))

preload_app true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ログファイルの記載部分を見てもらえるとわかるが、Unicorn の設定ファイルには Ruby の構文が利用可能となっている。&lt;/p&gt;

&lt;h3 id="unicorn--3"&gt;Unicorn サーバを起動する&lt;/h3&gt;

&lt;p&gt;Unicorn サーバを起動する。&lt;br /&gt;
unicorn コマンドを利用して起動することになる。&lt;code&gt;$APP_DIR&lt;/code&gt; に移動して、以下のコマンドで起動する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ unicorn -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;先ほど作成した Unicorn の設定ファイルを &lt;code&gt;-c&lt;/code&gt; オプションで指定し、&lt;code&gt;-D&lt;/code&gt; オプションでデーモン起動を行っている。&lt;/p&gt;

&lt;p&gt;unicorn はデフォルトで &lt;code&gt;config.ru&lt;/code&gt; をアプリケーションのエントリポイントとして認識するので、起動時のディレクトリに存在する Sinatra で書かれた Rack アプリケーションである &lt;code&gt;$APP_DIR/config.ru&lt;/code&gt; が上記のコマンドで読み込まれている。&lt;/p&gt;

&lt;p&gt;ログファイルを確認してみる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ cat unicorn.log
I, [2011-07-30T21:50:47.966116 #6632]  INFO -- : unlinking existing socket=/tmp/unicorn.sock
I, [2011-07-30T21:50:47.966669 #6632]  INFO -- : listening on addr=/tmp/unicorn.sock fd=3
I, [2011-07-30T21:50:47.967666 #6632]  INFO -- : Refreshing Gem list
I, [2011-07-30T21:50:48.343228 #6632]  INFO -- : worker=0 spawning...
I, [2011-07-30T21:50:48.343795 #6632]  INFO -- : worker=1 spawning...
I, [2011-07-30T21:50:48.344260 #6632]  INFO -- : master process ready
I, [2011-07-30T21:50:48.344266 #6635]  INFO -- : worker=0 spawned pid=6635
I, [2011-07-30T21:50:48.344450 #6635]  INFO -- : worker=0 ready
I, [2011-07-30T21:50:48.344672 #6638]  INFO -- : worker=1 spawned pid=6638
I, [2011-07-30T21:50:48.344863 #6638]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;エラーが表示されておらず、上記のようなログが出力されていれば問題なく起動が行えている。
master プロセスが1つ上がり、worker プロセス2つを起動している。&lt;/p&gt;

&lt;h3 id="nginx--unicorn-"&gt;nginx と Unicorn を連携する&lt;/h3&gt;

&lt;p&gt;フロントでリクエストを処理する nginx の設定。&lt;/p&gt;

&lt;p&gt;最低限の設定というところで、以下の設定を記述する。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;upstream&lt;/code&gt; ディレクティブ(ロードバランシングの指定)で &lt;code&gt;unicornapp&lt;/code&gt; というバックエンドサーバを定義し、Unicorn サーバの Unix ドメインソケットを指定しておく。&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;location&lt;/code&gt; ディレクティブで &lt;code&gt;upstream&lt;/code&gt; に指定した &lt;code&gt;unicornapp&lt;/code&gt; バックエンドサーバを指定する&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;upstream unicornapp {
  server unix:/tmp/unicorn.sock;
}

server {
        listen   80;
        server_name localhost;

        location / {
               proxy_pass http://unicornapp;
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;nginx 設定ファイルの再読込を行い、ブラウザで &lt;code&gt;http://localhost/hello&lt;/code&gt; の URI を参照すると先ほどの rackup コマンドを使用して確認した “Hello World” と同じメッセージの画面が表示されていることが確認できる。&lt;br /&gt;
(ここで確認している画面は Unicorn で提供されているサービス)&lt;/p&gt;

&lt;p&gt;unicorn のログにもリクエストを処理したメッセージが確認できる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ tail -f unicorn.log
...
I, [2011-07-30T22:13:27.755913 #7306]  INFO -- : worker=1 ready
I, [2011-07-30T22:13:27.756925 #7303]  INFO -- : worker=0 spawned pid=7303
I, [2011-07-30T22:13:27.757150 #7303]  INFO -- : worker=0 ready
127.0.0.1 - - [30/Jul/2011 22:13:39] "GET /hello HTTP/1.0" 200 11 0.0155
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で基本的な設定はおしまい。&lt;/p&gt;

&lt;h3 id="unicorn--4"&gt;Unicorn を停止する&lt;/h3&gt;

&lt;p&gt;Unicorn に対する操作は基本 Unicorn の master プロセスに対してのシグナルでの操作となる。&lt;/p&gt;

&lt;p&gt;まずは停止方法。2つの停止方法がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;プロセスを即座に終了する: &lt;strong&gt;INT/TERM&lt;/strong&gt; シグナルを使用&lt;/li&gt;
  &lt;li&gt;処理を行っているリクエストが完了するのを待ってプロセスを終了する: &lt;strong&gt;QUIT&lt;/strong&gt; シグナルを使用&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7299     1  0 22:13 ?        00:00:04 unicorn master -c unicorn.conf -D
hoge      7303  7299  0 22:13 ?        00:00:03 unicorn worker[0] -c unicorn.conf -D
hoge      7306  7299  0 22:13 ?        00:00:03 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記でわかるように、master プロセスは 7299 のプロセスIDで動作している。master プロセスに対してシグナルを送る。&lt;/p&gt;

&lt;p&gt;Unicorn を gracefully に終了させる場合、&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -QUIT 7299
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;unicorn.log&lt;/code&gt; を確認。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:32:13.866125 #7299]  INFO -- : reaped #&amp;lt;Process::Status: pid 7303 exit 0&amp;gt; worker=0
I, [2011-07-30T23:32:13.866403 #7299]  INFO -- : reaped #&amp;lt;Process::Status: pid 7306 exit 0&amp;gt; worker=1
I, [2011-07-30T23:32:13.866683 #7299]  INFO -- : master complete
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2つの worker プロセスと master プロセスが終了したことがわかる。&lt;/p&gt;

&lt;h3 id="unicorn--5"&gt;Unicorn の設定の再読込&lt;/h3&gt;

&lt;p&gt;Unicorn の設定を再読込させる場合は、master プロセスに &lt;strong&gt;HUP&lt;/strong&gt; シグナルを送る。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -HUP &lt;master のプロセスid=""&gt;


ログを確認してみると、再読みされていることが確認できる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:35:42.261177 #7768]  INFO -- : reloading config_file=unicorn.conf
I, [2011-07-30T23:35:42.272338 #7768]  INFO -- : Refreshing Gem list
I, [2011-07-30T23:35:42.557187 #7768]  INFO -- : done reloading config_file=unicorn.conf
I, [2011-07-30T23:35:42.557362 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7773 exit 0&amp;gt; worker=0
I, [2011-07-30T23:35:42.557432 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7776 exit 0&amp;gt; worker=1
I, [2011-07-30T23:35:42.557545 #7768]  INFO -- : worker=0 spawning...
I, [2011-07-30T23:35:42.558136 #7768]  INFO -- : worker=1 spawning...
I, [2011-07-30T23:35:42.558726 #7782]  INFO -- : worker=0 spawned pid=7782
I, [2011-07-30T23:35:42.558966 #7782]  INFO -- : worker=0 ready
I, [2011-07-30T23:35:42.559173 #7785]  INFO -- : worker=1 spawned pid=7785
I, [2011-07-30T23:35:42.559430 #7785]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

### サービスの提供を止めずにプログラムの再読込 ###

プログラム(ここで言う Sinatra Hello World アプリ)を再配置するときなど、再度プログラムをロードし直す必要がある。  
Unicorn サーバを停止して、再起動でもよいが、サービスの提供を止めずに実施する場合の実施方法は以下の方法となる。

現在のプロセスの状況は以下の通り。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:00 unicorn master -c unicorn.conf -D
hoge      7782  7768  0 23:35 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7785  7768  0 23:35 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

ここで何らかのアプリの改修があり、プログラムを再配置したとする。

Unicorn では、既存のプロセスをそのまま残し、新たな Unicorn サーバのセットをもう一セット作成し、リクエストの処理もそちらに引き継いであげることができる。

まず 現在の master プロセスに USR2 シグナルを送る。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -USR2 7768
&lt;/code&gt;&lt;/pre&gt;

Unicorn のプロセスを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:01 unicorn master (old) -c unicorn.conf -D
hoge      7782  7768  0 23:35 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7785  7768  0 23:35 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
hoge      7822  7768  1 23:43 ?        00:00:00 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

元々あったプロセス(master pid: 7768)に old という表示が入っており、Unicorn サーバのセットがもうワンセット追加されていることがわかる。

新たに生成されたプロセスには、プログラムの更新が反映されている。

この時の Unicorn の動作をログで確認してみると以下の動作になっている。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:43:20.117449 #7822]  INFO -- : executing ["/home/hoge/.rvm/gems/ruby-1.9.2-p180/bin/unicorn", "-c", "unicorn.conf", "-D"] (in /home/hoge/Dropbox/work/unicorn-app-sample)
I, [2011-07-30T23:43:20.117641 #7822]  INFO -- : forked child re-executing...
I, [2011-07-30T23:43:20.798555 #7822]  INFO -- : inherited addr=/tmp/unicorn.sock fd=3
I, [2011-07-30T23:43:20.798829 #7822]  INFO -- : Refreshing Gem list
I, [2011-07-30T23:43:21.165052 #7822]  INFO -- : worker=0 spawning...
I, [2011-07-30T23:43:21.165798 #7822]  INFO -- : worker=1 spawning...
I, [2011-07-30T23:43:21.166209 #7826]  INFO -- : worker=0 spawned pid=7826
I, [2011-07-30T23:43:21.166311 #7822]  INFO -- : master process ready
I, [2011-07-30T23:43:21.166401 #7826]  INFO -- : worker=0 ready
I, [2011-07-30T23:43:21.166635 #7829]  INFO -- : worker=1 spawned pid=7829
I, [2011-07-30T23:43:21.166768 #7829]  INFO -- : worker=1 ready
&lt;/code&gt;&lt;/pre&gt;

新しいプロセスにリクエストの受付処理は引き継がれているので、古い方のプロセスを落としていく。

まずは、古い方の master プロセスに WINCH シグナルを送り、その worker プロセスを落としてあげる。
WINCH シグナルはその master プロセスの worker プロセスを gracefully に止めてあげる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -WINCH 7768
&lt;/code&gt;&lt;/pre&gt;

プロセスとログを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7768     1  0 23:35 ?        00:00:01 unicorn master (old) -c unicorn.conf -D
hoge      7822  7768  0 23:43 ?        00:00:01 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:48:45.648299 #7768]  INFO -- : gracefully stopping all workers
I, [2011-07-30T23:48:45.678491 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7782 exit 0&amp;gt; worker=0
I, [2011-07-30T23:48:45.678664 #7768]  INFO -- : reaped #&amp;lt;Process::Status: pid 7785 exit 0&amp;gt; worker=1
&lt;/code&gt;&lt;/pre&gt;

確かに、古い方の Unicorn のプロセスは、master プロセスだけが残り、worker は全て終了している。

一旦ここで念のため、アプリがキチンと動作しているか確認しておく。  
問題無いようであれば、古い master プロセスも止めてあげる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ kill -QUIT 7768
&lt;/code&gt;&lt;/pre&gt;

プロセスとログを確認してみる。

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ ps -ef | grep unicorn | grep -v grep
hoge      7822     1  0 23:43 ?        00:00:01 unicorn master -c unicorn.conf -D
hoge      7826  7822  0 23:43 ?        00:00:00 unicorn worker[0] -c unicorn.conf -D
hoge      7829  7822  0 23:43 ?        00:00:00 unicorn worker[1] -c unicorn.conf -D
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;I, [2011-07-30T23:51:35.694051 #7768]  INFO -- : master complete
&lt;/code&gt;&lt;/pre&gt;

これで、新しいプログラムで Unicorn サーバが動作している状態となる。
&lt;/master&gt;&lt;/code&gt;&lt;/pre&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-07-09:/2011/07/09/flowdock/</id>
    <title type="html">情報の集約とコミュニケーションの円滑化 - チームの情報のハブになる便利なツール Flowdock</title>
    <published>2011-07-08T15:35:00Z</published>
    <updated>2011-07-08T15:35:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/07/09/flowdock/"/>
    <content type="html">&lt;p&gt;チーム内で扱われる情報を一箇所に集約し、リアルタイムにそれらの情報についてコミニュケーションをとれるようなツールはないだろうか？
たまたまフォローしている方のつぶやきで知った Flowdock。1ヶ月程使ってみたが、まさに求めていた(以上の)ツール。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/"&gt;Flowdock Teamwork Revolution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/images/misc/flowdock-w500.png" alt="lowdock" /&gt;&lt;/p&gt;

&lt;p&gt;実際に使用している画面は以下のような感じ。&lt;br /&gt;
使い方は至ってシンプル。まさにヒットしているコミニュケーションツール(twitter だったり、2ch だったり)の特徴だ。
このシンプルさのため、自分たちの目的に合わせて自由に使える柔軟性も合わせ持つ。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/misc/flowdock-1-w500.png" alt="lowdock-1" /&gt;&lt;/p&gt;

&lt;p&gt;左側が &lt;strong&gt;influx&lt;/strong&gt;(直訳すると「流入」) と呼ばれているもので、チーム内に必要な情報を流しこむところ。&lt;br /&gt;
上記画面では、twitter のリアルタイム検索の結果、チェックしておきたい twitter アカウントの情報、Wiki ツールである Confluence の更新履歴などがリアルタイムに流れ込んできている。&lt;/p&gt;

&lt;p&gt;この流れこんできている1つ1つの情報にはコメントを入れることもできる。&lt;br /&gt;
例えば wiki で書かれた更新履歴についてコメントして議論したり、後でチェックしておきたい情報にはコメントを入れておくようなこともできるので、情報が埋もれてしまうことがない。&lt;/p&gt;

&lt;p&gt;右側がグループチャットのペイン。&lt;br /&gt;
独り言を呟くのもよいが、twitter のように “@” を使って宛先を指定できたり、”#” を使ってタグを付けることもできる。&lt;br /&gt;
自分宛のつぶやきには上記のように背景色が黄色になるのでわかり易い。また、設定で変えられるが自分宛のつぶやきが届いた場合には「ポローン」と音で通知してれる。&lt;/p&gt;

&lt;p&gt;使い方がシンプルな割に多くの特徴をもつアプリケーションで、なかなかその良さの全ては書ききれない。&lt;br /&gt;
先に記述した内容と多少重複すること部分もあるが、公式サイトで書かれている3つの特徴について書いてみる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Discuss (議論する)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Aggregate (集約する)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Organize (整理する)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;具体的にどういうことか？&lt;/p&gt;

&lt;h3 id="discuss-"&gt;Discuss (議論する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;リアルタイムグループチャット &amp;amp;&amp;amp; ファイルの共有と保管場所として&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;チーム内のコミニュケーションにメールを使うのは非効率でストレスが溜まる。&lt;br /&gt;
開発者間であれば、IRC などを使うのも手なのだが、デザイナーさんであったり、IT を専門としない方などとのやり取りには使い難い。&lt;br /&gt;
また、画像などが扱えると会話がスムーズになったりもする。&lt;/p&gt;

&lt;p&gt;誰にでも簡単に使えて、画像の扱いも容易なリアルタイムグループチャット、まず1つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;更に、Twitter のように、”@” で宛先を指定でき、指定された方では音声での通知(設定は変えられる)、背景色の変化などで容易に認識できるようになっている。
また、”#” でタグ付けが行える。&lt;/p&gt;

&lt;p&gt;タグでの絞り込み検索、”@” の宛先による絞り込み検索なども行えるので、チャットアプリケーションにありがちな &lt;strong&gt;過去情報が埋もれてしまう心配もない&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;タグ、”@” による宛先指定は取り外し可能なので、自分などはちょっとしたタスク管理にも Flowdock を使っており、タグを活用している。
すぐできないタスクには “#todo” タグを振っておき、後で”#todo”タグでタスクを検索、完了したらタグを剥がす、というような使い方。&lt;br /&gt;
また、”@” を併用することで、誰のタスクなのか？まで管理できたりもする。&lt;/p&gt;

&lt;h3 id="aggregate-"&gt;Aggregate (集約する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;他システムとの容易な連携&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redmine や JIRA といった課題管理システム、Confluence などの Wiki システム、github など、プロジェクトには欠かせない他システムとの連携が容易に、かつ、リアルタイムに行える。&lt;/p&gt;

&lt;p&gt;リアルなアップデート情報は Flowdock だけを気にしていれば事足りるようになる。&lt;/p&gt;

&lt;p&gt;この&lt;strong&gt;チームに必要な情報を全て1箇所に集約&lt;/strong&gt;できるというのが、2つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;Atlassian 製品の代理店でもあるらしく、Atlassian 製品との連携は特によくでている。&lt;br /&gt;
それ以外のものでも、基本 RSS フィードをはいているものであれば、Flow に流し込むことができる。&lt;/p&gt;

&lt;p&gt;また、Twitter との連携も可能で、リアルタイム検索の結果の流しこみ、Twitter アカウントの follow も可能。&lt;/p&gt;

&lt;p&gt;開発チームであれば、リポジトリへのコミットログや、deploy 情報も流し込めるので Flowdock の &lt;strong&gt;influx&lt;/strong&gt; を追っているだけで、ティーム内の活動状況を把握することができる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/tour/developers"&gt;Flowdock for Software Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="organize-"&gt;Organize (整理する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;タグ付けで会話をナレッジに&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;グループチャットでは一過性の情報をやり取りすることが大半だが、Flowdock では&lt;strong&gt;そのやり取りがそのままナレッジとしても蓄積される&lt;/strong&gt;仕組みを用意してくれている。&lt;br /&gt;
これが3つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;まず、やり取りされる情報は全て永久に Flowdock に保存される。&lt;br /&gt;
Twitter のようなタグ付け、メンションの機能、そして、全文検索も可能なので、&lt;strong&gt;過去やり取りした情報を容易に後からピックアップすることができる&lt;/strong&gt;。&lt;br /&gt;
(タグは日本語でも全然問題ないが、全文検索に関しては現状日本語での検索は行えない。)&lt;/p&gt;

&lt;h3 id="section"&gt;「ドッグフードを食べる」&lt;/h3&gt;

&lt;p&gt;ダラダラと書いてしまったが、使ってみてもらえるとすぐにその良さを体感してもらえるのではないかと思う。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/"&gt;Flowdock Teamwork Revolution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ソフトウェア開発の概念で、「ドッグフードを食べる」という言葉がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food"&gt;Eating your own dog food - Wikipedia, the free encyclopedia&lt;/a&gt;&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;Eating your own dog food, also called dogfooding, is when a company (usually, a software company) uses the products that it makes.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;自社製品を自分たちでも実際に業務で使って評価して開発していることを言うのだが、使ってみて、まさにそうして開発されてきたサービスではないのかなと感じた。&lt;/p&gt;

&lt;p&gt;自分たちが必要、便利だと思うものをサービスにして、それをその利用者にも喜んでもらえる、という状況は理想的な状況だ。&lt;/p&gt;

&lt;p&gt;フィンランドの会社のようで、メンバの方とちょっとやり取りさせてもらったのだが、とても丁寧で親切。&lt;br /&gt;
そして、自分たちのサービスを好きで、誇りを持っており、更によいサービスにしていきたいと思っている意志と情熱がひしひしと伝わってきた。&lt;/p&gt;

&lt;p&gt;今後の更なる進化も期待できるサービス。&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;チーム内で扱われる情報を一箇所に集約し、リアルタイムにそれらの情報についてコミニュケーションをとれるようなツールはないだろうか？
たまたまフォローしている方のつぶやきで知った Flowdock。1ヶ月程使ってみたが、まさに求めていた(以上の)ツール。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/"&gt;Flowdock Teamwork Revolution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/images/misc/flowdock-w500.png" alt="lowdock" /&gt;&lt;/p&gt;

&lt;p&gt;実際に使用している画面は以下のような感じ。&lt;br /&gt;
使い方は至ってシンプル。まさにヒットしているコミニュケーションツール(twitter だったり、2ch だったり)の特徴だ。
このシンプルさのため、自分たちの目的に合わせて自由に使える柔軟性も合わせ持つ。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/misc/flowdock-1-w500.png" alt="lowdock-1" /&gt;&lt;/p&gt;

&lt;p&gt;左側が &lt;strong&gt;influx&lt;/strong&gt;(直訳すると「流入」) と呼ばれているもので、チーム内に必要な情報を流しこむところ。&lt;br /&gt;
上記画面では、twitter のリアルタイム検索の結果、チェックしておきたい twitter アカウントの情報、Wiki ツールである Confluence の更新履歴などがリアルタイムに流れ込んできている。&lt;/p&gt;

&lt;p&gt;この流れこんできている1つ1つの情報にはコメントを入れることもできる。&lt;br /&gt;
例えば wiki で書かれた更新履歴についてコメントして議論したり、後でチェックしておきたい情報にはコメントを入れておくようなこともできるので、情報が埋もれてしまうことがない。&lt;/p&gt;

&lt;p&gt;右側がグループチャットのペイン。&lt;br /&gt;
独り言を呟くのもよいが、twitter のように “@” を使って宛先を指定できたり、”#” を使ってタグを付けることもできる。&lt;br /&gt;
自分宛のつぶやきには上記のように背景色が黄色になるのでわかり易い。また、設定で変えられるが自分宛のつぶやきが届いた場合には「ポローン」と音で通知してれる。&lt;/p&gt;

&lt;p&gt;使い方がシンプルな割に多くの特徴をもつアプリケーションで、なかなかその良さの全ては書ききれない。&lt;br /&gt;
先に記述した内容と多少重複すること部分もあるが、公式サイトで書かれている3つの特徴について書いてみる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Discuss (議論する)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Aggregate (集約する)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Organize (整理する)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;具体的にどういうことか？&lt;/p&gt;

&lt;h3 id="discuss-"&gt;Discuss (議論する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;リアルタイムグループチャット &amp;amp;&amp;amp; ファイルの共有と保管場所として&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;チーム内のコミニュケーションにメールを使うのは非効率でストレスが溜まる。&lt;br /&gt;
開発者間であれば、IRC などを使うのも手なのだが、デザイナーさんであったり、IT を専門としない方などとのやり取りには使い難い。&lt;br /&gt;
また、画像などが扱えると会話がスムーズになったりもする。&lt;/p&gt;

&lt;p&gt;誰にでも簡単に使えて、画像の扱いも容易なリアルタイムグループチャット、まず1つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;更に、Twitter のように、”@” で宛先を指定でき、指定された方では音声での通知(設定は変えられる)、背景色の変化などで容易に認識できるようになっている。
また、”#” でタグ付けが行える。&lt;/p&gt;

&lt;p&gt;タグでの絞り込み検索、”@” の宛先による絞り込み検索なども行えるので、チャットアプリケーションにありがちな &lt;strong&gt;過去情報が埋もれてしまう心配もない&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;タグ、”@” による宛先指定は取り外し可能なので、自分などはちょっとしたタスク管理にも Flowdock を使っており、タグを活用している。
すぐできないタスクには “#todo” タグを振っておき、後で”#todo”タグでタスクを検索、完了したらタグを剥がす、というような使い方。&lt;br /&gt;
また、”@” を併用することで、誰のタスクなのか？まで管理できたりもする。&lt;/p&gt;

&lt;h3 id="aggregate-"&gt;Aggregate (集約する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;他システムとの容易な連携&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redmine や JIRA といった課題管理システム、Confluence などの Wiki システム、github など、プロジェクトには欠かせない他システムとの連携が容易に、かつ、リアルタイムに行える。&lt;/p&gt;

&lt;p&gt;リアルなアップデート情報は Flowdock だけを気にしていれば事足りるようになる。&lt;/p&gt;

&lt;p&gt;この&lt;strong&gt;チームに必要な情報を全て1箇所に集約&lt;/strong&gt;できるというのが、2つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;Atlassian 製品の代理店でもあるらしく、Atlassian 製品との連携は特によくでている。&lt;br /&gt;
それ以外のものでも、基本 RSS フィードをはいているものであれば、Flow に流し込むことができる。&lt;/p&gt;

&lt;p&gt;また、Twitter との連携も可能で、リアルタイム検索の結果の流しこみ、Twitter アカウントの follow も可能。&lt;/p&gt;

&lt;p&gt;開発チームであれば、リポジトリへのコミットログや、deploy 情報も流し込めるので Flowdock の &lt;strong&gt;influx&lt;/strong&gt; を追っているだけで、ティーム内の活動状況を把握することができる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/tour/developers"&gt;Flowdock for Software Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="organize-"&gt;Organize (整理する)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;タグ付けで会話をナレッジに&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;グループチャットでは一過性の情報をやり取りすることが大半だが、Flowdock では&lt;strong&gt;そのやり取りがそのままナレッジとしても蓄積される&lt;/strong&gt;仕組みを用意してくれている。&lt;br /&gt;
これが3つ目の Flowdock の特徴。&lt;/p&gt;

&lt;p&gt;まず、やり取りされる情報は全て永久に Flowdock に保存される。&lt;br /&gt;
Twitter のようなタグ付け、メンションの機能、そして、全文検索も可能なので、&lt;strong&gt;過去やり取りした情報を容易に後からピックアップすることができる&lt;/strong&gt;。&lt;br /&gt;
(タグは日本語でも全然問題ないが、全文検索に関しては現状日本語での検索は行えない。)&lt;/p&gt;

&lt;h3 id="section"&gt;「ドッグフードを食べる」&lt;/h3&gt;

&lt;p&gt;ダラダラと書いてしまったが、使ってみてもらえるとすぐにその良さを体感してもらえるのではないかと思う。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.flowdock.com/"&gt;Flowdock Teamwork Revolution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ソフトウェア開発の概念で、「ドッグフードを食べる」という言葉がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food"&gt;Eating your own dog food - Wikipedia, the free encyclopedia&lt;/a&gt;&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;Eating your own dog food, also called dogfooding, is when a company (usually, a software company) uses the products that it makes.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;自社製品を自分たちでも実際に業務で使って評価して開発していることを言うのだが、使ってみて、まさにそうして開発されてきたサービスではないのかなと感じた。&lt;/p&gt;

&lt;p&gt;自分たちが必要、便利だと思うものをサービスにして、それをその利用者にも喜んでもらえる、という状況は理想的な状況だ。&lt;/p&gt;

&lt;p&gt;フィンランドの会社のようで、メンバの方とちょっとやり取りさせてもらったのだが、とても丁寧で親切。&lt;br /&gt;
そして、自分たちのサービスを好きで、誇りを持っており、更によいサービスにしていきたいと思っている意志と情熱がひしひしと伝わってきた。&lt;/p&gt;

&lt;p&gt;今後の更なる進化も期待できるサービス。&lt;/p&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-07-03:/2011/07/03/virtualbox-shared-folders/</id>
    <title type="html">作業データを複数の VM で共有する - VirtualBox「共有フォルダ」の使い方</title>
    <published>2011-07-03T08:01:00Z</published>
    <updated>2011-07-03T08:01:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/07/03/virtualbox-shared-folders/"/>
    <content type="html">&lt;p&gt;複数の VM 環境を扱っているとき、VM 上でカスタマイズする設定ファイル、スクリプトなどの大半は各 VM で共有できることが多い。&lt;br /&gt;
VM 環境毎に新たにファイルを作成したり、ファイルを scp 等でコピーしたり、など、まともにやっていると管理含めてメンドイことになる。&lt;br /&gt;
ローカルで開発を行っており、複数の VM を使って作業を行う場合、VM 環境からローカル(ホストOS)のファイルを扱えるようにしておいて、各 VM で共有できると何かと便利だ。&lt;/p&gt;

&lt;p&gt;VM 環境からローカル(ホストOS)のファイルを「共有フォルダ」として扱えるようにする。&lt;/p&gt;

&lt;p&gt;また、このホスト OS の対象ファイルをオンラインストレージサービス Dropbox などで管理していものを利用すると、どのマシンでも同じ作業データを使用して VM 環境を利用できるようになる。&lt;/p&gt;

&lt;h3 id="section"&gt;環境と手順の概要&lt;/h3&gt;

&lt;p&gt;環境は以下の通りとなる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Oracle VM VirtualBox v4.0.8&lt;/li&gt;
  &lt;li&gt;ローカル(ホスト)OSは、Ubuntu 10.04 Desktop or Windows XP&lt;br /&gt;
VirtualBox が動作すれば特に選ばないはず。&lt;/li&gt;
  &lt;li&gt;仮想 OS は Turnkey Linux (Ubuntu 10.04) を使用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;手順は以下の流れとなる。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;VM Manager での作業
    &lt;ol&gt;
      &lt;li&gt;VM Manager でネットワーク設定に “Host only adapter” を追加しておく&lt;/li&gt;
      &lt;li&gt;共有フォルダを作成しておく&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;VM ゲスト OS での作業
    &lt;ol&gt;
      &lt;li&gt;必要なパッケージのインストール&lt;/li&gt;
      &lt;li&gt;Guest Additions のインストール&lt;br /&gt;
 a. イメージのマウント&lt;br /&gt;
 b. Guest Addictions のインストール実行&lt;/li&gt;
      &lt;li&gt;共有フォルダを利用する&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="vm-manager-"&gt;1. VM Manager での作業&lt;/h3&gt;

&lt;p&gt;まずは、VM Manager での作業。まだ VM のマシンは起動していない。&lt;/p&gt;

&lt;h4 id="vm-manager--host-only-adapter-"&gt;1.1. VM Manager でネットワーク設定に “Host only adapter” を追加しておく&lt;/h4&gt;

&lt;p&gt;VM Manager を使用して仮想マシンのネットワーク設定に “Host only adapter” を設定していない場合には設定しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-network-setting-w500.png" alt="virtualbox-network-setting" /&gt;&lt;/p&gt;

&lt;h4 id="section-1"&gt;1.2. 共有フォルダを作成しておく&lt;/h4&gt;

&lt;p&gt;VM から使用するローカル(ゲストOS)のディレクトリを指定し、共有フォルダとして VM Manager に登録しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-share-folder-setting-w500.png" alt="virtualbox-share-folder-setting" /&gt;&lt;/p&gt;

&lt;p&gt;上記の例では、実体としてのフォルダを”ファルダのパス” (&lt;code&gt;/home/xxx/Dropbox&lt;/code&gt;) に指定し、”フォルダ名” に “Dropbox” と指定している。
後者の “フォルダ名” というのが、VM 環境のゲスト OS から参照する際のフォルダの名称となる。&lt;/p&gt;

&lt;p&gt;ここで、VM のマシンを起動しておく。&lt;/p&gt;

&lt;h3 id="vm--os-"&gt;2. VM ゲスト OS での作業&lt;/h3&gt;

&lt;p&gt;VM のゲスト OS での作業になる。&lt;/p&gt;

&lt;h4 id="section-2"&gt;2.1. 必要なパッケージのインストール&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;bzip2&lt;/code&gt;、&lt;code&gt;dkms&lt;/code&gt;、&lt;code&gt;build-essential&lt;/code&gt;、&lt;code&gt;linux-headers-&amp;lt;kernel-version&amp;gt;&lt;/code&gt; が必要となる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# apt-get install bzip2
# apt-get install dkms
# apt-get install build-essential
# apt-get install linux-headers-`uname -r`
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="guest-additions-"&gt;2.2. Guest Additions のインストール&lt;/h4&gt;

&lt;p&gt;VirtualBox が提供している Guest Addictions のインストールを行う。
まずは、このインストールに使用するファイルをゲストOSから見えるようにする。&lt;/p&gt;

&lt;h5 id="a-"&gt;2.2.a) イメージのマウント&lt;/h5&gt;

&lt;p&gt;VirtualBox の “デバイス” メニューにある “Guest Addictions のインストール” をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-guest-addictions-install-1-w500.png" alt="virtualbox-guest-addictions-install-1" /&gt;&lt;/p&gt;

&lt;p&gt;クリックした後、画面上何の変化もなく、何が起きたの？的な状況になるが、これで、ゲスト OS から “Guest Addictions” のインストール用ファイルがあるイメージを参照できるようになっている。&lt;/p&gt;

&lt;p&gt;ゲスト OS からマウントする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mkdir /media/cdrom
# mount /dev/cdrom /media/cdrom
# cd /media/cdrom/
# ls -l
total 37393
dr-xr-xr-x 3 root root     2048 2011-05-17 01:59 32Bit
dr-xr-xr-x 2 root root     2048 2011-05-17 01:59 64Bit
-r-xr-xr-x 1 root root      647 2011-01-19 21:42 AUTORUN.INF
-r-xr-xr-x 1 root root  7853516 2011-05-17 01:53 VBoxLinuxAdditions.run
-r-xr-xr-x 1 root root 14664192 2011-05-17 01:55 VBoxSolarisAdditions.pkg
-r-xr-xr-x 1 root root  9284432 2011-05-17 01:45 VBoxWindowsAdditions-amd64.exe
-r-xr-xr-x 1 root root  6190464 2011-05-17 01:39 VBoxWindowsAdditions-x86.exe
-r-xr-xr-x 1 root root   278832 2011-05-17 01:39 VBoxWindowsAdditions.exe
-r-xr-xr-x 1 root root     6966 2011-05-17 01:51 autorun.sh
-r-xr-xr-x 1 root root     5523 2011-05-17 01:51 runasroot.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;インストールプログラムである &lt;code&gt;VBoxLinuxAdditions.run&lt;/code&gt; が見えている。&lt;/p&gt;

&lt;h5 id="b-guest-addictions-"&gt;2.2.b) Guest Addictions のインストール実行&lt;/h5&gt;

&lt;p&gt;インストールを実行する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# ./VBoxLinuxAdditions.run 
Verifying archive integrity... All good.
Uncompressing VirtualBox 4.0.8 Guest Additions for Linux..........
VirtualBox Guest Additions installer
tar: Record size = 8 blocks
Removing existing VirtualBox DKMS kernel modules ...done.
Removing existing VirtualBox non-DKMS kernel modules ...done.
Building the VirtualBox Guest Additions kernel modules ...done.
Doing non-kernel setup of the Guest Additions ...done.
Starting the VirtualBox Guest Additions ...done.
Installing the Window System drivers ...fail!
(Could not find the X.Org or XFree86 Window System.)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;“Window System drivers” が fail しているが、サーバ用途で使っていてファイルの共有だけの用途であれば無視して構わない。&lt;/p&gt;

&lt;h4 id="section-3"&gt;2.3. 共有フォルダを利用する&lt;/h4&gt;

&lt;p&gt;先に VM Manager 側の作業で共有フォルダ “Dropbox” を作成していた。
この共有フォルダをゲスト OS でマウントする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mkdir Dropbox
# mount -t vboxsf Dropbox ~/Dropbox
# cd Dropbox/
# ls -l
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上でゲスト OS のファイルを VM ゲスト OS から利用可能となる。&lt;/p&gt;

&lt;h3 id="section-4"&gt;参考サイト&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.turnkeylinux.org/forum/general/20110128/lamp-and-virtualbox-4-shared-folders"&gt;LAMP and VirtualBox 4 Shared Folders TurnKey Linux Forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <summary type="html">&lt;p&gt;複数の VM 環境を扱っているとき、VM 上でカスタマイズする設定ファイル、スクリプトなどの大半は各 VM で共有できることが多い。&lt;br /&gt;
VM 環境毎に新たにファイルを作成したり、ファイルを scp 等でコピーしたり、など、まともにやっていると管理含めてメンドイことになる。&lt;br /&gt;
ローカルで開発を行っており、複数の VM を使って作業を行う場合、VM 環境からローカル(ホストOS)のファイルを扱えるようにしておいて、各 VM で共有できると何かと便利だ。&lt;/p&gt;

&lt;p&gt;VM 環境からローカル(ホストOS)のファイルを「共有フォルダ」として扱えるようにする。&lt;/p&gt;

&lt;p&gt;また、このホスト OS の対象ファイルをオンラインストレージサービス Dropbox などで管理していものを利用すると、どのマシンでも同じ作業データを使用して VM 環境を利用できるようになる。&lt;/p&gt;

&lt;h3 id="section"&gt;環境と手順の概要&lt;/h3&gt;

&lt;p&gt;環境は以下の通りとなる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Oracle VM VirtualBox v4.0.8&lt;/li&gt;
  &lt;li&gt;ローカル(ホスト)OSは、Ubuntu 10.04 Desktop or Windows XP&lt;br /&gt;
VirtualBox が動作すれば特に選ばないはず。&lt;/li&gt;
  &lt;li&gt;仮想 OS は Turnkey Linux (Ubuntu 10.04) を使用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;手順は以下の流れとなる。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;VM Manager での作業
    &lt;ol&gt;
      &lt;li&gt;VM Manager でネットワーク設定に “Host only adapter” を追加しておく&lt;/li&gt;
      &lt;li&gt;共有フォルダを作成しておく&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;VM ゲスト OS での作業
    &lt;ol&gt;
      &lt;li&gt;必要なパッケージのインストール&lt;/li&gt;
      &lt;li&gt;Guest Additions のインストール&lt;br /&gt;
 a. イメージのマウント&lt;br /&gt;
 b. Guest Addictions のインストール実行&lt;/li&gt;
      &lt;li&gt;共有フォルダを利用する&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="vm-manager-"&gt;1. VM Manager での作業&lt;/h3&gt;

&lt;p&gt;まずは、VM Manager での作業。まだ VM のマシンは起動していない。&lt;/p&gt;

&lt;h4 id="vm-manager--host-only-adapter-"&gt;1.1. VM Manager でネットワーク設定に “Host only adapter” を追加しておく&lt;/h4&gt;

&lt;p&gt;VM Manager を使用して仮想マシンのネットワーク設定に “Host only adapter” を設定していない場合には設定しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-network-setting-w500.png" alt="virtualbox-network-setting" /&gt;&lt;/p&gt;

&lt;h4 id="section-1"&gt;1.2. 共有フォルダを作成しておく&lt;/h4&gt;

&lt;p&gt;VM から使用するローカル(ゲストOS)のディレクトリを指定し、共有フォルダとして VM Manager に登録しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-share-folder-setting-w500.png" alt="virtualbox-share-folder-setting" /&gt;&lt;/p&gt;

&lt;p&gt;上記の例では、実体としてのフォルダを”ファルダのパス” (&lt;code&gt;/home/xxx/Dropbox&lt;/code&gt;) に指定し、”フォルダ名” に “Dropbox” と指定している。
後者の “フォルダ名” というのが、VM 環境のゲスト OS から参照する際のフォルダの名称となる。&lt;/p&gt;

&lt;p&gt;ここで、VM のマシンを起動しておく。&lt;/p&gt;

&lt;h3 id="vm--os-"&gt;2. VM ゲスト OS での作業&lt;/h3&gt;

&lt;p&gt;VM のゲスト OS での作業になる。&lt;/p&gt;

&lt;h4 id="section-2"&gt;2.1. 必要なパッケージのインストール&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;bzip2&lt;/code&gt;、&lt;code&gt;dkms&lt;/code&gt;、&lt;code&gt;build-essential&lt;/code&gt;、&lt;code&gt;linux-headers-&amp;lt;kernel-version&amp;gt;&lt;/code&gt; が必要となる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# apt-get install bzip2
# apt-get install dkms
# apt-get install build-essential
# apt-get install linux-headers-`uname -r`
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="guest-additions-"&gt;2.2. Guest Additions のインストール&lt;/h4&gt;

&lt;p&gt;VirtualBox が提供している Guest Addictions のインストールを行う。
まずは、このインストールに使用するファイルをゲストOSから見えるようにする。&lt;/p&gt;

&lt;h5 id="a-"&gt;2.2.a) イメージのマウント&lt;/h5&gt;

&lt;p&gt;VirtualBox の “デバイス” メニューにある “Guest Addictions のインストール” をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/virtualbox-guest-addictions-install-1-w500.png" alt="virtualbox-guest-addictions-install-1" /&gt;&lt;/p&gt;

&lt;p&gt;クリックした後、画面上何の変化もなく、何が起きたの？的な状況になるが、これで、ゲスト OS から “Guest Addictions” のインストール用ファイルがあるイメージを参照できるようになっている。&lt;/p&gt;

&lt;p&gt;ゲスト OS からマウントする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mkdir /media/cdrom
# mount /dev/cdrom /media/cdrom
# cd /media/cdrom/
# ls -l
total 37393
dr-xr-xr-x 3 root root     2048 2011-05-17 01:59 32Bit
dr-xr-xr-x 2 root root     2048 2011-05-17 01:59 64Bit
-r-xr-xr-x 1 root root      647 2011-01-19 21:42 AUTORUN.INF
-r-xr-xr-x 1 root root  7853516 2011-05-17 01:53 VBoxLinuxAdditions.run
-r-xr-xr-x 1 root root 14664192 2011-05-17 01:55 VBoxSolarisAdditions.pkg
-r-xr-xr-x 1 root root  9284432 2011-05-17 01:45 VBoxWindowsAdditions-amd64.exe
-r-xr-xr-x 1 root root  6190464 2011-05-17 01:39 VBoxWindowsAdditions-x86.exe
-r-xr-xr-x 1 root root   278832 2011-05-17 01:39 VBoxWindowsAdditions.exe
-r-xr-xr-x 1 root root     6966 2011-05-17 01:51 autorun.sh
-r-xr-xr-x 1 root root     5523 2011-05-17 01:51 runasroot.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;インストールプログラムである &lt;code&gt;VBoxLinuxAdditions.run&lt;/code&gt; が見えている。&lt;/p&gt;

&lt;h5 id="b-guest-addictions-"&gt;2.2.b) Guest Addictions のインストール実行&lt;/h5&gt;

&lt;p&gt;インストールを実行する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# ./VBoxLinuxAdditions.run 
Verifying archive integrity... All good.
Uncompressing VirtualBox 4.0.8 Guest Additions for Linux..........
VirtualBox Guest Additions installer
tar: Record size = 8 blocks
Removing existing VirtualBox DKMS kernel modules ...done.
Removing existing VirtualBox non-DKMS kernel modules ...done.
Building the VirtualBox Guest Additions kernel modules ...done.
Doing non-kernel setup of the Guest Additions ...done.
Starting the VirtualBox Guest Additions ...done.
Installing the Window System drivers ...fail!
(Could not find the X.Org or XFree86 Window System.)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;“Window System drivers” が fail しているが、サーバ用途で使っていてファイルの共有だけの用途であれば無視して構わない。&lt;/p&gt;

&lt;h4 id="section-3"&gt;2.3. 共有フォルダを利用する&lt;/h4&gt;

&lt;p&gt;先に VM Manager 側の作業で共有フォルダ “Dropbox” を作成していた。
この共有フォルダをゲスト OS でマウントする。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mkdir Dropbox
# mount -t vboxsf Dropbox ~/Dropbox
# cd Dropbox/
# ls -l
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上でゲスト OS のファイルを VM ゲスト OS から利用可能となる。&lt;/p&gt;

&lt;h3 id="section-4"&gt;参考サイト&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.turnkeylinux.org/forum/general/20110128/lamp-and-virtualbox-4-shared-folders"&gt;LAMP and VirtualBox 4 Shared Folders TurnKey Linux Forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-06-26:/2011/06/26/refinerycms-add-migration-to-engine/</id>
    <title type="html">Refinery CMS - カスタム Engine でのマイグレーションの追加</title>
    <published>2011-06-26T14:05:00Z</published>
    <updated>2011-06-26T14:05:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/06/26/refinerycms-add-migration-to-engine/"/>
    <content type="html">&lt;p&gt;作成したカスタム Engine でマイグレーションを追加する場合、&lt;a href="http://refinerycms.com/"&gt;Refinery CMS&lt;/a&gt; のお作法としてどうするのがよいか？
如何様にもできそうだが、カスタム Engine のメンテナンス性が保てるやり方がよい。そのメモ。&lt;/p&gt;

&lt;p&gt;まず最初に product という簡単なサンプルカスタム Engine を作成する。
その後にマイグレーションを追加する方法を記載していく。作業の流れは以下の通り。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Rails 標準の rails generate migration でマイグレーションファイルを作成する&lt;/li&gt;
  &lt;li&gt;作成されたマイグレーションファイルをカスタム Engine 配下(&lt;code&gt;vendor/engines/my_engine/db/migrate&lt;/code&gt;)に配置する&lt;/li&gt;
  &lt;li&gt;generator を使用して Rails プロジェクト本体に配置し直して、&lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="engine-"&gt;0. 新規のカスタム Engine を作成しておく&lt;/h3&gt;

&lt;p&gt;これから作業するための新規のカスタム Engine を作成しておく。product という簡易な engine になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinery_engine product title:string description:text image:image
      create  vendor/engines/products/app/controllers/admin/products_controller.rb
      create  vendor/engines/products/app/controllers/products_controller.rb
      create  vendor/engines/products/app/models/product.rb
...(snip)...
      create  vendor/engines/products/refinerycms-products.gemspec
      create  vendor/engines/products/spec/models/product_spec.rb
------------------------
Now run:
bundle install
rails generate refinerycms_products
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最後のメッセージの指示通り引き続きコマンドを叩き、カスタム Engine を動作可能な状態としておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ bundle install
...(snip)...
$ rails g refinerycms_products
      create  db/migrate/20110615142942_create_products.rb
      create  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
$ rake db:migrate
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -&amp;gt; 0.0014s
-- add_index(:products, :id)
   -&amp;gt; 0.0005s
==  CreateProducts: migrated (0.4472s) ========================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で OK。サーバを起動して管理画面を確認してみると確かに product の管理画面が追加されている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-1-w500.png" alt="add-migrateion-to-engine" /&gt;&lt;/p&gt;

&lt;h3 id="rails--rails-generate-migration-"&gt;1. Rails 標準の rails generate migration でマイグレーションファイルを作成する&lt;/h3&gt;

&lt;p&gt;Product のモデルはすでに作成済みであるが、販売促進用のブローシャアをそれぞれの製品につけたくなったとする。製品に添付ファイルをつけられるようにする。&lt;/p&gt;

&lt;p&gt;まずは、Rails 標準の rails generate migration を使用して普通に(Rails way で)マイグレーションファイルを作成する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g migration AddBrochureToProducts
      invoke  active_record
      create    db/migrate/20110616161904_add_brochure_to_products.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;マイグレーションファイルに必要な記載を行っておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;db/migrate/20110615145336_add_brochure_to_product.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;class AddBrochureToProducts &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :products, :brochure_id, :integer
  end

  def self.down
    remove_column :products, :brochure
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;マイグレーションファイルへの追加は以上で終了となる。&lt;/p&gt;

&lt;p&gt;上記のマイグレーションの記載に関して、products テーブルに brochure_id という外部キーのフィールドを追加し、関連付けまでさせてたのはわかるが、brochure 本体はどこ？となるだろう。&lt;/p&gt;

&lt;p&gt;ここでは、Refinery CMS が標準で用意している Resources Engine を利用している。&lt;/p&gt;

&lt;p&gt;resource(ファイル)を扱う為の仕組みは既に Refinery CMS には用意されており、Resource モデルも既に存在する。上記はその外部キーを products テーブルに作成しようとしている。&lt;/p&gt;

&lt;p&gt;当然上記のスキーマの更新だけでは動作しないので、既に作成済みの Product モデルにも Resouce への関連を追加しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;vendor/engines/products/app/models/product.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class Product &amp;lt; ActiveRecord::Base

  acts_as_indexed :fields =&amp;gt; [:title, :description]

  validates :title, :presence =&amp;gt; true, :uniqueness =&amp;gt; true

  belongs_to :image

  belongs_to :brochure, :class_name =&amp;gt; 'Resource' # add
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="engine-vendorenginesmyenginedbmigrate"&gt;2. 作成されたマイグレーションファイルをカスタム Engine 配下(vendor/engines/my_engine/db/migrate)に配置する&lt;/h3&gt;

&lt;p&gt;先ほどの作成されたマイグレーションファイルは Rails プロジェクト本体の db/migrate 配下に作成されている。
これを Engine の db/migrate 配下に移動する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ mv db/migrate/20110616161904_add_brochure_to_products.rb vendor/engines/products/db/migrate/
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="generator--rails--rake-dbmigrate"&gt;3. generator を使用して Rails プロジェクト本体に配置し直し rake db:migrate&lt;/h3&gt;

&lt;p&gt;Refinery CMS が用意している generator を使用して、Rails プロジェクト本体に配置し直す。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinerycms_products
      create  db/migrate/20110616163831_add_brochure_to_products.rb
You already have a migration called create_products
      create  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;products Engine 配下の db/migrate に移動したマイグレーションファイルが、Rails プロジェクト本体の db/migrate 配下にコピーされる。
これで migrate する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rake db:migrate
==  AddBrochureToProducts: migrating ==========================================
-- add_column(:products, :brochure, :integer)
   -&amp;gt; 0.0014s
==  AddBrochureToProducts: migrated (0.0015s) =================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;仮に同じ名前のマイグレーションファイルがあった場合には、rails g refinerycms_products を実行しても Rails プロジェクト本体にはファイルはコピーされない。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinerycms_products
You already have a migration called add_brochure_to_products
You already have a migration called create_products
   identical  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上となる。&lt;/p&gt;

&lt;p&gt;スキーマに変更を加える場合には 1 〜 3 の同様の作業を繰り返す。&lt;/p&gt;

&lt;p&gt;まどろっこしいことをやっているようだが、この方法により、カスタム Engine ディレクトリ内に全て完結した構成がとれる。&lt;br /&gt;
独立性が保たれるので、他プロジェクトへの移植性も高くなる。&lt;/p&gt;

&lt;h3 id="section"&gt;(蛇足) 管理画面にブローシャアの登録機能を追加&lt;/h3&gt;

&lt;p&gt;「カスタム Engine でのマイグレーションの追加」の作業は以上で終了だが、モデルには手を加えたものの、管理画面にブローシャアを登録する為の機能が存在しないので追加する。&lt;/p&gt;

&lt;p&gt;既に管理画面用の共通部品として refinerycms-core で resource 用のPicker(&lt;code&gt;/shared/admin/_resource_picker.html.erb&lt;/code&gt;)が用意されているので、これを利用する。&lt;/p&gt;

&lt;p&gt;管理画面のフォームの view に以下の追加を行っておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;vendor/engines/products/app/views/admin/products/_form.html.erb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;イメージのフィールドの下あたりで brochure 用のフィールドを追加しておく。&lt;/p&gt;

&lt;pre class="html"&gt;&lt;code class="language-html"&gt;...(snip)
  &amp;lt;div class='field'&amp;gt;
    &amp;lt;%= f.label :image -%&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; "/shared/admin/image_picker", :locals =&amp;gt; {
          :f =&amp;gt; f,
          :field =&amp;gt; :image_id,
          :image =&amp;gt; @product.image,
          :toggle_image_display =&amp;gt; false
        } %&amp;gt;
  &amp;lt;/div&amp;gt;
  # add
  &amp;lt;div class='field'&amp;gt;
    &amp;lt;%= f.label :brochure -%&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; "/shared/admin/resource_picker", :locals =&amp;gt; {
          :f =&amp;gt; f,
          :field =&amp;gt; :brochure_id,
          :resource =&amp;gt; @product.brochure,
        } %&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;管理画面で確認すると確かにブローシャア用のフィールドが追加されておりちゃんと機能する。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-2-w500.png" alt="add-migrateion-to-engine2" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-3-w500.png" alt="add-migrateion-to-engine3" /&gt;&lt;/p&gt;

&lt;p&gt;同様にユーザに表示する画面にもブローシャアをダウンロードするための機能を追加しておく必要があるが、ここでは割愛する。&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;作成したカスタム Engine でマイグレーションを追加する場合、&lt;a href="http://refinerycms.com/"&gt;Refinery CMS&lt;/a&gt; のお作法としてどうするのがよいか？
如何様にもできそうだが、カスタム Engine のメンテナンス性が保てるやり方がよい。そのメモ。&lt;/p&gt;

&lt;p&gt;まず最初に product という簡単なサンプルカスタム Engine を作成する。
その後にマイグレーションを追加する方法を記載していく。作業の流れは以下の通り。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Rails 標準の rails generate migration でマイグレーションファイルを作成する&lt;/li&gt;
  &lt;li&gt;作成されたマイグレーションファイルをカスタム Engine 配下(&lt;code&gt;vendor/engines/my_engine/db/migrate&lt;/code&gt;)に配置する&lt;/li&gt;
  &lt;li&gt;generator を使用して Rails プロジェクト本体に配置し直して、&lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id="engine-"&gt;0. 新規のカスタム Engine を作成しておく&lt;/h3&gt;

&lt;p&gt;これから作業するための新規のカスタム Engine を作成しておく。product という簡易な engine になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinery_engine product title:string description:text image:image
      create  vendor/engines/products/app/controllers/admin/products_controller.rb
      create  vendor/engines/products/app/controllers/products_controller.rb
      create  vendor/engines/products/app/models/product.rb
...(snip)...
      create  vendor/engines/products/refinerycms-products.gemspec
      create  vendor/engines/products/spec/models/product_spec.rb
------------------------
Now run:
bundle install
rails generate refinerycms_products
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最後のメッセージの指示通り引き続きコマンドを叩き、カスタム Engine を動作可能な状態としておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ bundle install
...(snip)...
$ rails g refinerycms_products
      create  db/migrate/20110615142942_create_products.rb
      create  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
$ rake db:migrate
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -&amp;gt; 0.0014s
-- add_index(:products, :id)
   -&amp;gt; 0.0005s
==  CreateProducts: migrated (0.4472s) ========================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で OK。サーバを起動して管理画面を確認してみると確かに product の管理画面が追加されている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-1-w500.png" alt="add-migrateion-to-engine" /&gt;&lt;/p&gt;

&lt;h3 id="rails--rails-generate-migration-"&gt;1. Rails 標準の rails generate migration でマイグレーションファイルを作成する&lt;/h3&gt;

&lt;p&gt;Product のモデルはすでに作成済みであるが、販売促進用のブローシャアをそれぞれの製品につけたくなったとする。製品に添付ファイルをつけられるようにする。&lt;/p&gt;

&lt;p&gt;まずは、Rails 標準の rails generate migration を使用して普通に(Rails way で)マイグレーションファイルを作成する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g migration AddBrochureToProducts
      invoke  active_record
      create    db/migrate/20110616161904_add_brochure_to_products.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;マイグレーションファイルに必要な記載を行っておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;db/migrate/20110615145336_add_brochure_to_product.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;class AddBrochureToProducts &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :products, :brochure_id, :integer
  end

  def self.down
    remove_column :products, :brochure
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;マイグレーションファイルへの追加は以上で終了となる。&lt;/p&gt;

&lt;p&gt;上記のマイグレーションの記載に関して、products テーブルに brochure_id という外部キーのフィールドを追加し、関連付けまでさせてたのはわかるが、brochure 本体はどこ？となるだろう。&lt;/p&gt;

&lt;p&gt;ここでは、Refinery CMS が標準で用意している Resources Engine を利用している。&lt;/p&gt;

&lt;p&gt;resource(ファイル)を扱う為の仕組みは既に Refinery CMS には用意されており、Resource モデルも既に存在する。上記はその外部キーを products テーブルに作成しようとしている。&lt;/p&gt;

&lt;p&gt;当然上記のスキーマの更新だけでは動作しないので、既に作成済みの Product モデルにも Resouce への関連を追加しておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;vendor/engines/products/app/models/product.rb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="ruby"&gt;&lt;code class="language-ruby"&gt;class Product &amp;lt; ActiveRecord::Base

  acts_as_indexed :fields =&amp;gt; [:title, :description]

  validates :title, :presence =&amp;gt; true, :uniqueness =&amp;gt; true

  belongs_to :image

  belongs_to :brochure, :class_name =&amp;gt; 'Resource' # add
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="engine-vendorenginesmyenginedbmigrate"&gt;2. 作成されたマイグレーションファイルをカスタム Engine 配下(vendor/engines/my_engine/db/migrate)に配置する&lt;/h3&gt;

&lt;p&gt;先ほどの作成されたマイグレーションファイルは Rails プロジェクト本体の db/migrate 配下に作成されている。
これを Engine の db/migrate 配下に移動する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ mv db/migrate/20110616161904_add_brochure_to_products.rb vendor/engines/products/db/migrate/
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="generator--rails--rake-dbmigrate"&gt;3. generator を使用して Rails プロジェクト本体に配置し直し rake db:migrate&lt;/h3&gt;

&lt;p&gt;Refinery CMS が用意している generator を使用して、Rails プロジェクト本体に配置し直す。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinerycms_products
      create  db/migrate/20110616163831_add_brochure_to_products.rb
You already have a migration called create_products
      create  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;products Engine 配下の db/migrate に移動したマイグレーションファイルが、Rails プロジェクト本体の db/migrate 配下にコピーされる。
これで migrate する。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rake db:migrate
==  AddBrochureToProducts: migrating ==========================================
-- add_column(:products, :brochure, :integer)
   -&amp;gt; 0.0014s
==  AddBrochureToProducts: migrated (0.0015s) =================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;仮に同じ名前のマイグレーションファイルがあった場合には、rails g refinerycms_products を実行しても Rails プロジェクト本体にはファイルはコピーされない。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;$ rails g refinerycms_products
You already have a migration called add_brochure_to_products
You already have a migration called create_products
   identical  db/seeds/products.rb
------------------------
Now run:
rake db:migrate
------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上となる。&lt;/p&gt;

&lt;p&gt;スキーマに変更を加える場合には 1 〜 3 の同様の作業を繰り返す。&lt;/p&gt;

&lt;p&gt;まどろっこしいことをやっているようだが、この方法により、カスタム Engine ディレクトリ内に全て完結した構成がとれる。&lt;br /&gt;
独立性が保たれるので、他プロジェクトへの移植性も高くなる。&lt;/p&gt;

&lt;h3 id="section"&gt;(蛇足) 管理画面にブローシャアの登録機能を追加&lt;/h3&gt;

&lt;p&gt;「カスタム Engine でのマイグレーションの追加」の作業は以上で終了だが、モデルには手を加えたものの、管理画面にブローシャアを登録する為の機能が存在しないので追加する。&lt;/p&gt;

&lt;p&gt;既に管理画面用の共通部品として refinerycms-core で resource 用のPicker(&lt;code&gt;/shared/admin/_resource_picker.html.erb&lt;/code&gt;)が用意されているので、これを利用する。&lt;/p&gt;

&lt;p&gt;管理画面のフォームの view に以下の追加を行っておく。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;vendor/engines/products/app/views/admin/products/_form.html.erb&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;イメージのフィールドの下あたりで brochure 用のフィールドを追加しておく。&lt;/p&gt;

&lt;pre class="html"&gt;&lt;code class="language-html"&gt;...(snip)
  &amp;lt;div class='field'&amp;gt;
    &amp;lt;%= f.label :image -%&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; "/shared/admin/image_picker", :locals =&amp;gt; {
          :f =&amp;gt; f,
          :field =&amp;gt; :image_id,
          :image =&amp;gt; @product.image,
          :toggle_image_display =&amp;gt; false
        } %&amp;gt;
  &amp;lt;/div&amp;gt;
  # add
  &amp;lt;div class='field'&amp;gt;
    &amp;lt;%= f.label :brochure -%&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; "/shared/admin/resource_picker", :locals =&amp;gt; {
          :f =&amp;gt; f,
          :field =&amp;gt; :brochure_id,
          :resource =&amp;gt; @product.brochure,
        } %&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;管理画面で確認すると確かにブローシャア用のフィールドが追加されておりちゃんと機能する。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-2-w500.png" alt="add-migrateion-to-engine2" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ruby-misc/add-migrateion-to-engine-3-w500.png" alt="add-migrateion-to-engine3" /&gt;&lt;/p&gt;

&lt;p&gt;同様にユーザに表示する画面にもブローシャアをダウンロードするための機能を追加しておく必要があるが、ここでは割愛する。&lt;/p&gt;
</summary>
  </entry>
  <entry>
    <id>tag:blog.designrecipe.jp,2011-06-05:/2011/06/05/atlassian-confluence-install-memo/</id>
    <title type="html">Atlassian の Confluence 3.5 インストールメモ</title>
    <published>2011-06-05T14:05:00Z</published>
    <updated>2011-06-05T14:05:00Z</updated>
    <link rel="alternate" href="http://blog.designrecipe.jp/2011/06/05/atlassian-confluence-install-memo/"/>
    <content type="html">&lt;p&gt;Wiki のツールを調べており、Atlassian の Confluence を試してみることにした。そのインストールメモ。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.atlassian.com/ja_JP/software/confluence/"&gt;エンタープライズ コラボレーションおよび Wiki ソフトウェア - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/atlassian-confluence-w500.png" alt="atlassian-confluence" /&gt;&lt;/p&gt;

&lt;p&gt;まずは評価目的で試してみる。以下の構成でインストールする。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ベースとなる OS は仮想環境上にのせる。TurnKey Linux の提供する &lt;a href="http://www.turnkeylinux.org/tomcat"&gt;Virtual Applicace Standalone Tomcat Appliance&lt;/a&gt; を使う。
    &lt;ul&gt;
      &lt;li&gt;この環境は、Java 環境、Tomcat サーバ、MySQL 5.1 がすでに利用可能な環境となる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Confluence は Standalone ではなく WAR バージョンを既存の Tomcat 環境にインストールする&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;インストールの手順は、以下のドキュメントを参考に行う。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/DOC/Installing+the+Confluence+EAR-WAR+Edition"&gt;Installing the Confluence EAR-WAR Edition - Confluence 3.5 - Atlassian Documentation - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;事前に用意するものと事前準備&lt;/h3&gt;

&lt;h4 id="section-1"&gt;用意するもの&lt;/h4&gt;

&lt;p&gt;まず、Confluence のインストールに必要なものは以下の2点。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Confluence のインストール用ファイル&lt;/li&gt;
  &lt;li&gt;ライセンス&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ライセンスファイルはインストール途中で取得するので、まずはインストールに必要なファイルをダウンロードしておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.atlassian.com/software/confluence/ConfluenceDownloadCenter.jspa"&gt;Download Wiki Software - Confluence Enterprise Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記サイトの右側にある “Show all” をクリックし、全てのダウンロード可能なファイルを表示させ、&lt;code&gt;Confluence 3.5.5 - EAR/WAR (TAR.GZ Archive)&lt;/code&gt; をダウンロードする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-download-w500.png" alt="confluence-download" /&gt;&lt;/p&gt;

&lt;h4 id="section-2"&gt;事前準備&lt;/h4&gt;

&lt;p&gt;今回 &lt;a href="http://www.turnkeylinux.org/tomcat"&gt;Virtual Applicace Standalone Tomcat Appliance&lt;/a&gt; のアプライアンスをベースとするので、サイトからアプライアンスライブラリをダウンロードし、仮想環境上に作成しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/turnkeylinux-standalone-tomcat-w500.png" alt="turnkeylinux-standalone-tomcat" /&gt;&lt;/p&gt;

&lt;p&gt;ここでは仮想環境上にアプライアンスをインストールする手順は割愛する。今回使用するアプライアンスライブラリではないが、過去 Redmine の環境を構築した際のメモがあるので参照のこと。&lt;br /&gt;
(大枠の手順は変わらない)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="/2011/01/22/turnkey-redmine-virtualbox-1/"&gt;手間要らずでプロジェクト管理ツール Redmine を導入する - VirtualBox 編 (その1)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ここから先は既に上記の仮想アプライアンスのインストールは完了しているものとして記述する。&lt;/p&gt;

&lt;p&gt;今回の構築時には、追加で以下の2点を実施しておく。&lt;br /&gt;
作業内容はそれぞれのページを参照のこと。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ロケールとタイムゾーンの変更
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="/2011/06/04/ubuntu-initial-setup-locale-timezone/"&gt;Ubuntuサーバ日本向け環境の初期設定 - ロケールとタイムゾーン&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Java 環境を OpenJDK から Sun Java へ変更 (Confluence は OpenJDK を正式にサポートしていない模様)
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="/2011/06/05/turnkey-linux-tomcat-from-openjdk-to-sunjdk/"&gt;Ubuntu(TurnKey Linux) で Java 環境を OpenJDK ではなく Sun Java をデフォルトに + Tomcat も&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;で、さらに Java 環境絡みで実施しておく必要がある。仮想OSが使用できるメモリと Java が利用するメモリに関してになる。&lt;/p&gt;

&lt;p&gt;デフォルトの設定のままではメモリが足りず、インストールがハングってしまうことになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;仮想 OS には 1G over のメモリは割り当てておく&lt;/li&gt;
  &lt;li&gt;Java 環境では、ヒープの Max は 1G、Permanent 領域も 256M くらいは必要&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;にはしておいた方がよい。&lt;/p&gt;

&lt;p&gt;Java 環境の変更に関しては &lt;code&gt;/etc/init.d/tomcat6&lt;/code&gt; で変更を行っておく。&lt;code&gt;JAVA_OPTS&lt;/code&gt; に設定を追加。以下のように変更を加えた。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# git diff b4119c5 9f7a1a5 tomcat6
diff --git a/init.d/tomcat6 b/init.d/tomcat6
index 7b31300..575967b 100755
--- a/init.d/tomcat6
+++ b/init.d/tomcat6
@@ -79,7 +79,7 @@ TOMCAT6_SECURITY=no
 # It also looks like the default heap size of 64M is not enough for most cases
 # so the maximum heap size is set to 128M
 if [ -z "$JAVA_OPTS" ]; then
-       JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
+       JAVA_OPTS="-Djava.awt.headless=true -Xms128M -Xmx1024M -XX:MaxPermSize=256M"
 fi
 
 # End of variables that can be overwritten in $DEFAULT
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ちなみに、Standalone 版を確認してみたところ、&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;JAVA_OPTS="-Xms256m -Xmx512m -XX:MaxPermSize=256m $JAVA_OPTS -Djava.awt.headless=true "
export JAVA_OPTS
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;となっていた。&lt;/p&gt;

&lt;h3 id="confluence-"&gt;Confluence のインストール&lt;/h3&gt;

&lt;h4 id="confluence--confluence-"&gt;Confluence の設定ファイルに Confluence ホームディレクトリの設定&lt;/h4&gt;

&lt;p&gt;Confluence のインストール時には、以下2つのディレクトリを意識しておく必要がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ホームディレクトリ&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;先にダウンロードしていた &lt;code&gt;confluence-3.5.5.tar.gz&lt;/code&gt; を &lt;code&gt;/opt/atlassian&lt;/code&gt; 配下に展開し、&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;は、&lt;code&gt;/opt/atlassian/confluence&lt;/code&gt; とすることにして、シンボリックリンクをはっておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# ln -s /opt/atlassian/confluence-3.5.5 /opt/atlassian/confluence
# cd /opt/atlassian/
# ls -l
total 4
lrwxrwxrwx  1 root root   35 2011-06-05 13:27 confluence -&amp;gt; /opt/atlassian/confluence-3.5.5
drwxr-xr-x 11 root root 4096 2011-06-05 13:19 confluence-3.5.5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ホームディレクトリは、&lt;code&gt;/opt/atlassian/confluence-data&lt;/code&gt; としておく。&lt;/p&gt;

&lt;p&gt;Tomcat サーバは tomcat6 ユーザで動作するので、ホームディレクトリと念の為インストールディレクトリもパーミッションの変更を行っておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# chown -R tomcat6:tomcat6 /opt/atlassian/confluence-data
# chown -R tomcat6:tomcat6 /opt/atlassian/confluence-3.5.5 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ホームディレクトリの位置を Confluence の設定に反映しておく。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties&lt;/code&gt;の &lt;code&gt;confluence.home&lt;/code&gt; の値を上記で決めたディレクトリに指定しておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;confluence.home=/opt/atlassian/confluence-data
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="db-"&gt;DB の設定&lt;/h4&gt;

&lt;p&gt;評価目的であれば内蔵の DB を使えばよいのだが、DB 環境含めての評価を行っておきたいので MySQL への接続設定を行う。以下のページが参考になる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/DOC/Database+Setup+For+MySQL"&gt;Database Setup For MySQL - Confluence 3.5 - Atlassian Documentation - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記に記載のある MySQL の設定ファイル &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt; の設定を追記+変更しておく。以下は変更点。&lt;br /&gt;
全て&lt;code&gt;[mysqld]&lt;/code&gt; セクション内になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# git diff b4119c53 9f7a1a5 my.cnf
diff --git a/mysql/my.cnf b/mysql/my.cnf
index 92b55c2..9e0be08 100644
--- a/mysql/my.cnf
+++ b/mysql/my.cnf
@@ -46,6 +46,16 @@ basedir              = /usr
 datadir                = /var/lib/mysql
 tmpdir         = /tmp
 skip-external-locking
+
+# add
+default-collation=utf8_bin
+character-set-server=utf8
+collation-server=utf8_bin
+default-character-set=utf8
+
+default-storage-engine=INNODB
+
+transaction-isolation=READ-COMMITTED
 #
 # Instead of skip-networking the default is now to listen only on
 # localhost which is more compatible and is not less secure.
@@ -54,7 +64,7 @@ bind-address          = 127.0.0.1
 # * Fine Tuning
 #
 key_buffer             = 16M
-max_allowed_packet     = 16M
+max_allowed_packet     = 32M
 thread_stack           = 192K
 thread_cache_size       = 8
 # This replaces the startup script and checks MyISAM tables if needed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設定変更後、MySQL の再起動をかけておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# service mysql restart
mysql start/running, process 8088
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Confluence で使用するデータベースの作成、接続ユーザの作成を行っておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.1.41-3ubuntu12.8 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&amp;gt; CREATE DATABASE confluence;
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; GRANT ALL PRIVILEGES ON confluence.* TO 'confluenceuser'@'localhost' IDENTIFIED BY 'confluencepass';
Query OK, 0 rows affected (0.03 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記のデータベースのユーザ名(confluenceuser)パスワード(confluencepass)は一例。適切なものに変更して入力を行うこと。&lt;/p&gt;

&lt;p&gt;DB は以上。&lt;/p&gt;

&lt;h4 id="tomcat-"&gt;Tomcat の設定&lt;/h4&gt;

&lt;p&gt;Tomcat の設定ファイルに先ほど配置した Confluence を Web アプリケーションとして認識させるための設定を追加しておく。&lt;/p&gt;

&lt;p&gt;Tomcat の設定ファイルは、通常 Tomcat のインストールディレクトリの &lt;code&gt;conf/Catalina/localhost&lt;/code&gt; に配置するが、今回使用している TurnKey Linux での該当ディレクトリは &lt;code&gt;/etc/tomcat6/Catalina/localhost&lt;/code&gt; になる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/tomcat6/Catalina/localhost/confluence.xml&lt;/code&gt; ファイルを作成し、以下の記述を行う。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;confluence.xml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;&amp;lt;Context path="/confluence"
         docBase="/opt/atlassian/confluence/confluence"
         debug="0"
         reloadable="true" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;docBase&lt;/code&gt; には先に&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;として決めたパス配下の confluence ディレクトリを設定している。&lt;/p&gt;

&lt;p&gt;Tomcat の再起動を行う。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# service tomcat6 restart
 * Stopping Tomcat servlet engine tomcat6
   ...done.
 * Starting Tomcat servlet engine tomcat6
   ...done.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で Tomcat の設定は完了。上記の起動時に妙なエラーが出ていなければまずは OK。&lt;/p&gt;

&lt;h4 id="web-"&gt;Web 画面からの設定&lt;/h4&gt;

&lt;p&gt;ここから先はブラウザで &lt;code&gt;http://&amp;lt;server host&amp;gt;/confluence&lt;/code&gt; にアクセスし、残りの設定を Web の画面から行う。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-1-w500.png" alt="confluence-install-setup-1" /&gt;&lt;/p&gt;

&lt;p&gt;まずはライセンスファイルの情報が必要になる。&lt;/p&gt;

&lt;p&gt;上記ページの “generate an evaluation license online” をクリックすることで、My Atlassian のログイン画面に遷移するので、ログインを行う。&lt;br /&gt;
(アカウントをまだ作成していない場合はアカウントを先に作成する)&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/my-atlassian-login-w500.png" alt="ログイン - My Atlassian" /&gt;&lt;/p&gt;

&lt;p&gt;ログイン後のページに必要な項目が引き継がれた状態で表示されるので、”ライセンスの生成”をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-2-w500.png" alt="confluence-install-setup-2" /&gt;&lt;/p&gt;

&lt;p&gt;うまいことページが Redidirect される仕組みになっていて、先に表示されていたライセンス入力画面にライセンスキーが入力された状態で戻ってくる。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-3-w500.png" alt="confluence-install-setup-3" /&gt;&lt;/p&gt;

&lt;p&gt;外部のデータベースを使用するので、”Production Installation” をクリックし、次のページに進む。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-4-w500.png" alt="confluence-install-setup-4" /&gt;&lt;/p&gt;

&lt;p&gt;今回 MySQL を使うので、”External Database” で “MySQL” を選択し、”External Database” をクリックし次のページに進む。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-5-w500.png" alt="confluence-install-setup-5" /&gt;&lt;/p&gt;

&lt;p&gt;Web アプリケーションサーバのデータソースは使わずに直接つなぐので、”Direct JDBC” をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-6-w500.png" alt="confluence-install-setup-6" /&gt;&lt;/p&gt;

&lt;p&gt;“Driver Class Name” はそのままとし、Database URL には、表示されている文字列の最後に &lt;code&gt;&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8&lt;/code&gt; を追加してあげる。全文字列は以下の文字列になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;jdbc:mysql://localhost/confluence?autoReconnect=true&amp;amp;sessionVariables=storage_engine%3DInnoDB&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;もし、データベース名を confluence とは異なる名前にしていた場合には、適宜変更しておく。&lt;/p&gt;

&lt;p&gt;また、DB の設定時に作成した confluence データベースに接続を行うユーザ名とそのパスワードを入力して “Next” をクリックする。&lt;/p&gt;

&lt;p&gt;この後データベースへのスキーマ作成などいろいろな作業が走るのでしばし時間をおいた後に次の画面に遷移する。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-7-w500.png" alt="confluence-install-setup-7" /&gt;&lt;/p&gt;

&lt;p&gt;Example サイトがあった方がとっつきやすくなるので、”Example Site” をクリックする。&lt;/p&gt;

&lt;p&gt;この後、”Create administrator” 画面へと遷移し、Administrator アカウントを作成した後にセットアップが完了となる。&lt;br /&gt;
(画面のスクリーンショットを撮り忘れ。。)&lt;/p&gt;

&lt;p&gt;以上でインストール作業は完了となる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://&amp;lt;server host&amp;gt;/confluence&lt;/code&gt; にアクセスすると Confluence が利用可能となっている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-last-w500.png" alt="confluence-install-setup-last" /&gt;&lt;/p&gt;

&lt;p&gt;この状態ではコンテツの日本化はされていない。一部の日本語入力においても問題がある。この後日本語化を行う。次回に続く。&lt;/p&gt;

&lt;p&gt;待ちきれない場合は、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.ricksoft.jp/document/pages/viewpage.action?pageId=77332576"&gt;Confluenceの日本語化 - インストール手順 - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;を参照のこと。&lt;/p&gt;
</content>
    <summary type="html">&lt;p&gt;Wiki のツールを調べており、Atlassian の Confluence を試してみることにした。そのインストールメモ。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.atlassian.com/ja_JP/software/confluence/"&gt;エンタープライズ コラボレーションおよび Wiki ソフトウェア - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/atlassian-confluence-w500.png" alt="atlassian-confluence" /&gt;&lt;/p&gt;

&lt;p&gt;まずは評価目的で試してみる。以下の構成でインストールする。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ベースとなる OS は仮想環境上にのせる。TurnKey Linux の提供する &lt;a href="http://www.turnkeylinux.org/tomcat"&gt;Virtual Applicace Standalone Tomcat Appliance&lt;/a&gt; を使う。
    &lt;ul&gt;
      &lt;li&gt;この環境は、Java 環境、Tomcat サーバ、MySQL 5.1 がすでに利用可能な環境となる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Confluence は Standalone ではなく WAR バージョンを既存の Tomcat 環境にインストールする&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;インストールの手順は、以下のドキュメントを参考に行う。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/DOC/Installing+the+Confluence+EAR-WAR+Edition"&gt;Installing the Confluence EAR-WAR Edition - Confluence 3.5 - Atlassian Documentation - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="section"&gt;事前に用意するものと事前準備&lt;/h3&gt;

&lt;h4 id="section-1"&gt;用意するもの&lt;/h4&gt;

&lt;p&gt;まず、Confluence のインストールに必要なものは以下の2点。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Confluence のインストール用ファイル&lt;/li&gt;
  &lt;li&gt;ライセンス&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ライセンスファイルはインストール途中で取得するので、まずはインストールに必要なファイルをダウンロードしておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.atlassian.com/software/confluence/ConfluenceDownloadCenter.jspa"&gt;Download Wiki Software - Confluence Enterprise Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記サイトの右側にある “Show all” をクリックし、全てのダウンロード可能なファイルを表示させ、&lt;code&gt;Confluence 3.5.5 - EAR/WAR (TAR.GZ Archive)&lt;/code&gt; をダウンロードする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-download-w500.png" alt="confluence-download" /&gt;&lt;/p&gt;

&lt;h4 id="section-2"&gt;事前準備&lt;/h4&gt;

&lt;p&gt;今回 &lt;a href="http://www.turnkeylinux.org/tomcat"&gt;Virtual Applicace Standalone Tomcat Appliance&lt;/a&gt; のアプライアンスをベースとするので、サイトからアプライアンスライブラリをダウンロードし、仮想環境上に作成しておく。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/turnkeylinux-standalone-tomcat-w500.png" alt="turnkeylinux-standalone-tomcat" /&gt;&lt;/p&gt;

&lt;p&gt;ここでは仮想環境上にアプライアンスをインストールする手順は割愛する。今回使用するアプライアンスライブラリではないが、過去 Redmine の環境を構築した際のメモがあるので参照のこと。&lt;br /&gt;
(大枠の手順は変わらない)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="/2011/01/22/turnkey-redmine-virtualbox-1/"&gt;手間要らずでプロジェクト管理ツール Redmine を導入する - VirtualBox 編 (その1)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ここから先は既に上記の仮想アプライアンスのインストールは完了しているものとして記述する。&lt;/p&gt;

&lt;p&gt;今回の構築時には、追加で以下の2点を実施しておく。&lt;br /&gt;
作業内容はそれぞれのページを参照のこと。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ロケールとタイムゾーンの変更
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="/2011/06/04/ubuntu-initial-setup-locale-timezone/"&gt;Ubuntuサーバ日本向け環境の初期設定 - ロケールとタイムゾーン&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Java 環境を OpenJDK から Sun Java へ変更 (Confluence は OpenJDK を正式にサポートしていない模様)
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="/2011/06/05/turnkey-linux-tomcat-from-openjdk-to-sunjdk/"&gt;Ubuntu(TurnKey Linux) で Java 環境を OpenJDK ではなく Sun Java をデフォルトに + Tomcat も&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;で、さらに Java 環境絡みで実施しておく必要がある。仮想OSが使用できるメモリと Java が利用するメモリに関してになる。&lt;/p&gt;

&lt;p&gt;デフォルトの設定のままではメモリが足りず、インストールがハングってしまうことになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;仮想 OS には 1G over のメモリは割り当てておく&lt;/li&gt;
  &lt;li&gt;Java 環境では、ヒープの Max は 1G、Permanent 領域も 256M くらいは必要&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;にはしておいた方がよい。&lt;/p&gt;

&lt;p&gt;Java 環境の変更に関しては &lt;code&gt;/etc/init.d/tomcat6&lt;/code&gt; で変更を行っておく。&lt;code&gt;JAVA_OPTS&lt;/code&gt; に設定を追加。以下のように変更を加えた。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# git diff b4119c5 9f7a1a5 tomcat6
diff --git a/init.d/tomcat6 b/init.d/tomcat6
index 7b31300..575967b 100755
--- a/init.d/tomcat6
+++ b/init.d/tomcat6
@@ -79,7 +79,7 @@ TOMCAT6_SECURITY=no
 # It also looks like the default heap size of 64M is not enough for most cases
 # so the maximum heap size is set to 128M
 if [ -z "$JAVA_OPTS" ]; then
-       JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
+       JAVA_OPTS="-Djava.awt.headless=true -Xms128M -Xmx1024M -XX:MaxPermSize=256M"
 fi
 
 # End of variables that can be overwritten in $DEFAULT
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ちなみに、Standalone 版を確認してみたところ、&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;JAVA_OPTS="-Xms256m -Xmx512m -XX:MaxPermSize=256m $JAVA_OPTS -Djava.awt.headless=true "
export JAVA_OPTS
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;となっていた。&lt;/p&gt;

&lt;h3 id="confluence-"&gt;Confluence のインストール&lt;/h3&gt;

&lt;h4 id="confluence--confluence-"&gt;Confluence の設定ファイルに Confluence ホームディレクトリの設定&lt;/h4&gt;

&lt;p&gt;Confluence のインストール時には、以下2つのディレクトリを意識しておく必要がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ホームディレクトリ&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;先にダウンロードしていた &lt;code&gt;confluence-3.5.5.tar.gz&lt;/code&gt; を &lt;code&gt;/opt/atlassian&lt;/code&gt; 配下に展開し、&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;は、&lt;code&gt;/opt/atlassian/confluence&lt;/code&gt; とすることにして、シンボリックリンクをはっておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# ln -s /opt/atlassian/confluence-3.5.5 /opt/atlassian/confluence
# cd /opt/atlassian/
# ls -l
total 4
lrwxrwxrwx  1 root root   35 2011-06-05 13:27 confluence -&amp;gt; /opt/atlassian/confluence-3.5.5
drwxr-xr-x 11 root root 4096 2011-06-05 13:19 confluence-3.5.5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ホームディレクトリは、&lt;code&gt;/opt/atlassian/confluence-data&lt;/code&gt; としておく。&lt;/p&gt;

&lt;p&gt;Tomcat サーバは tomcat6 ユーザで動作するので、ホームディレクトリと念の為インストールディレクトリもパーミッションの変更を行っておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# chown -R tomcat6:tomcat6 /opt/atlassian/confluence-data
# chown -R tomcat6:tomcat6 /opt/atlassian/confluence-3.5.5 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ホームディレクトリの位置を Confluence の設定に反映しておく。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties&lt;/code&gt;の &lt;code&gt;confluence.home&lt;/code&gt; の値を上記で決めたディレクトリに指定しておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;confluence.home=/opt/atlassian/confluence-data
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="db-"&gt;DB の設定&lt;/h4&gt;

&lt;p&gt;評価目的であれば内蔵の DB を使えばよいのだが、DB 環境含めての評価を行っておきたいので MySQL への接続設定を行う。以下のページが参考になる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/DOC/Database+Setup+For+MySQL"&gt;Database Setup For MySQL - Confluence 3.5 - Atlassian Documentation - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上記に記載のある MySQL の設定ファイル &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt; の設定を追記+変更しておく。以下は変更点。&lt;br /&gt;
全て&lt;code&gt;[mysqld]&lt;/code&gt; セクション内になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# git diff b4119c53 9f7a1a5 my.cnf
diff --git a/mysql/my.cnf b/mysql/my.cnf
index 92b55c2..9e0be08 100644
--- a/mysql/my.cnf
+++ b/mysql/my.cnf
@@ -46,6 +46,16 @@ basedir              = /usr
 datadir                = /var/lib/mysql
 tmpdir         = /tmp
 skip-external-locking
+
+# add
+default-collation=utf8_bin
+character-set-server=utf8
+collation-server=utf8_bin
+default-character-set=utf8
+
+default-storage-engine=INNODB
+
+transaction-isolation=READ-COMMITTED
 #
 # Instead of skip-networking the default is now to listen only on
 # localhost which is more compatible and is not less secure.
@@ -54,7 +64,7 @@ bind-address          = 127.0.0.1
 # * Fine Tuning
 #
 key_buffer             = 16M
-max_allowed_packet     = 16M
+max_allowed_packet     = 32M
 thread_stack           = 192K
 thread_cache_size       = 8
 # This replaces the startup script and checks MyISAM tables if needed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;設定変更後、MySQL の再起動をかけておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# service mysql restart
mysql start/running, process 8088
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Confluence で使用するデータベースの作成、接続ユーザの作成を行っておく。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.1.41-3ubuntu12.8 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&amp;gt; CREATE DATABASE confluence;
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; GRANT ALL PRIVILEGES ON confluence.* TO 'confluenceuser'@'localhost' IDENTIFIED BY 'confluencepass';
Query OK, 0 rows affected (0.03 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上記のデータベースのユーザ名(confluenceuser)パスワード(confluencepass)は一例。適切なものに変更して入力を行うこと。&lt;/p&gt;

&lt;p&gt;DB は以上。&lt;/p&gt;

&lt;h4 id="tomcat-"&gt;Tomcat の設定&lt;/h4&gt;

&lt;p&gt;Tomcat の設定ファイルに先ほど配置した Confluence を Web アプリケーションとして認識させるための設定を追加しておく。&lt;/p&gt;

&lt;p&gt;Tomcat の設定ファイルは、通常 Tomcat のインストールディレクトリの &lt;code&gt;conf/Catalina/localhost&lt;/code&gt; に配置するが、今回使用している TurnKey Linux での該当ディレクトリは &lt;code&gt;/etc/tomcat6/Catalina/localhost&lt;/code&gt; になる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/tomcat6/Catalina/localhost/confluence.xml&lt;/code&gt; ファイルを作成し、以下の記述を行う。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;confluence.xml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;&amp;lt;Context path="/confluence"
         docBase="/opt/atlassian/confluence/confluence"
         debug="0"
         reloadable="true" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;docBase&lt;/code&gt; には先に&lt;strong&gt;インストールディレクトリ&lt;/strong&gt;として決めたパス配下の confluence ディレクトリを設定している。&lt;/p&gt;

&lt;p&gt;Tomcat の再起動を行う。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;# service tomcat6 restart
 * Stopping Tomcat servlet engine tomcat6
   ...done.
 * Starting Tomcat servlet engine tomcat6
   ...done.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上で Tomcat の設定は完了。上記の起動時に妙なエラーが出ていなければまずは OK。&lt;/p&gt;

&lt;h4 id="web-"&gt;Web 画面からの設定&lt;/h4&gt;

&lt;p&gt;ここから先はブラウザで &lt;code&gt;http://&amp;lt;server host&amp;gt;/confluence&lt;/code&gt; にアクセスし、残りの設定を Web の画面から行う。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-1-w500.png" alt="confluence-install-setup-1" /&gt;&lt;/p&gt;

&lt;p&gt;まずはライセンスファイルの情報が必要になる。&lt;/p&gt;

&lt;p&gt;上記ページの “generate an evaluation license online” をクリックすることで、My Atlassian のログイン画面に遷移するので、ログインを行う。&lt;br /&gt;
(アカウントをまだ作成していない場合はアカウントを先に作成する)&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/my-atlassian-login-w500.png" alt="ログイン - My Atlassian" /&gt;&lt;/p&gt;

&lt;p&gt;ログイン後のページに必要な項目が引き継がれた状態で表示されるので、”ライセンスの生成”をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-2-w500.png" alt="confluence-install-setup-2" /&gt;&lt;/p&gt;

&lt;p&gt;うまいことページが Redidirect される仕組みになっていて、先に表示されていたライセンス入力画面にライセンスキーが入力された状態で戻ってくる。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-3-w500.png" alt="confluence-install-setup-3" /&gt;&lt;/p&gt;

&lt;p&gt;外部のデータベースを使用するので、”Production Installation” をクリックし、次のページに進む。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-4-w500.png" alt="confluence-install-setup-4" /&gt;&lt;/p&gt;

&lt;p&gt;今回 MySQL を使うので、”External Database” で “MySQL” を選択し、”External Database” をクリックし次のページに進む。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-5-w500.png" alt="confluence-install-setup-5" /&gt;&lt;/p&gt;

&lt;p&gt;Web アプリケーションサーバのデータソースは使わずに直接つなぐので、”Direct JDBC” をクリックする。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-6-w500.png" alt="confluence-install-setup-6" /&gt;&lt;/p&gt;

&lt;p&gt;“Driver Class Name” はそのままとし、Database URL には、表示されている文字列の最後に &lt;code&gt;&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8&lt;/code&gt; を追加してあげる。全文字列は以下の文字列になる。&lt;/p&gt;

&lt;pre class="shell"&gt;&lt;code class="language-shell"&gt;jdbc:mysql://localhost/confluence?autoReconnect=true&amp;amp;sessionVariables=storage_engine%3DInnoDB&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;もし、データベース名を confluence とは異なる名前にしていた場合には、適宜変更しておく。&lt;/p&gt;

&lt;p&gt;また、DB の設定時に作成した confluence データベースに接続を行うユーザ名とそのパスワードを入力して “Next” をクリックする。&lt;/p&gt;

&lt;p&gt;この後データベースへのスキーマ作成などいろいろな作業が走るのでしばし時間をおいた後に次の画面に遷移する。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-7-w500.png" alt="confluence-install-setup-7" /&gt;&lt;/p&gt;

&lt;p&gt;Example サイトがあった方がとっつきやすくなるので、”Example Site” をクリックする。&lt;/p&gt;

&lt;p&gt;この後、”Create administrator” 画面へと遷移し、Administrator アカウントを作成した後にセットアップが完了となる。&lt;br /&gt;
(画面のスクリーンショットを撮り忘れ。。)&lt;/p&gt;

&lt;p&gt;以上でインストール作業は完了となる。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://&amp;lt;server host&amp;gt;/confluence&lt;/code&gt; にアクセスすると Confluence が利用可能となっている。&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/ubuntu/confluence-install-setup-last-w500.png" alt="confluence-install-setup-last" /&gt;&lt;/p&gt;

&lt;p&gt;この状態ではコンテツの日本化はされていない。一部の日本語入力においても問題がある。この後日本語化を行う。次回に続く。&lt;/p&gt;

&lt;p&gt;待ちきれない場合は、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.ricksoft.jp/document/pages/viewpage.action?pageId=77332576"&gt;Confluenceの日本語化 - インストール手順 - Confluence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;を参照のこと。&lt;/p&gt;
</summary>
  </entry>
</feed>

