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


# ハマったポイント

1. nginx + unicorn でローカル環境に/でアクセスすると403 forbiddenが返ってくる。
2. 403解消後、/にアクセスると今度は「We're sorry, but something went wrong.」が返ってくる。

# nginx + unicorn で403が帰ってくる問題

## 原因の調査

当時のステータス

```bash
$ rails server -b 192.168.33.10
```

でrailsのサーバーを起動させて、3000番ポートでアクセスした場合は、正常にrailsのwelcomeページが動作する。

しかし、nginx + unicornで動作させると403が返ってくる。

とりあえずググってみて、ドキュメントルートに指定しているdirectoryのパーミッション？の問題かと思ってとりあえず、ドキュメントルートに指定していた、publicのdirectoryの権限を777にしてみる。
→ 効果なし。

とりあえずセオリー通りnginxのerrorログを確認

```bash
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

の２つのエラーを確認。
しかし、めぼしいエラーは発見されず。

次にnginxのエラーを確認

```bash
[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が読み込めないらしい。

とりあえず確認

```bash
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にハマる](http://blog.tnantoka.com/posts/49/versions/current)
[RedmineをCentOS 7上で動かすーUnicornとNginx編¶](http://www.torutk.com/projects/swe/wiki/Redmine%E3%82%92CentOS_7%E4%B8%8A%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E3%83%BCUnicorn%E3%81%A8Nginx%E7%B7%A8#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E8%B5%B7%E5%8B%95%E3%82%A8%E3%83%A9%E3%83%BC%E4%BA%8B%E4%BE%8B2)
[centos7でunix domain socketが読めない](http://lxyuma.hatenablog.com/entry/2015/08/29/200443)

上記三点の記事をまとめると

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を再起動する。

```bash

$ 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を実行

```bash
# 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ファイルが生成される。

改めて/でアクセスする
→ 正常に表示！

１個めのトラブル解消にかなり回り道してしまった。。。
nginxのログを確認するのはかなり癖付け無いと無駄に労力を食ってしまう。。。