Drowsy Dog's Diary

any note, any thought

2014年2月4日
by kazoo
0 comments

[rails]アセットパイプラインのためのApache最適化設定

アセットパイプライン

「アセット」とは Web サーバ上の静的コンテンツのこと。具体的には、画像、CSS、Javascript などのファイル。

アセットパイプラインはバージョン3.1以降の Rails に備わっている機能で、主な役目はアセットを圧縮・結合すること、そしてファイルのフィンガープリントをファイル名に組込むこと。この2つの操作を「コンパイル」と呼んでいる。

は、アセットをコンパイルするコマンド。
app/assets/images/
app/assets/stylesheets/
app/assets/javascripts/
app/assets/fonts/

などにあるファイルが「プリコンパイル」される。

コンパイルによって、 app/assets/images/ 以下の画像ファイルには MD5 ハッシュをファイル名に付加して /public/assets/ にコピー。また CSS/JS は、それぞれの拡張子(.scss, .erb, .coffee など)に応じた方法でファイルが変換され、CSS や JS ごとの結合が行われた後、Minification(空白、改行、コメントの除去等)された後に gzip 圧縮される。

このようにすることで、アセットの通信量を最小化しつつ、ファイルの中身の変化に応じてファイル名自体が変わるので、ブラウザやプロキシサーバにキャッシュされていても古いファイルが替わらないという問題を避けられる。むしろ /assets/ 以下の URI へのアクセスに関しては、出来る限りキャッシュを推奨するのが望ましい。そのための HTTP リクエスト/レスポンスのヘッダ設定が以下のようになる。

キャッシュ設定

ここでは CentOS 想定。設定ファイルパス、URI は適当に読み替えてください。

/etc/httpd/sites-available/my_site

それぞれの意味はこんな感じ。

  • ExpiresActive… On にすると Expires および Cache-Control ヘッダを生成する
  • ExpiresDefault… Expires に設定するデフォルトの値。ここではアクセス日時+30日間
  • Header set Cache-Control… HTTP ヘッダの Cache-Control の値を上書きする。”public” は、ブラウザだけでなく Web プロクシにもキャッシュを許可する
  • Header unset Etag… HTTP ヘッダの ETag を削除する(レスポンスが ETag ヘッダを持たないようにする

圧縮設定

アセットパイプラインにおける CSS ファイルなどは圧縮・結合された上で /public/assets/ に配置される。そのとき、*.css, *.css.gz の2つのファイルが生成される。ミニフィケーションと結合だけが行われたものと、それをさらに gzip したもの。

現在多くの Web ブラウザでは、gzip形式で圧縮されたコンテンツをサーバから受け取って、それを展開してからレンダリングする機能を持っている。そういったブラウザは、Accept-Encoding リクエストヘッダに gzip あるいは x-gzip という文字を含む値をセットする。これを受け取った Apache や Nginx といった Web サーバは、その場でコンテンツを圧縮して送り返す。

しかし、アセットパイプラインを利用している場合はすでに圧縮されたファイルが存在しているので、この圧縮は CPU の無駄となる。なので、すでに圧縮済みのファイルを利用するような設定が以下となる。

/etc/httpd/sites-available/my_site

  • AddEncoding… 拡張子 .gz のファイルのエンコーディングが x-zip だと指定する。
  • Header set Vary Accept-Encodig… Vary ヘッダは、リクエストのヘッダによってレスポンスが変化することと、その基準となるリクエストヘッダを Web プロクシに教える。これによってたとえば gzip 圧縮に対応しているブラウザとしていないブラウザが同一のプロクシにアクセスしても問題が出ないようにできる
  • RewriteEngine on/RewriteCond… Accept-Encodingヘッダに gzip/x-gzip という文字を含むリクエストで、かつ末尾に .gz を加えた URI に対応するファイルが存在する場合、それを返す
  • <FilesMatch>…. 拡張子 .css.gz および .js.gz の MIME タイプを ForceType ディレクティブによって指定する

2013年6月12日
by kazoo
0 comments

Redmineサーバの移行

ローカルの Ubuntu 12.04 + nginx + unicorn + mysql で運用していた Redmine を、
クラウドの Ubuntu 12.04 + apache2 + mysql 環境に移してくれというご依頼。

結論から言うと「Redmine の rails フォルダをまるっとコピー」で済ませたのですが。

その前にいろいろやってみたことメモ。
自分用。

Passenger

移行先はほぼクリーンだけど、すでに Apache + MySQL で社内ドキュメント Wiki みたいなのが動いていた。
ので、nginx 共存よりは Apache + Passenger がいいのかな、ということで。導入お勉強。

rbenv

いらんかもしれんけど、システムワイドな .rbenv を入れてみる。
参考:http://qiita.com/items/8e973a544b592376a07e

ここで dev は全員が所属しているグループ名。

各員、.bashrc などに以下を記述しておく。

ruby-build をインストール。

ruby1.93 をインストール。

OK.

apache2 + passenger

Apache2関連モジュールと Passenger のインストール。

このとき足りないパッケージがあれば passenger が教えてくれる。
apache2 の conf に書く内容も教えてくれる。

ということで、この3行を、
/etc/apache2/sites-available/redmine
としてコピー。

Redmine(略)

http://madroom-project.blogspot.jp/2012/12/ubuntu-1204redmine-220apache.html
Ubuntu + Apache + Passenger + Redmine は、ほぼこちらの内容で OK でした。感謝。

あとは database.yml と configuration.yml を現状に合わせて、とりあえず新環境での Redmine 稼働は OK。バージョンは 2.2.0。

データ移行

さて、MySQL データ移行。
DBよく知らないけどたぶん export して import すればいいんだろー、と思ってぐぐってやってみた。
http://fmkt.blog65.fc2.com/blog-entry-7.html
http://napzak.com/tips/?MySQL%E3%81%AE%E3%83%80%E3%83%B3%E3%83%97%EF%BC%88%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%EF%BC%89%E3%80%81%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E3%80%81%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97
mysqldumpを使う。ふむふむ。

旧サーバで、

引越し先で

結局

おお。あっさりコピーできた。。と、ぱっと見は思ったのだけど、いざ既存のチケットを操作しようとするとエラーが出たりして、不整合があるらしい。何度かやってみるも結局そこで時間切れ。

最終的には旧 Redmine の rails 環境をそのまま /usr/local/redmine-old に持って来て、

してしまいました。やや不完全燃焼。。。