I am using private pub for one of my projects. Its working fine on localhost but when I deploy it on live server it giving following error:
Errno::ECONNREFUSED in CommentsController#new
Connection refused - connect(2) for "202.164.34.20" port 9292
Here is my private_pub.yml file content for local server:
development:
server: "http://localhost:9292/faye/faye"
secret_token: "secret"
test:
server: "http://localhost:9292/faye/faye"
secret_token: "secret"
production:
server: "http://example.com/faye/faye"
secret_token: "0378a6008f37cbd9c3390ce4069bb85f776d068f7b4885d6890f07066affde25"
signature_expiration: 3600 # one hour
and for other server, here is the file content:
development:
server: "http://202.164.34.20:9292/faye/faye"
secret_token: "secret"
test:
server: "http://202.164.34.20:9292/faye/faye"
secret_token: "secret"
production:
server: "http://localhost:9292/faye/faye"
secret_token: "0378a6008f37cbd9c3390ce4069bb85f776d068f7b4885d6890f07066affde25"
signature_expiration: 3600 # one hour
Now I need to deploy this on http://202.164.34.20:3001 url. please suggest.
localhost:9292 means it will bind to 127.0.0.0, if you want to access from public ip make sure to bind to your external ip or to 0.0.0.0.
Although I would suggest to proxy it with nginx/apache so users can just connect to port 80
Example for nginx
server {
listen 80;
server_name faye.yourdomain.com;
access_log /var/log/nginx/faye.log;
location /faye {
proxy_pass http://127.0.0.1:9292;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
}
}
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
Related
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:
Rails 5 ActionCable fails to upgrade to WebSocket on Elastic Beanstalk -> From this post I ensured I was using an Application Load Balancer
ActionCable on AWS: Error during WebSocket handshake: Unexpected response code: 404 -> Configured an nginx proxy, with no change
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"
After posting on reddit, I was able to fix my issue by:
Removing my .ebextensions/nginx_proxy.config file.
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;
}
I'm trying to connect to an ActionCable websocket and everything works fine running locally with just Puma and without nginx.
However, when I try to do the exact same thing on my staging environment, the connection is immediately closing after connecting. I am able to get the downstream welcome messages and maybe a ping.
However, the connection abruptly closes without any of the onClose callbacks so my guess is nginx is not letting the connection persist.
Here is my sites nginx configuration.
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/home/deploy/my-app/shared/tmp/sockets/puma.sock fail_timeout=60;
keepalive 60;
}
server {
listen 80;
server_name localhost;
# websocket_pass websocket;
root /home/deploy/my-app/current/public;
try_files $uri/index.html $uri #app;
location #app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
#location / {
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header Host $host;
# proxy_redirect off;
# proxy_http_version 1.1;
# proxy_set_header Connection '';
# proxy_pass http://app;
#}
location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /cable {
proxy_pass http://app;
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;
}
I also found this error in nginx error logs:
2019/02/11 21:08:35 [error] 10233#10233: *2 recv() failed (104: Connection reset by peer) while proxying upgraded connection, client: x.x.x.x, server: localhost, request: "GET /cable/ HTTP/1.1", upstream: "http://unix:/home/deploy/wr-api/shared/tmp/sockets/puma.sock:/cable/", host: "x.x.x.x"
So after some time, we noticed that the staging environment cable.yml had this value for url:
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
Removing that value and all other values except for adapter: staging fixed it for us.
New cable.yml staging config:
staging:
adapter: redis
Working!
Could not connect websocket using Action Cable in Rails 5.1. HTTP server is Unicorn on nginx and adapter is Redis.
Rails configuration is the following.
# config/environments/production.rb
config.action_cable.disable_request_forgery_protection = true
nginx configuration is the following.
upstream unicorn {
server unix:/rails/current/tmp/sockets/unicorn.sock;
}
server {
listen 80;
charset utf-8;
server_name sub.example.com;
root /rails/current/public;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://unicorn;
break;
}
}
location /cable {
proxy_pass http://unicorn;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
...
}
Errors in console of web browser are the following.
WebSocket connection to 'wss://sub.example.com/cable' failed: Error during WebSocket handshake: Unexpected response code: 404
Errors in Rails are the following.
[ERROR] Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
[INFO] Finished "/cable/"[non-WebSocket] for xxx.xxx.xxx.xxx at 2017-xx-xx
A strangest thing is a error in Rails does not have HTTP_UPGRADE value. But HTTP request headers of web browser include Upgrade key and websocket value. Also setting "websocket" for proxy header in nginx configurations.
What should I do?
On the back of that writeup, I just realized the universal solution is
a simple change to the config/secrets.yml file to reference the
ENV["PORT"] setting
...
# Be sure to restart your server when you modify this file.
development:
secret_key_base: 231bf79489c63f8c8facd7...
action_cable_url : http://localhost:<%= ENV["PORT"] %>
test:
secret_key_base: 1ab8adbcf8410aebb...
action_cable_url : http://localhost:<%= ENV["PORT"] %>
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
action_cable_url : <%= ENV["SERVER_PORT"] %>
.
You can also have this in your dot file:
export PORT=3000
source
Good day!
I want to run websocket app with Faye gem, but the following problem occurs: when I deploy my app on production server, Ngix can't receive faye.js and can't connect to faye server. In Nginx error.log I found next errors:
2014/12/24 15:44:39 [error] upstream prematurely closed connection while reading response header from upstream, client: 46.0.121.23, server: example.com, request: "GET /faye HTTP/1.1", upstream: "http://127.0.0.1:9292/faye", host: "example.com"
2014/12/24 15:44:39 [error] *1 connect() failed (111: Connection refused) while connecting to upstream, client: 46.0.121.23, server: example.com, request: "GET /faye HTTP/1.1", upstream: "http://127.0.0.1:9292/faye", host: "example.com"
I try the How to start faye server on a rails app deployed using dokku? and Error 502 Bad Gateway on NGINX + rails + dokku answers, but it's not help for me.
My Procfile is
web: bundle exec rails s Puma -p 5000
faye: bundle exec rackup s Puma faye.ru
My faye.ru is
require 'faye'
require File.expand_path('../config/initializers/faye_token.rb', __FILE__)
class ServerAuth
def incoming(message, callback)
if message['channel'] !~ %r{^/meta/}
if message['ext']['auth_token'] != FAYE_TOKEN
message['error'] = 'Invalid authentication token.'
end
end
callback.call(message)
end
end
faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 0)
faye_server.add_extension(ServerAuth.new)
run faye_server
My nginx.conf is:
upstream example.com { server 127.0.0.1:49169; }
server {
listen [::]:80;
listen 80;
server_name example.com;
location / {
proxy_pass http://example.com;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
location /faye {
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache_bypass $http_pragma $http_authorization;
proxy_no_cache $http_pragma $http_authorization;
proxy_pass http://localhost:9292;
}
}
My app get faye.js next:
<%= javascript_include_tag "http://example.com/faye.js" %>
And connect to faye server
$(function() {
var faye = new Faye.Client('http://example.com/faye');
faye.subscribe('/comments/new', function (data) {
eval(data);
});
});
What can I do? In development enviroment all works fine, but in production only errors.
Try to config from this gist
https://gist.github.com/Bubelbub/0a942a0d51a3d329897d
In server section:
large_client_header_buffers 8 32k;
In faye location:
proxy_buffers 8 32k;
proxy_buffer_size 64k;
Using Nginx 1.6 with private_pub gem
Here are my config files:
private_pub.ru
# Run with: rackup private_pub.ru -s thin -E production
require "bundler/setup"
require "yaml"
require "faye"
require "private_pub"
Faye::WebSocket.load_adapter('thin')
PrivatePub.load_config(File.expand_path("../config/private_pub.yml", __FILE__), ENV["RAILS_ENV"] || "development")
run PrivatePub.faye_app
Private_pub.yml
development:
server: "http://localhost:9292/faye/faye"
secret_token: "secret"
test:
server: "http://localhost:9292/faye/faye"
secret_token: "secret"
production:
server: "http://xxxxx.com/faye/faye"
secret_token: "my secret token"
signature_expiration: 3600 # one hour
in my Nginx.conf
location /faye {
proxy_pass http://0.0.0.0:9292;
break;
}
The service is running but really really slow and I get those errors on safari:
WebSocket connection to 'ws://xxxxx.com/faye' failed: Unexpected response code: 400
Failed to load resource: the server responded with a status of 404 (Not Found)
Failed to load resource: the server responded with a status of 502 (Bad Gateway)
Any thoughts?
OK.. I found the solution for those who ever want to install Faye/Private_pub on Nginx running thin and unicorn.
First:
You have to understand that your upstream server is your localhost:9292 (127.0.0.1:9292)
you set your upstream in your Nginx conf by adding the following:
location /faye {
proxy_pass http://127.0.0.1:9292;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_set_header X-Forwarded-Proto https;
break;
}
Also for those who have a 504 after that change the config file in the Nginx and php.fmp (if you have it) so that the timeout is increased.
Don't forget to reload your Nginx. If you still have errors check your Nginx error.log