What config.action_cable.url should be configured for websockets / Rails / Kubernetes /Minukube with Nginx?
When running "docker-compose" locally an Nginx processes in front of a Rails process (not API only, but with SSR) and a standalone Cable process (cf the guides), the websockets work fine by passing the following server-side (in say "/config/application.rb", with action_cable_meta_tag set in the layouts):
config.action_cable.url = 'ws://localhost:28080'
I am targetting Kubernetes with Minikube locally: I deployed Nginx in front of a Rails deployment (RAILS_ENV=production) along with a Cable deployment but I can't make it work. The Cable service is internal of type "ClusterIP", with "port" and "targetPort". I tried several variations.
Any advice?
Note that I use Nginx -> Rails + Cable on Minikube, and the entry-point is the Nginx service, external of kind LoadBalancer where I used:
upstream rails {
server rails-svc:3000;
}
server {
listen 9000 default_server;
root /usr/share/nginx/html;
try_files $uri @rails;
add_header Cache-Control public;
add_header Last-Modified "";
add_header Etag "";
location @rails {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Host $http_host;
proxy_pass_header Set-Cookie;
proxy_redirect off;
proxy_pass http://rails;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
To allow any origin, I also set:
config.action_cable.disable_request_forgery_protection = true
I have an answer: in a Minikube cluster, don't put anything and disable forgery protection, Rails will default the correct value. When Nginx is front of a Rails pod and a standalone ActionCable/websocket pod (the Rails image is launched with bundle exec puma -p 28080 cable/config.ru), if I name "cable-svc" the service that exposes the ActionCable container, and "rails-svc" the one for the Rails container, you need to:
CABLE_URI127.0.0.1:some_port), do:# config.action_cable.url <-- comment this
config.action_cable.disable_request_forgery_protection=true
upstream rails {
server rails-svc:3000;
}
server {
[...root, location @rails {...}]
location /cable {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass "http://cable-svc:28080";
}
}
Check the logs, no more WebSockets in Rails, and Cable responds.