本地服务器部署带ActionCable的Rails 5应用:Nginx+Puma+SSL问题
嘿,我之前在本地部署过几乎一模一样的Rails 5 + Puma + Nginx + ActionCable + SSL的环境,踩了不少坑,给你整理下关键的配置和排查步骤,应该能解决你遇到的问题:
1. 先搞定Puma的生产环境配置
Puma的生产配置很容易和开发环境搞混,先确保config/puma.rb的生产参数是对的:
- 推荐用Unix Socket(比TCP更高效),配置示例:
environment 'production' bind "unix://#{Rails.root}/tmp/sockets/puma.sock" pidfile "#{Rails.root}/tmp/pids/puma.pid" state_path "#{Rails.root}/tmp/pids/puma.state" workers 2 # 根据本地CPU核心数调整,本地测试1个也够用 threads 4, 8 - 启动Puma一定要指定生产环境:
RAILS_ENV=production bundle exec puma -C config/puma.rb - 先单独测试Puma能不能正常运行:用
curl -k http://127.0.0.1:3000(如果用TCP绑定的话),或者先跳过SSL直接测基础连接,没问题再往下走。
2. Nginx反向代理+SSL配置
本地SSL需要自签证书,先生成证书文件:
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt
把生成的localhost.key和localhost.crt放到/etc/nginx/ssl/目录,记得改权限:sudo chmod 600 /etc/nginx/ssl/*
然后配置Nginx的server块(路径一般是/etc/nginx/sites-available/your_app.conf),重点注意ActionCable的WebSocket升级配置,我当初就是漏了这个卡了好久:
server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/localhost.crt; ssl_certificate_key /etc/nginx/ssl/localhost.key; root /path/to/your/rails/app/public; passenger_enabled off; # 禁用Passenger,因为我们用Puma # 主应用反向代理 location / { proxy_pass http://unix:/path/to/your/rails/app/tmp/sockets/puma.sock; 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; } # ActionCable专属配置,必须加这几行才能建立WebSocket连接 location /cable { proxy_pass http://unix:/path/to/your/rails/app/tmp/sockets/puma.sock; 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; proxy_set_header X-Forwarded-Proto $scheme; } # 静态资源直接让Nginx处理,提升性能 location ~* ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break; } } # 把HTTP请求强制重定向到HTTPS server { listen 80; server_name localhost; return 301 https://$host$request_uri; }
配置完后先检查语法:sudo nginx -t,没问题再重启Nginx:sudo systemctl restart nginx
3. ActionCable生产环境关键配置
- 确保
config/cable.yml的生产适配器配置正确,本地测试用async足够,要是后续需要更稳定的可以换Redis:production: adapter: async # 要是装了Redis可以换成下面的配置 # adapter: redis # url: redis://localhost:6379/1 - 在
config/environments/production.rb里指定ActionCable的WS地址,并允许本地域名访问:config.action_cable.url = 'wss://localhost/cable' config.action_cable.allowed_request_origins = [/https?:\/\/localhost(:\d+)?/] - 别忘了预编译生产环境的静态资源:
RAILS_ENV=production bundle exec rails assets:precompile,不然页面加载不了ActionCable的JS文件。
4. Curl测试的注意事项
因为是自签SSL证书,curl会默认拒绝连接,测试时要加-k参数忽略证书验证:
curl -k https://localhost
要是想测试ActionCable的WebSocket连接,可以用wscat(先装npm install -g wscat):
wscat -c wss://localhost/cable --no-check
5. 最后排查权限问题
- 确保Rails应用目录的权限给Nginx和Puma的运行用户(一般是
www-data):sudo chown -R www-data:www-data /path/to/your/rails/app tmp/sockets/、tmp/pids/、log/这些目录需要读写权限,手动创建并授权:mkdir -p tmp/sockets tmp/pids && chmod 775 tmp/sockets tmp/pids
内容的提问来源于stack exchange,提问作者AlexB
相关产品推荐
相关产品推荐

