Action Cable with Puma, Nginx, Docker Swarm
I setup a DigitalOcean Ubuntu 22 droplet to host a docker swarm with containers for a rails app, postgress, and redis. I’m not able to get action cable to work with puma and nginx. I see errors in the console for: WebSocket connection to wss://mydomainname.com/cable
I followed their guides:
Setting up nginx as a reverse proxy:
https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-reverse-proxy-on-ubuntu-22-04
Encrypting nginx:
https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04
Has anyone had any luck with a similar setup?
I fixed this finally.
I updated my /etc/nginx/sites-available/mydomain.com with these additions. This is in the first server section under server_name
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /cable {
proxy_pass http://127.0.0.1:3000/cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
I also modified my config/production.rb The HOST variable is the domain name of my server.
config.action_cable.url = "wss://#{ENV['HOST']}/cable"
config.action_cable.allowed_request_origins = ["https://#{ENV['HOST']}"]
Setting up a Docker swarm with Rails, Postgres, and Redis on DigitalOcean can be quite a task, and getting Action Cable to cooperate with Puma and Nginx can be tricky.
First, check your Action Cable configuration in your Rails app. Make sure your cable.yml file is correctly set up for production, specifying the correct URL.
Next, verify your Nginx config to ensure it's properly proxying WebSocket connections. Your Nginx setup should allow WebSocket connections and proxy them to your Rails app.
Also, double-check your SSL certificate setup with Let's Encrypt. Sometimes, certificate issues can interfere with WebSocket connections.
Lastly, inspect your server and Rails logs for any specific error messages related to WebSocket connections. This might give you more clues about what's going wrong.
Troubleshooting this kind of setup can be a bit of a maze, but with some patience and detailed investigation, you should be able to get those WebSocket connections up and running. 🐍🚢🔧
All the tutorials I've found use puma for development and then passenger for production. But I wanted my environments to be the same!
Looking at the rails log and searching for /cable helped. The error message there seemed to indicate that nginx wasn't passing the right headers along, so I played around with the /etc/nginx/sites-available/mydomain.com file until something worked (see comment above). I'm not sure if all the settings I added are needed.