ポートを指定してPumaを起動するとsocketファイルをlistenしなくなる

Rails5で開発したウェブアプリーションをpumaコマンドで起動する際、 ポートを指定して起動しようとするとデフォルトでsocketファイルをlistenしなくてハマったので、調べたことを忘れないように残しておく。


### ずっとハマっていたエラー

なんかよくわからなかったが、socketファイルが読めいないせいでNginxに以下のようなエラーがずっとでていた。socketファイルはちゃんとあるし、実行ユーザまわりの権限も正しく設定しているつもりだったので、なに言ってんだ。と思っていた。

> connect() to unix:///var/www/my-app-name/shared/tmp/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: xxx.xxx.xx.xxx, server: localhost, request: "GET / HTTP/1.1", upstream: "http://unix:///var/www/my-app-name/shared/tmp/sockets/puma.sock:/", host: "xx.xxx.xxx.xxx"


### Nginxの設定（一部抜粋）

NginxをリバースプロキシとしてPumaの前段において、unixドメインソケットを経由してNginxとPumaがやりとりするような構成を期待していた。が、どうやらsocketファイルはちゃんと読めていないらしい。

```/etc/nginx/nginx.conf
upstream puma {
  server unix:///var/www/my-app-name/shared/tmp/sockets/puma.sock;
}
server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  localhost;
    root         /var/www/my-app-name/current/public;

    include /etc/nginx/default.d/*.conf;

    location / {
        try_files $uri $uri/index.html $uri.html @webapp;
    }

    location @webapp {
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://puma;
    }
}
```

### Pumaの起動

本番環境にsshではいり、コマンドを叩いてPumaを起動しようとしていた。

```
$ bundle exec puma -t 5:5 -p 3000 -e production -C config/puma.rb
```

いろいろ試しているうちに、このコマンドだと正しく起動できることに気づいた。

```
$ bundle exec pumactl start
```

```
$ bundle exec puma -t 5:5 -e production -C config/puma.rb
```

pumaコマンドとpumactlコマンドの違いについては、前回書いたこちらの記事をどうぞ。
[Pumaの起動におけるpumaコマンドとpumactlコマンドの違い](http://qiita.com/kappy0322/items/33cbbe84815534f8b479)


### そして気づいた原因

結論から書くと、`-p` オプションをつけてPumaを起動したときにはsocketファイルをlistenしなくなるらしい。確かに、socketファイルで通信しようとしているのに、ポートを指定する必要はなかった。
[調べなきゃ寝れない！と調べたら余計に寝れなくなったソケットの話](http://qiita.com/kuni-nakaji/items/d11219e4ad7c74ece748)


### Pumaの起動におけるlistenの挙動の違い

どうやら以下のような仕様らしい。

1. pumaコマンドを `-p` オプションを付けて起動すると、socketファイルをlistenしなくなる
2. pumaコマンドを `-p` オプションを外して起動すると、socketファイルと指定したポートの双方をlistenする
3. pumactlコマンドで起動するとsocketファイルと指定したポートの双方をlistenする

**1. bundle exec puma -p 3000**

```
$ bundle exec puma -p 3000

Puma starting in single mode...
* Version 3.9.1 (ruby 2.4.0-p0), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: production
* Listening on tcp://0.0.0.0:3000 
Use Ctrl-C to stop
```

**2. bundle exec puma**

```
$ bundle exec puma

Puma starting in single mode...
* Version 3.9.1 (ruby 2.4.0-p0), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: production
* Listening on tcp://0.0.0.0:3000
* Listening on unix:///var/www/my-app-name/releases/20170620162839/tmp/sockets/puma.sock
Use Ctrl-C to stop
```

**3. bundle exec pumactl start**

```
$ bundle exec pumactl start

Puma starting in single mode...
* Version 3.9.1 (ruby 2.4.0-p0), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: production
* Listening on tcp://0.0.0.0:3000
* Listening on unix:///var/www/my-app-name/releases/20170620162839/tmp/sockets/puma.sock
Use Ctrl-C to stop
```


### ポートの開放とlistenの関係

socketファイルで通信をするためには、対象のポートを開いてlistenしていないといけなかった。そもそもlistenってなんだ、と思われている方は以下の記事がとてもわかりやすかった。
[ロミオとジュリエットで学ぶ「ポートが開いてる」と「Listenしている」の違い
](http://qiita.com/DQNEO/items/7027fda87a1ecf44b9f2)