如何在使用 puma/nginx 时服务于位于 /public 目录中不属于 asset pipeline 的 assets?

17

这是一个AWS问题,我正在使用Ruby 2.2(Puma)平台。

我的已编译资产(在/public/assets中)按预期提供服务。 /public中的其他资产未被提供服务(404)。

我应该在哪里进行配置?这是一个nginx问题吗?还是一个puma问题?

还是这只是一个AWS映像问题?

这里有一个实时示例(robots.txt应该从根目录提供服务):http://staging.us-west-2.elasticbeanstalk.com/public/robots.txt

值得一提的是,默认的Passenger平台映像可以直接使用。


2
你能告诉我们 public 目录中其他资源的名称/位置吗? - Richard Peck
1
你是指像422.html、500.html、favicon.ico这样的文件吗? - chrisp
1
是的,你说你有一些资产在公共目录中不会显示,但有些会显示。为了进行有效的比较,我需要知道你有哪些不会显示的资产。 - Richard Peck
编译过的文件(/public/assets)可以正常访问。其他列出的文件则无法访问。 - chrisp
2
我通过修复由AWS提供的nginx配置来解决了这个问题。(AWS的默认配置是错误的 - 客观上,它是错误的。)AWS社区支持论坛上有一个关于此问题的帖子。已经过去几个月了,所以我没有直接的链接给你。像底部答案那样,有些人选择让Rails服务于资产。我不喜欢这样做。所以我让nginx或[您的Web服务器]来处理静态资产服务。SO答案:https://dev59.com/RnrZa4cB1Zd3GeqP46SV - chrisp
显示剩余2条评论
3个回答

7

如果有需要帮助的人或者知道如何改进的人,这是让我最终成功工作的nginx配置。在/.ebextensions/01_files.config中:

files:
    "/etc/nginx/conf.d/webapp_healthd.conf" :
        mode: "000755"
        owner: root
        group: root
        content: |
            upstream my_app {
              server unix:///var/run/puma/my_app.sock;
            }

            log_format healthd '$msec"$uri"'
                            '$status"$request_time"$upstream_response_time"'
                            '$http_x_forwarded_for';

            server {
              listen 80;
              server_name _ localhost; # need to listen to localhost for worker tier
              root /var/app/current/public;

              if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
                set $year $1;
                set $month $2;
                set $day $3;
                set $hour $4;
              }

              access_log  /var/log/nginx/access.log  main;
              access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

              try_files $uri/index.html $uri @my_app;

              location @my_app {
                proxy_pass http://my_app; # match the name of upstream directive which is defined above
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              }

              location /assets {
                alias /var/app/current/public/assets;
                gzip_static on;
                gzip on;
                expires max;
                add_header Cache-Control public;
              }
            }
    "/opt/elasticbeanstalk/hooks/appdeploy/post/03_restart_nginx.sh":
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/usr/bin/env bash
            rm /etc/nginx/conf.d/webapp_healthd.conf.bak
            rm /etc/nginx/conf.d/custom.conf            
            service nginx restart

我一开始有些犹豫,因为如果EB对这个文件进行了一些更改,那么我就得重新修改。但是,由于我需要对EB nginx配置进行其他几个修改,所以最终我还是采用了这种方法。 - Eric Walker
这个对你还管用吗?我也处于同样的情况,调整nginx配置似乎没有效果。不太清楚哪些nginx文件实际上被用来做什么。我修改了你上面的那个 - 通过ssh验证它是否有效,在重启nginx后,还没有成功。 - Ricky Brown
@RickyBrown 是的,我还在工作。不幸的是,我没有建议给你。 - thebenedict

7

所以,我正在使用完全相同的环境,并且通过一些谷歌搜索找到了解决方案:

在Rails 4+中,文件如下:

/config/environments/production.rb

您应该在文件顶部附近找到以下行。
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?

既然我们正在使用Passenger(nginx或apache),那就没问题了,但Puma不会为我们处理这个问题 :)

为了解决这个问题...

在AWS控制台中,转到所涉项目的弹性Beanstalk仪表板,并在左侧菜单中单击“配置”。

现在,在名为“软件配置”的框中单击小齿轮图标

现在,您应该看到“环境属性”下的一个表格,在“属性名称”下输入“RAILS_SERVE_STATIC_FILES”,然后在值字段中键入“true”(不带引号),并单击应用。

瞧!现在您的项目正在提供静态文件 :)


8
生产环境下应用服务器不应提供静态资源。让请求静态文件的任务落到Rails应用上效率不高。更多信息请见http://guides.rubyonrails.org/configuring.html。 - thebenedict

-3

我只需要运行bundle exec rake assets:precompile


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接