«前の日記(2013-12-28) 最新 次の日記(2013-12-30)» 編集

いがいが日記


2013-12-29 [長年日記]

_ いがいが日記の環境を nginx + unicorn へ

ここまでApache + CGI(!)で動いてきたこの日記、時間ができたので nginx + unicorn で動作するようにした。 unicorn がtdiary を8080ポートでWebアプリとして起動する。nginx はそのフロントで80番ポートに来たアクセスを unicorn が待っている 8080 へつなぐことにします。

例によって @machu 先生のページを参考にした。ほとんどまちゅさんのページ通りだけど、メモも兼ねてできるだけ全部書きます。

tDiaryを Nginx + Unicorn + さくらVPSで動かした tDiaryを Nginx + Unicorn + さくらVPSで動かした(2)

また、昨日の日記に書いたようにRubyは rbenv のものを使います。

前準備

CGI時代と違ってtdiary 関連ファイルをweb公開先に置かなくていいのでホームの下へ移動した。tdiary-contrib はもしかしたらgem 化したものを使えるかもしれないけど、今まで動いてた環境が Github から clone した状態だったので、そのまま使って動かすことにした。

/var/www/ ← nginx の root にする
/home/igarashi/var/tdiary
  tdiary-core/ ← GitHubからtdiary-coreをclone
  tdiary-contrib/ ← GitHubからtdiary-contribをclone
  data/ ← tdiary のデータ置き場。日記データなどが入ってる

インストール

$ sudo apttitude install nginx 
$ gem install unicorn

Apacheを停止

$ sudo /etc/init.d/apache2 stop

tdiary と unicorn を設定

tdiary-core へ移動して以下。bundler と gem群 をインストール。

$ gem install bundler
$ bundle install  --without test development 

tdiary.conf を tdiary-core へ移動。(or サンプルをコピーしてつくる) 以下を変更。

@data_path = '/home/igarashi/var/tdiary/data'
@options['sp.path'] = [
  '/home/igarashi/var/tdiary/tdiary-core/misc/plugin',
  '/home/igarashi/var/tdiary/tdiary-contrib/plugin',
] 

config.ru を編集して、 /diary/ で動かす設定にする。 (まちゅさんのときからいろいろ整備されているので、この変更だけで大丈夫みたい。)

base_dir = '/diary'

ここまで来たらtdiaryを動かせる。まずは rackup コマンドで動かしてアクセスしてみると良い。

$ bundle exec rackup
---
Thin web server (v1.6.1 codename Death Proof)
Maximum connections set to 1024
Listening on 0.0.0.0:9292, CTRL+C to stop
---

起動したら

$ wget http://localhost:9292/diary/ -O -

って感じでアクセスしてみて日記ぽいものが出ていればOK。エラーだったら調査。(sakura で動かしているので、外からはポート制限しているので中から9292にアクセスしてます。)

私はGFMスタイルまわりでエラーが出ていたので調べたら、gem 化されて便利になってた。Gemfile に以下を追加して bundle install し直したところ解消。

gem 'tdiary-style-gfm'

また、この問題 を踏んだのでtdiaryを最新版へアップデート(git pull)。素早く修正されていてありがたい。

あと、 この辺を対応。

  • 使っている theme を tdiary-core/theme 以下へコピー
  • .htpasswd を tdiary-core 以下へコピー

unicorn で動かす

rack で確認したらunicorn で動かしてみる。

tdiary-core に unicorn の設定ファイル unicorn.conf を作成。内容はまちゅさんのページと同じ。

worker_processes 4
listen 8080, :tcp_nopush => true
pid "unicorn.pid"

stderr_path "log/unicorn.stderr.log"
stdout_path "log/unicorn.stdout.log"

preload_app true
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true

起動する(-D はデーモン化)。8080へアクセスして接続確認してみる。

$ bundle exec unicorn -c unicorn.conf -D
$ wget http://localhost:8080/diary/ -O -

停止と再起動はunicorn プロセスへシグナルを送る。プロセスのPIDは tdiary-core/unicorn.pid ファイルに書いてある。

$ cd /home/igarashi/var/tdiary/tdiary-core
$ kill -HUP `cat unicorn.pid` ← 再起動
$ kill -QUIT `cat unicorn.pid` ← 終了

nginx の設定ファイルを書く

次はnginx をフロントに立ててunicorn へ。

nginx は /etc/nginx/ 以下に設定ファイル一式が置いてある。その中の sites-available フォルダに設定ファイルを置いておいて、 sites-enabled フォルダへそのシンボリックを貼っておくと読み込まれて有効になる。 default っていう設定ファイルを外して、 igarashikuniaki.net というファイルを追加した。

/etc/nginx/sites-available/igarashikuniaki.net

upstream tdiary.unicorn {
        server localhost:8080; 
        # ↑下の方で条件に合致したものをunicorn が待っている 8080へ渡す
}

server {
        server_name  igarashikuniaki.net;
        access_log  /var/log/nginx/localhost.access.log;

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

        location ~ ^/diary/ {
                try_files $uri @unicorn;
                # ↑ RSSフィードファイルなどのため、ファイルがない時だけ以下の @unicorn 処理へ
               # $uri は nginx が提供する変数で、アクセスされたパスが入っている。
        }

        location @unicorn {
                rewrite /diary/([0-9\-]+)\.html$ /diary/index.rb?date=$1 last;
                # ↑ /diary/20131229.html を /diary/index.rb?date=20131229 へ
                proxy_pass http://tdiary.unicorn;
                # ↑⬆上の方に書いてあるupstream tdiary.unicorn へ流す
        }
}

tdiary は /diary/ で動かす想定。設定ファイルはこれでミニマムのはず。実際は トップへきたら /diary/ へ飛ばしたり、昔つかってたぽい /tdiary/ へ来てもアクセスできるように追記した。

nginx 設定ファイルを有効にする

$ sudo rm /etc/nginx/sites-enabled/default
$ sudo ln -s /etc/nginx/sites-available/igarashikuniaki.net sites-enabled/. 
$ sudo /etc/init.d/nginx restart

ちょっとはまったのが、sites-enabled/ に置くシンボリックリンクを相対パスで書いていたら全然動かなかったこと。

これで外からブラウザで接続できるはず!おつかれさまでした。

nginx 自動起動

OS起動持に nginx を起動するようにする。

$ sudo update-rc.d nginx defaults  # 自動起動

ちなみに解除はこちら

$ sudo update-rc.d -f nginx remove # 自動起動解除

現在の設定は以下で見れる。起動時のレベルに応じた /etc/rc*.d/ にファイルがあれば自動起動する仕掛け。

$ ls /etc/rc*.d/*nginx  

apache の自動起動は解除した。

$ sudo update-rc.d -f apache2 remove

Unicorn 自動起動

unicorn も nginx と同じようにOS起動時に起動させよう。ネットで調べたところ、このようなスクリプト を書けばできる。長いのでgistに置きました。これを /etc/init.d/unicorn として置けば、 $ sudo /etc/init.d/unicorn start や stop が使えるようになる。(ubuntu のお作法だと service コマンド使った方がそれらしいと思うけど慣れてるのでこっちでいいや。また、みんなで管理するなら unicorn を動かす別のユーザーを作った方がいいのだろうけど、個人用なので割愛。) うまく動くことを確認して以下で自動起動設定。

sudo update-rc.d unicorn defaults  # 自動起動
sudo update-rc.d -f unicorn remove # 自動起動解除
パフォーマンス

CGI(作業前)

$ ab -n 30 -c 3 http://igarashikuniaki.net/diary/
Requests per second:    2.01 [#/sec] (mean)
Time per request:       1494.132 [ms] (mean)
Time per request:       498.044 [ms] (mean, across all concurrent requests) 

nginx + unicorn(作業後)

$ ab -n 30 -c 3 http://igarashikuniaki.net/diary/
Requests per second:    13.60 [#/sec] (mean)
Time per request:       220.560 [ms] (mean)
Time per request:       73.520 [ms] (mean, across all concurrent requests) 

ということで1桁近く速くなりました!CGIが都度Rubyプロセスを起動しているのに対して、unicorn はプロセスを起動した状態で待っていることなどが効いているのでしょう。それでもCGIは手軽にレンサバで動かせる素晴らしい技術でした。10年間使ったなぁ。すごいです。

次は静的ファイルもnginxで返すようにしたり、tdiary の gem を使うように整備していきたいです。


«前の日記(2013-12-28) 最新 次の日記(2013-12-30)» 編集