そもそもは、GitLabのGroup Avaterがリンク切れになっていて、調査したところ、どうやらファイル自体はアップロードされているものの、ファイル自体を参照しようとすると404になってた、というのが発端です。その対応ログです。
ちなみに、
- RailsのVersion
~> 4.1.0
- Webサーバ
Apache
- Applicationサーバ
Unicorn
の構成です。
解決策1(応急処置)
対策自体は、config/environments/production.rb
の1行を、以下のように修正し、再起動するだけで解決しました。
# Disable Rails's static asset server (Apache or nginx will already do this)
- config.serve_static_assets = false
+ config.serve_static_assets = true
コメントにもあるように、基本的に、static assetsについては、ApacheやNginxのようなWebサーバが行ってくれるはずですが、なぜいけなかったのでしょうか?
原因
参考URLにある通り、どうやら、WebサーバであるApacheがpublic/uploads/*
をプロキシしても、ApplicationサーバであるUnicornが処理しないのが原因のようです。(設定でそのようにしているのだから当たり前ですね。)
the problem is apache will proxy the derectory "uploads/*" to unicorn
but unicorn won't deal with the request because this
config.serve_static_assets = faules in "config/environments/production.rb"
最初に行った対策で、Apacheからstatic assetsが配信されるようになるのですが、それだと、Unicornの負荷が上がってしまいそうです。(Webサーバを使っている場合、static assetsをApplicationサーバに処理させるのは非推奨のようです。)
なので、根本的には、config.serve_static_assets = false
として、static assetsはApacheから配信されるように設定し、役割を分けることがより適切な対応となります。
解決策2
現時点では、public/uploads/*
は、Unicornに処理されています。
Processing by NamespacesController#show as HTML
Parameters: {"id"=>"uploads/group/avatar/**/logo.png"}
Completed 404 Not Found in 10ms (Views: 4.5ms | ActiveRecord: 0.7ms)
これを解決するには、リバースプロキシの設定で、public以下のupload/*
のリクエストは、Webサーバが処理するように設定を追記します。
#########################################
# Reverse Proxy Settings (GitLab Service)
ProxyPass /uploads ! # <- This is it!
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
これでWebサーバを再起動すれば、晴れて'public/uploads/*`以下のstatic assetsがApacheで処理されるようになります。
XXX.XXX.XXX.XXX - - [12/Nov/2014:12:54:50 +0900] "GET /uploads/group/avatar/XX/logo.png HTTP/1.1" 301 366 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36"
まとめ
Apacheでpublic以下の任意のディレクトリの中身を処理させたい場合、リバースプロキシの設定を追加する必要がある。