配置 nginx 代理 thin 和 Rails ActionCable
Configuring nginx to proxy thin and Rails ActionCable
我正在尝试使用 ActionCable(主要是复制 DHH example)并尝试将它连接到 Ubuntu 服务器上的 运行,服务器上有瘦(在端口 8443 上)和 nginx。在本地一切正常,但是,当我尝试在实时服务器上代理它时,我收到此错误响应:failed: Error during WebSocket handshake: Unexpected response code: 301
.
这是我的 nginx 配置的相关部分:
server {
listen 80;
server_name _not_;
root /home/ubuntu/www/;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8443;
}
server {
listen 80;
...
location /websocket/ {
proxy_pass http://127.0.0.1:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
}
...
}
我有点不适应这里的 nginx -- 我错过了什么或错了什么?
一个月后回过头来发现问题不是nginx的配置问题,而是thin的问题。我做了三件事:
(1) 配置精简以使用 the Faye adapter:
# config.ru
require 'faye'
Faye::WebSocket.load_adapter('thin')
require ::File.expand_path('../config/environment', __FILE__)
use Faye::RackAdapter, mount: '/faye', timeout: 25
run Rails.application
(2) 切换到在 routes.rb
中安装 ActionCable,而不是尝试 运行 它 as a standalone。
#routes.rb
MyAwesomeApp::Application.routes.draw do
...
match "/websocket", to: ActionCable.server, via: [:get, :post]
end
(3) 恢复到我的正常 nginx 配置,上游的 websockets 变薄了(就像网络服务器一样:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close; }
upstream thin {
server 127.0.0.1:3000;
}
server {
...
location /websocket {
proxy_pass http://thin;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; }
...
}
所以,我很抱歉 nginx,我正在为你开脱——看来这些问题主要与瘦有关。
编辑:我添加了我在路由中安装后返回的旧 nginx 配置。同样值得注意的是,对于那些使用 SSL 的人来说,config.force_ssl
会破坏安全的 wss
websocket。相反,您应该在控制器级别执行 force_ssl
,as recommended here,并配置 nginx 以将任何 HTTP 路由重写为 HTTPS。
这个线程对我很有帮助,但我选择将 AC 进程分离到一个单独的 puma 实例中,这样我就可以单独配置工作人员等。后来我从 nginx 添加了 SSL 代理,以确保使用最新的密码等。这避免了 rails/puma/AC 担心 SSL 与非 SSL;服务器实例中的一切都是非 SSL。
这是我的 AC 服务器部分:
server {
listen 881 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
server_name localhost;
location / {
proxy_pass http://cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
注解github issue:您需要确保您的 AC 配置允许您的域作为源:
#config/initializers/cable.rb
ActionCable.server.config.allowed_request_origins = %w( http://my-domain.com )
我正在尝试使用 ActionCable(主要是复制 DHH example)并尝试将它连接到 Ubuntu 服务器上的 运行,服务器上有瘦(在端口 8443 上)和 nginx。在本地一切正常,但是,当我尝试在实时服务器上代理它时,我收到此错误响应:failed: Error during WebSocket handshake: Unexpected response code: 301
.
这是我的 nginx 配置的相关部分:
server {
listen 80;
server_name _not_;
root /home/ubuntu/www/;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8443;
}
server {
listen 80;
...
location /websocket/ {
proxy_pass http://127.0.0.1:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
}
...
}
我有点不适应这里的 nginx -- 我错过了什么或错了什么?
一个月后回过头来发现问题不是nginx的配置问题,而是thin的问题。我做了三件事:
(1) 配置精简以使用 the Faye adapter:
# config.ru
require 'faye'
Faye::WebSocket.load_adapter('thin')
require ::File.expand_path('../config/environment', __FILE__)
use Faye::RackAdapter, mount: '/faye', timeout: 25
run Rails.application
(2) 切换到在 routes.rb
中安装 ActionCable,而不是尝试 运行 它 as a standalone。
#routes.rb
MyAwesomeApp::Application.routes.draw do
...
match "/websocket", to: ActionCable.server, via: [:get, :post]
end
(3) 恢复到我的正常 nginx 配置,上游的 websockets 变薄了(就像网络服务器一样:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close; }
upstream thin {
server 127.0.0.1:3000;
}
server {
...
location /websocket {
proxy_pass http://thin;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; }
...
}
所以,我很抱歉 nginx,我正在为你开脱——看来这些问题主要与瘦有关。
编辑:我添加了我在路由中安装后返回的旧 nginx 配置。同样值得注意的是,对于那些使用 SSL 的人来说,config.force_ssl
会破坏安全的 wss
websocket。相反,您应该在控制器级别执行 force_ssl
,as recommended here,并配置 nginx 以将任何 HTTP 路由重写为 HTTPS。
这个线程对我很有帮助,但我选择将 AC 进程分离到一个单独的 puma 实例中,这样我就可以单独配置工作人员等。后来我从 nginx 添加了 SSL 代理,以确保使用最新的密码等。这避免了 rails/puma/AC 担心 SSL 与非 SSL;服务器实例中的一切都是非 SSL。
这是我的 AC 服务器部分:
server {
listen 881 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
server_name localhost;
location / {
proxy_pass http://cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
注解github issue:您需要确保您的 AC 配置允许您的域作为源:
#config/initializers/cable.rb
ActionCable.server.config.allowed_request_origins = %w( http://my-domain.com )