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している」の違い