LoginSignup
39
39

More than 5 years have passed since last update.

Rails5のActionCableをCapistrano経由でデプロイ

Posted at

Rails 5の目玉機能の一つに、WebSocketsを容易に利用できるActionCableがあります。Rails 4でもgemで提供されてましたが、Rails 5で本体にマージされました。しかし本番環境の情報が少なかったので、記事にまとめました。ActionCableを使ったRails 5アプリは、以下の記事がわかりやすいです。

この例ではdevelopment環境およびHerokuでは動作しますが、この記事は本番環境のnginxを自前で設定してゆきます。

動作環境と構成

フロントのWebサーバにはnginxを、RackサーバにはPumaを使い、Capistrano3でデプロイします。UnicornをRackサーバに使うと、WebSocketsサーバも別に作成する必要があるので、今回はPumaを使います。Pumaとnginxの処理は puma.sock 経由で行います。デプロイおよびPumaの制御にはCapistranoを使います。サービスとして起動するには、jungleまたはsystemdの設定を自前で用意すれば良さそうですが、ここでは触れません。

ActionCableのデフォルトに従い/cableをWebSocketsのパスに、つまりws://your-domain.example.com/cable(またはwss://your-domain.example.com/cable)からWebSocketsに接続します。

Railsアプリの設定

まずRailsアプリ側で、ActionCableが許可するホストを設定します。nginxとRailsアプリが同サーバ上でも、サーバのホストを許可する必要があります(Allowed Request Origins)。

config/environments/production.rb
config.action_cable.allowed_request_origins = [ 'https://your-domain.example.com' ]

Capistranoの設定とデプロイ

capistrano-pumaというgemを使うと、サーバ側のpumaを手元から制御できます。Gemfilecapistrano3-pumacapistrano-puma は別のgemないので注意!)を追加して、Capfile に設定します。

Gemfile
gem 'capistrano3-puma' , group: :development
Capfile
require 'capistrano/puma'

以上でCapistrano経由で本番環境のpumaを制御できます。

(bundle exec) cap production puma:start

この時 puma:config タスクが走り、pumaの設定ファイルがデプロイ先の "#{shared_path}/puma.rb" に作成されます。pumaの設定ファイルは config/deploy.rb を元に生成されます。設定項目はcapistrano-pumaのREADMEにあります。デフォルトでは、pumaのsockファイルが "#{shared_path}/tmp/sockets/puma.sock" に配置されます。つまり puma:start を走らせると"#{shared_path}/tmp/sockets/puma.sock" 越しにRailsアプリにアクセスできるので、nginxはこのファイルを見に行くよう設定します。

nginxの設定

通常のHTTPリクエストは、Unicorn同様upstreamにソケットを指定します。WebSocketsに対するリクエスト(/cable)はHTTPバージョンとヘッダを書き換えて同じソケットに渡します。

nginx.conf
http {
  upstream puma {
    server unix:/path-to-your-project/tmp/sockets/puma.sock;
  }

  server {
    # General web access
    try_files $uri $uri/index.html $uri.html @webapp;
    location @webapp {
      root /path-to-your-project/public/;
      proxy_pass http://puma;
    }

    # WebSocket configure
    location /cable {
      proxy_pass http://puma;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }
}

繋がらないときは

検証用にcURLでWebSockets通信もできますが、wscatが便利です。

wscat -c ws://your-domain.example.com/cable    # or wss://... in SSL version

設定ができてなければエラーが帰ってきて、反応が無いときは正常に通信できてる場合が多いです。正しく通信できないときはログとにらめっこしましょう。

参考

39
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
39