Help us understand the problem. What is going on with this article?

Rails + unicorn + nginx でWeb Serverを起動させるときにはまった話。

More than 3 years have passed since last update.

ハマったポイント

  1. nginx + unicorn でローカル環境に/でアクセスすると403 forbiddenが返ってくる。
  2. 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を入れてました。

修正した内容が以下

/etc/nginx/conf.d/default.conf
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の設定ファイルを変更

config/unicorn.rb
# 削除
listen "/tmp/unicorn.sock"
pid "/tmp/unicorn.pid"

# 追加
listen "/var/run/unicorn.sock"
pid "/var/run/unicorn.pid"

/etc/nginx/conf.d/default.conf
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のログを確認するのはかなり癖付け無いと無駄に労力を食ってしまう。。。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away