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ファイルはちゃんと読めていないらしい。
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コマンドの違い
そして気づいた原因
結論から書くと、-p オプションをつけてPumaを起動したときにはsocketファイルをlistenしなくなるらしい。確かに、socketファイルで通信しようとしているのに、ポートを指定する必要はなかった。
調べなきゃ寝れない!と調べたら余計に寝れなくなったソケットの話
Pumaの起動におけるlistenの挙動の違い
どうやら以下のような仕様らしい。
- pumaコマンドを 
-pオプションを付けて起動すると、socketファイルをlistenしなくなる - pumaコマンドを 
-pオプションを外して起動すると、socketファイルと指定したポートの双方をlistenする - 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している」の違い