8

We are attempting to deploy DHH's simple Rails 5 chat example to a single, self contained EC2 instance on AWS. Code is available here: https://github.com/HectorPerez/chat-in-rails5

We used Elastic Beanstalk to spin up a single instance thus:

eb create dev-env -p “64bit Amazon Linux 2015.09 v2.0.4 running Ruby
2.2 (Puma)” –single -i t2.micro --envvars
SECRET_KEY_BASE=g5dh9cg614a37d4bdece9126b42d50d0ab8b2fc785daa1e0dac0383d6387f36b

This is a minimal installation, so there is no Elasticache, and no load balancer. To install redis on the EC2 instance we added an .ebextensions config file like this: https://gist.github.com/KeithP/08b38189372b7fd241e5#file-ebextensions-redis-config ; Git commit and deploy.

But the websocket doesnt work: Inspecting the browser console, we see this error repeating over and over:

application-a57354de3399cd895ca366df9bd7316ab69e81d266b63be7d7be563ebc78ab9d.js:27 
WebSocket connection to ‘ws://dev-env-y2e5dcrxqk.elasticbeanstalk.com/cable’ failed: 
Error during WebSocket handshake: Unexpected response code: 404

enter image description here

The server production.log shows 2 "Started GET /cable" for every "Finished /cable" call. There are no DEBUG messages from ActiveCable:

/var/app/containerfiles/logs/production.log
-------------------------------------

INFO -- : Processing by RoomsController#show as HTML 
DEBUG -- :   [1m[36mMessage Load (0.1ms)[0m  [1m[34mSELECT "messages".* FROM "messages"[0m INFO -- :   Rendered collection (0.0ms) 
INFO -- :   Rendered rooms/show.html.erb within layouts/application (0.5ms)   
INFO -- : Completed 200 OK in 2ms (Views: 1.2ms | ActiveRecord: 0.1ms) 
INFO -- : Started GET "/cable" for <ip_address> at 2016-01-01 17:28:26 +0000 
INFO -- : Started GET "/cable/" for <ip_address> at 2016-01-01 17:28:26 +0000 
INFO -- : Finished "/cable/" for <ip_address> at 2016-01-01 17:28:26 +0000
KeithP
  • 1,803
  • 1
  • 16
  • 23
  • We have checked that redis appears to have installed and started ok; and tried 'ActionCable.server.config.disable_request_forgery_protection = true' in production.rb – KeithP Dec 31 '15 at 13:08
  • Are you using a reverse proxy like nginx or connecting directly to a rails app running on port 80? – tpbowden Jan 07 '16 at 13:09
  • Have tried with and without this reverse proxy configuration: https://gist.github.com/KeithP/f8534c04d20c2b4e4b1d – KeithP Jan 07 '16 at 13:36
  • I managed to get it working with the following nginx config (replace your current lines 35-38) : https://gist.github.com/tpbowden/d85b72e5c3bf8ef8e97a – tpbowden Jan 07 '16 at 15:36
  • Thanks. we now get this in nginx/error.log: *1 connect() to unix:///var/www/my_app/tmp/sockets/my_app.sock failed (2: No such file or directory) – KeithP Jan 08 '16 at 10:24
  • If you're using puma with unix sockets then that should be the path to the socket file, you must have a config error somewhere. – tpbowden Jan 08 '16 at 10:28
  • Thanks it now works! The configs upstream backend was corrected to "server unix:///var/run/puma/my_app.sock;" But then we got 404s on the css and js assets. To fix this a further location directive was added: location /assets { root /var/app/current/public; }. Updated reverse proxy configuration: gist.github.com/KeithP/f8534c04d20c2b4e4b1d – KeithP Jan 09 '16 at 11:04

1 Answers1

4

To run the websocket chat example on a single instance Elastic Beanstalk deployment in AWS, you will need to add the following Nginx proxy configuration ( Note: replace "env1.t3tiiauce6.us-west-2.elasticbeanstalk.com" with your sitename ):

.ebextensions/nginx_proxy.config

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

  server {
      listen 80;

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

      server_name env1.t3tiiauce6.us-west-2.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;
            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 reload"

`

Lalit Kumar Maurya
  • 5,475
  • 2
  • 35
  • 29
KeithP
  • 1,803
  • 1
  • 16
  • 23
  • 2
    AWS server names got longer in January 2016, resulting in the eb deploy failure message "nginx: emerg could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64". As a workaround - if you make your environment name as short as possible it wont fall fowl of this. Eg use 'dev1' instead of 'dev-env'. The config file in the answer has been updated to reflect this. – KeithP Jan 27 '16 at 09:12
  • whats the file extension? I am getting the next error – jasmo2 Mar 30 '17 at 19:45
  • The configuration file .ebextensions/nginx_proxy.config in application version app-8b83-170330_144118 contains invalid YAML or JSON. YAML exception – jasmo2 Mar 30 '17 at 19:45
  • is the invalid YAML correctly indented? try it in a parser like this one: http://yaml-online-parser.appspot.com/ – KeithP Mar 31 '17 at 10:07
  • Thanks, it was the indentation problem. But now I got another issue – jasmo2 Mar 31 '17 at 14:23
  • container_command 01restart_nginx in .ebextensions/nginx_proxy.config failed. – jasmo2 Mar 31 '17 at 14:25