ハマったポイント
- nginx + unicorn でローカル環境に/でアクセスすると403 forbiddenが返ってくる。
- 403解消後、/にアクセスると今度は「We're sorry, but something went wrong.」が返ってくる。
nginx + unicorn で403が帰ってくる問題
原因の調査
当時のステータス
$ rails server -b 192.168.33.10
でrailsのサーバーを起動させて、3000番ポートでアクセスした場合は、正常にrailsのwelcomeページが動作する。
しかし、nginx + unicornで動作させると403が返ってくる。
とりあえずググってみて、ドキュメントルートに指定しているdirectoryのパーミッション?の問題かと思ってとりあえず、ドキュメントルートに指定していた、publicのdirectoryの権限を777にしてみる。
→ 効果なし。
とりあえずセオリー通りnginxのerrorログを確認
2016/09/28 19:29:28 [error] 8268#8268: *1 directory index of "/path/to/myapp/public/" is forbidden, client: 192.168.33.1, server: localhost, request: "GET / HTTP/1.1", host: "192.168.33.10"
とある。
nginxの設定の中でtry_files @unicornとしていたところを location / {}ディレクティブの中に加えることが必要。
ちなみに、403 forbiddenが起こっていた際には、server {}ディレクティブの中にtry_filesを入れてました。
修正した内容が以下
File Edit Options Buffers Tools Conf Help
upstream unicorn {
server unix:/var/run/unicorn.sock;
}
server {
listen 80;
server_name localhost;
charset koi8-r;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
client_max_body_size 64m;
root /var/www/app/rails_demo/public;
location / {
try_files $uri/index.html $uri @unicorn; // 追記
}
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
#try_files $uri/index.html $uri @unicorn; //コメントアウト
location @unicorn {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://unicorn;
}
}
これでnginxを再起動させて/にアクセスしたらとりあえず403は解消。
We're sorry, but something went wrong.問題
403が解決したのもつかの間。
次に/にアクセスしたらなんかよくわかんないエラーが起きているらしい。
とりあえず例に則って、railsのログを確認
log/development.log
log/unicorn.log
の2つのエラーを確認。
しかし、めぼしいエラーは発見されず。
次にnginxのエラーを確認
[crit] 9510#9510: *1 connect() to unix:/tmp/unicorn.sock failed (2: No such file or directory) while connecting to upstream, client: 192.168.33.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/unicorn.sock:/", host: "192.168.33.10"
なんか起きてる。
/tmp/直下にあるunicorn.sockが読み込めないらしい。
とりあえず確認
ls -la /tmp/nf
合計 8
drwxrwxrwt. 8 root root 4096 9月 29 19:39 .
dr-xr-xr-x. 18 root root 4096 9月 17 11:54 ..
srwxrwxrwx 1 vagrant vagrant 0 9月 29 19:34 unicorn.sock
ある。
なぜ?
ってことで調べていく内に以下の記事に当たる。
CentOS 7でNginx、Unicornにハマる
RedmineをCentOS 7上で動かすーUnicornとNginx編¶
centos7でunix domain socketが読めない
上記三点の記事をまとめると
CentOS7ではnginxとunicornで/tmpディレクトリが共有できない。
CentOS7ではsocketファイルを/tmp以下に置くのは非推奨で、/var/run以下におくと良いらしい。
ってことでunicornの設定ファイルとnginxの設定ファイルを変更
# 削除
listen "/tmp/unicorn.sock"
pid "/tmp/unicorn.pid"
# 追加
listen "/var/run/unicorn.sock"
pid "/var/run/unicorn.pid"
upstream unicorn {
# 削除
server unix:/tmp/unicorn.sock;
# 追加
server unix:/var/run/unicorn.sock;
}
上記に変更後unicornとnginxを再起動する。
$ bundle exec unicorn -c /var/www/app/rails_demo/config/unicorn.rb -E development -D
bundler: failed to load command: unicorn (/usr/local/rbenv/versions/2.3.1/bin/unicorn)
ArgumentError: directory for pid=/var/run/unicorn.pid not writable
エラーが起きる。
.pidファイルを/var/run以下に生成する権限がない。
そのため、root権限でunicornを実行
# taskディレクトリでunicornを起動するスクリプトを実装済み
$ sudo /usr/local/rbenv/shims/bundle exec rake unicorn:start
bundle exec unicorn -c /var/www/app/rails_demo/config/unicorn.rb -E development -D
これでrootでsocketファイルとpidファイルが生成される。
改めて/でアクセスする
→ 正常に表示!
1個めのトラブル解消にかなり回り道してしまった。。。
nginxのログを確認するのはかなり癖付け無いと無駄に労力を食ってしまう。。。