動かざることバグの如し

近づきたいよ 君の理想に

ActionCable使ったRailsのnginx設定

ActionCableはwebsocketを使うので通常のRailsと設定が違う。たくさんコケる要素があるのでそのメモをまとめた。

環境

  • Rails 5.0.3
  • puma
  • Redisは今回使わない

nginxの設定

upstream puma-realtime {
  server unix:///var/www/realtime/shared/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name hogehoge.com;
  root /var/www/realtime/current/public;
  client_max_body_size 0;

  location / {
    try_files $uri @proxy;
  }

  location /cable {
    proxy_pass http://puma-realtime;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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;
  }

  location @proxy {
    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://puma-realtime;
  }
}

もう一つコケる要素があって、developでは勝手にルーティングしてくれるけど、production環境では明示的にwebsocketのルーティングを示さなければならない。

config/routes.rb

mount ActionCable.server => '/cable'

その他設定項目

config/environments/production.rb

ActionCable.server.config.disable_request_forgery_protection = true
config.web_console.whitelisted_ips = '0.0.0.0/0'

config/cable.yml

productionの項目を adapter: asyncにしても動作したからRedisは必須というわけではない。使う場合は以下のようにadapter: redisを用いる。

development:
  adapter: async

test:
  adapter: async

production:
  adapter: redis
  url: redis://localhost:6379/1