Home > Back-end >  Rails 6 ActionCable Unable to Upgrade WebSocket Request
Rails 6 ActionCable Unable to Upgrade WebSocket Request

Time:02-26

I have been struggling to get my Rails app deployed correctly for a while now, and have decided it is finally time to consult the community for some help. I have read just about every stackoverflow post on this issues, including the following, with no luck:

Problem Description

I am using the following setup:

  • Ruby 2.7.5
  • Rails 6.1.0
  • GraphQL
  • React Frontend (separate repo)
  • Elastic Beanstalk
    • Ruby 2.7 running on 64bit Amazon Linux 2/3.4.1
  • Application Load Balancer
  • Postgres ActionCable adapter

My application is deployed to AWS Elasticbeanstalk and all requests to /graphql are successful. However, when attempting to connect to /cable I get this error in my browser console:

WebSocket connection to 'wss://api.redacted.io/cable' failed: 

When checking the Elastic Beanstalk logs I see: /var/app/containerfiles/logs/production.log:

I, [2022-02-20T19:35:25.849990 #32761]  INFO -- : [8e1d3e86-81cc-4708-89d3-ebad56470f8f] Started GET "/cable" for <redacted IP> at 2022-02-20 19:35:25  0000
I, [2022-02-20T19:35:25.850342 #32761]  INFO -- : [8e1d3e86-81cc-4708-89d3-ebad56470f8f] Started GET "/cable/"[non-WebSocket] for <redacted IP> at 2022-02-20 19:35:25  0000
E, [2022-02-20T19:35:25.850384 #32761] ERROR -- : [8e1d3e86-81cc-4708-89d3-ebad56470f8f] Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
I, [2022-02-20T19:35:25.850419 #32761]  INFO -- : [8e1d3e86-81cc-4708-89d3-ebad56470f8f] Finished "/cable/"[non-WebSocket] for <redacted IP> at 2022-02-20 19:35:25  0000

Potentially Relevant Files

cable.yml:

development:
  adapter: postgresql

test:
  adapter: test

production:
  adapter: postgresql

production.rb:

...
config.action_cable.url = 'wss://api.redacted.io/cable'

config.action_cable.allowed_request_origins = ['redacted.io', 'http://redacted.io', 'https://redacted.io']
...

.ebextensions/nginx_proxy.config:

files:
  "/etc/nginx/conf.d/websockets.conf" :
    content: |
      upstream backend {
          server unix:///var/run/puma/my_app.sock;
      }

      server_names_hash_bucket_size 128;

      server {
          listen 80;

          access_log /var/log/nginx/access.log;
          error_log /var/log/nginx/error.log;

          server_name redacted.elasticbeanstalk.com;

          # prevents 502 bad gateway error
          large_client_header_buffers 8 32k;

          location / {
              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_set_header X-NginX-Proxy true;

              # prevents 502 bad gateway error
              proxy_buffers 8 32k;
              proxy_buffer_size 64k;

              proxy_pass http://backend;
              proxy_redirect off;

              location /assets {
                root /var/app/current/public;
              }

              # enables WS support
              location /cable {
                proxy_pass http://backend/cable;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
              }
          }
      }


container_commands:
  01restart_nginx:
    command: "nginx -t && service nginx restart"

CodePudding user response:

After posting on reddit, I was able to fix my issue by:

  1. Removing my .ebextensions/nginx_proxy.config file.
  2. Creating a new file, .platform/nginx/conf.d/elasticbeanstalk/websocket.conf with the contents:
location /cable {
  proxy_pass http://my_app/cable;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  • Related