title: Rails 5 action cable SSL in production - WebSocket connection failed: Error during WebSocket handshake: Unexpected response 301
body: <p>I am trying to run an app with rails 5.0.0beta3 and websockets. I have everything working locally on development but in production I getting this response in my browser's console:</p>
  
  <p>"WebSocket connection failed: Error during WebSocket handshake: Unexpected response 301"</p>
  
  <p>Here is a my nginx conf.</p>
  
  <pre><code>upstream app {
    server unix:/home/dev/workspace/my_app/tmp/sockets/thin.0.sock max_fails=1 fail_timeout=15s;
    server unix:/home/dev/workspace/my_app/tmp/sockets/thin.1.sock max_fails=1 fail_timeout=15s;
  }
  
  server {
    listen 443 ssl;
    server_name www.my_app.co;
  
    root /home/dev/workspace/my_app/public;
    try_files $uri/index.html $uri @app;
  
    location @app {
      proxy_next_upstream error timeout http_502 http_503;
      proxy_read_timeout 60s;
  
      proxy_pass http://app;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-FORWARDED-PROTO $scheme;
      proxy_redirect off;
    }
  
    location /websocket/ {
      proxy_pass http://localhost:28080/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
    }
  
    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
  
    ssl on;
    ssl_certificate /ssl/www.my_app.co.crt;
    ssl_certificate_key /ssl/www.my_app.co.key;
  
    ssl_session_timeout 5m;
  
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;
  }
  </code></pre>
  
  <p>I am running thin for my app server and running puma for the websockets server along with redis locally. I am attempting to follow the action cable example app here: <a href="https://github.com/rails/actioncable-examples" rel="noreferrer">https://github.com/rails/actioncable-examples</a>.</p>
  
  <p>I am starting my puma server like this: <code>bundle exec puma -p 28080 cable/config.ru</code></p>
  
  <p>With this <code>puma.rb</code> in <code>config</code>:</p>
  
  <pre><code>workers 1
  threads 1, 10
  
  app_dir = File.expand_path("../..", __FILE__)
  shared_dir = "#{app_dir}/shared"
  
  rails_env = ENV['RAILS_ENV'] || "production"
  environment rails_env
  
  stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
  
  pidfile "#{shared_dir}/pids/puma.pid"
  state_path "#{shared_dir}/pids/puma.state"
  </code></pre>
  
  <p>Here is the relevant parts of my <code>production.rb</code> config:</p>
  
  <pre><code>config.action_cable.allowed_request_origins = ['https://www.chatben.co', 'https://45.55.192.195']
  config.action_cable.url = "wss://www.chatben.co/websocket"
  config.force_ssl = false
  </code></pre>
  
  <p>Here is my <code>development.rb</code> config: </p>
  
  <pre><code>config.action_cable.url = "ws://localhost:28080"
  config.action_cable.allowed_request_origins = ['http://localhost:3000']
  config.action_cable.disable_request_forgery_protection = true
  </code></pre>
  
  <p>In my app, I start my cable like this:</p>
  
  <pre><code>@App = {}
  App.cable = ActionCable.createConsumer()
  </code></pre>
  
  <p>Any suggestions would be awesome. I have noticed someone here: <a href="https://stackoverflow.com/questions/35041614/ror-5-0-0-actioncable-wss-websocket-handshake-unexpected-response-code-301">RoR 5.0.0 ActionCable wss WebSocket handshake: Unexpected response code: 301</a>
  was able to solve this by using a separate domain. That is what I will probably try next but I was hoping it wouldn't come to that.</p>
  
  <p>Thanks in advance for any help! I really appreciate it.</p>