rails + lighttpd でCSS が読み込めなくてはまった

rails + lighttpd でアプリを動かしてみたのですが、アクセスしたらCSS が読み込めなくて少しはまった。ということで、対応方法をメモ。すごい基本的なことだったんですけどね(ノд`)

環境

lighttpd.conf(問題あり版)

var.basedir = "/home/myuser/myapp/"

server.port = 3000

server.modules           = ( "mod_rewrite", "mod_alias", "mod_access", "mod_fastcgi", "mod_accesslog" )
server.error-handler-404 = "/dispatch.fcgi"
server.document-root     = var.basedir + "public/"

server.pid-file          = "/var/run/lighttpd.pid"

url.rewrite              = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )

server.errorlog          = var.basedir + "log/lighttpd.error.log"
accesslog.filename       = var.basedir + "log/lighttpd.access.log"

fastcgi.server = ( ".fcgi" =>
  ( "localhost" =>
      (
        "min-procs" => 1, 
        "max-procs" => 10,
        "socket"    => var.basedir + "log/fcgi.socket",
        "bin-path"  => var.basedir + "public/dispatch.fcgi",
        "bin-environment" => ( "RAILS_ENV" => "development" )
      )
  )
)

起動

$ sudo lighttpd -f /etc/lighttpd/lighttpd.conf


この状態でアクセスすると、ページは表示されるのですが、CSS が適応されない。

解決方法と原因

MYME-Type を明示的に指定していないのが原因だった。lighttpd.conf の最後でMIME-Type を指定してやればおk。

・・・

fastcgi.server = ( ".fcgi" =>
  ( "localhost" =>
      (
        "min-procs" => 1, 
        "max-procs" => 10,
        "socket"    => var.basedir + "log/fcgi.socket",
        "bin-path"  => var.basedir + "public/dispatch.fcgi",
        "bin-environment" => ( "RAILS_ENV" => "development" )
      )
  )
)

# 以下を追加
mimetype.assign = (
  ".css"        =>  "text/css",
  ".gif"        =>  "image/gif",
  ".htm"        =>  "text/html",
  ".html"       =>  "text/html",
  ".jpeg"       =>  "image/jpeg",
  ".jpg"        =>  "image/jpeg",
  ".js"         =>  "text/javascript",
  ".png"        =>  "image/png",
  ".swf"        =>  "application/x-shockwave-flash",
  ".txt"        =>  "text/plain",
  ".xml"        =>  "application/xml"
)
原因

rails とは全然関係なかったです。さっきも書いた通りMIME-Type が原因。あとは、アクセスに使ったブザウザがFirefox だったのが原因。

Firefoxのソースを読んでみると、ソース中でFirefox内部で処理するMIME-Typeがハードコーディングされてて、それ以外のMIME-TypeのやつはFirefoxでは処理できないからダウンロードしてるような雰囲気。


Firefox は、ソース内で定義されていないMIME-Type でデータが送られてくると、それをDL する。しかも、DL するのは直接ファイルを指定した場合っぽい。CSS のようにHTML ファイルから参照されてた場合は、処理できないので何も起らない。よって反映されないという感じ。

  • 検証

LiveHttpHeaders を用いてCSS ファイルを直接指定してみると、MIME-Type は「application/octet-stream」になっていた。application/octet-stream というのは特定のファイルをあらわすものではないので、そのままDL になってしまいました。
Safari でアクセスしたら、修正前のlighttpd.conf のままでもいけました。SafariIEMIME-Type でなく、ファイルの拡張子からファイル形式を判定して処理する模様。
「".css" => "text/css"」というマッピングをしてやることで、MIME-Type がきちんと指定されて送られてくるので、ファイルのパスを直接たたくと、ダウンロードでなく、きちんとブラウザ上でCSS ファイルが閲覧できました。