在同一AWS EC2服务器部署Angular5与Rails5.2及图片加载问题咨询
Rails + Angular 部署问题梳理与解决方案
嘿,先给你捋清楚:你的基础部署思路是对的——前后端分离,用Nginx托管静态的Angular生产包,Rails作为后端服务单独运行,这个架构是前后端分离项目的常规操作,但细节上有几个地方需要调整,才能解决进程崩溃和图片加载的问题。
一、部署思路的优化点
你现在遇到的Rails进程自动停止、直接暴露81端口的问题,都是服务管理和网络配置的细节漏洞:
- 你最初用
RACK_ENV=production bundle exec(应该是没写全,比如bundle exec puma -e production?)启动后进程自动挂掉,大概率是因为没让进程在后台稳定运行——直接在SSH终端执行命令,一旦断开连接,进程就会被系统终止。 - 用
rails s &把进程扔后台虽然暂时能用,但这种方式太不靠谱:服务器重启、进程意外崩溃后不会自动恢复,而且没有统一的日志管理,出问题根本没法排查。正确的姿势是用进程管理工具(比如systemd或者Puma自带的守护进程模式)来托管Rails服务,既能保证进程稳定运行、崩溃自动重启,还能方便查看日志。 - 另外,把Rails直接暴露在81端口其实不太安全,更优雅的做法是让Rails监听本地端口(比如
127.0.0.1:3000),然后通过Nginx做反向代理,把前端的API请求转发过去——这样不需要对外开81端口,还能统一处理跨域、请求头这些问题。
二、图片加载失败的解决方案
你说的site_url/path_to_file无法加载图片,主要是Nginx和Rails的静态资源处理逻辑没对齐,分两种情况来解决:
情况1:图片存在Rails的public目录下
如果你的上传逻辑是把图片存在Rails的public文件夹里,那问题出在Nginx没正确映射这个路径:
- 先确认Rails生产环境配置里的静态资源设置:
打开config/environments/production.rb,确保有这行:# 如果让Rails自己处理静态资源,设为true;如果让Nginx直接托管public目录,设为false更高效 config.public_file_server.enabled = true - 调整Nginx的Angular站点配置,添加静态资源的映射规则:
比如你的图片存在public/uploads下,就在Nginx配置里加:
改完配置后记得重启Nginx:# 匹配图片请求路径,直接指向Rails的public目录 location /uploads { root /path/to/your/rails/app/public; # 如果Nginx找不到文件,再转发给Rails处理 try_files $uri @rails_proxy; } # 反向代理到本地运行的Rails服务 location @rails_proxy { proxy_pass http://127.0.0.1:3000; # 传递必要的请求头,避免Rails出现域名、IP识别问题 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; }sudo systemctl restart nginx
情况2:用Active Storage存到AWS S3(如果是这种情况)
如果你的Rails用了Active Storage把图片存在S3,那问题可能是生产环境配置不对:
- 检查
config/storage.yml里的S3配置,确保生产环境的参数正确:production: service: S3 access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> region: 你的S3区域(比如us-east-1) bucket: 你的桶名 - 确认
config/environments/production.rb里指定了生产环境用S3存储:config.active_storage.service = :production - 还要检查S3桶的权限,确保允许公开读取(如果是私有桶的话,要让Rails生成预签名URL给前端)。
三、让Rails服务稳定运行的正确配置
为了彻底解决Rails进程自动停止的问题,推荐用systemd来管理Puma进程,步骤如下:
- 创建一个
systemd服务文件,比如/etc/systemd/system/rails-api.service:[Unit] Description=Rails API 服务 After=network.target [Service] User=ec2-user # 替换成你的服务器用户名,比如ubuntu或者ec2-user WorkingDirectory=/path/to/your/rails/app # 替换成你的Rails项目根目录 Environment="RAILS_ENV=production" Environment="SECRET_KEY_BASE=你的生产环境密钥" # 从Rails的config/secrets.yml或者credentials里获取 # 替换成你的bundle路径,比如用rbenv的话就是/home/ec2-user/.rbenv/shims/bundle ExecStart=/home/ec2-user/.rbenv/shims/bundle exec puma -e production -b tcp://127.0.0.1:3000 Restart=always # 进程崩溃自动重启 [Install] WantedBy=multi-user.target - 重新加载
systemd并启动服务:sudo systemctl daemon-reload sudo systemctl start rails-api.service sudo systemctl enable rails-api.service # 设置开机自启 - 可以通过以下命令查看服务状态和日志:
sudo systemctl status rails-api.service # 查看当前状态 sudo journalctl -u rails-api.service -f # 实时查看日志,排查问题很有用
总结一下:你的核心部署方向没问题,只要把Rails的进程管理换成systemd,调整Nginx的静态资源映射规则,就能解决进程自动停止和图片加载的问题啦~
内容的提问来源于stack exchange,提问作者CR7
相关产品推荐
相关产品推荐

