Rails 资产子域服务于主页

Posted

技术标签:

【中文标题】Rails 资产子域服务于主页【英文标题】:Rails assets subdomain serving main page 【发布时间】:2017-09-13 03:43:23 【问题描述】:

使用 Rails 4.3。我在production.rb 中有以下行:

# 启用来自资产服务器的图像、样式表和 javascript 服务。 config.action_controller.asset_host = "https://assets.example.com"

以及example.confnginx中的以下内容:

upstream example 
  server unix:/home/deployer/example/shared/tmp/sockets/puma.sock fail_timeout=0;


server 
  listen 80;
  server_name example.com;

  client_max_body_size 4G;
  keepalive_timeout 10;

  error_page 500 502 503 504 /500;

  root /home/deployer/example/current/public;

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

  location @example 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://example;
  

  location = /50x.html 
    root html;
  

  location = /404.html 
    root html;
  

  location @503 
    error_page 405 = /system/maintenance.html;
    if (-f $document_root/system/maintenance.html) 
      rewrite ^(.*)$ /system/maintenance.html break;
    
    rewrite ^(.*)$ /503.html break;
  

  if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ )
    return 405;
  

  if (-f $document_root/system/maintenance.html) 
    return 503;
  

我注意到我的子域 http://assets.example.com 是我的主域 https://example.com 的镜像,而不仅仅是为资产提供服务。例如,https://assets.example.com/blog/1 与 https://www.example.com/blog/1 相同。

如何防止这种情况发生?我只想让https://assets.example.com 提供静态资源。

【问题讨论】:

【参考方案1】:

我认为您应该将您的 nginx server 部分分成两个部分,一个用于 Web,另一个用于静态资产站点。

网络的服务器部分应该与您原来的帖子基本相同,它应该只对完整的主机名做出反应:

server_name www.example.com;

静态站点服务器部分应该是主站点部分的修改副本,主要区别如下:

server_name 应该包含assets.example.com 部分应包含 NO proxy_pass 指令,静态资产旨在静态提供,即直接由 nginx 提供,无需通过 Rails root 将与主站点中的相同 相对而言,资产文件将直接从 root 提供,因此如果您的 URL 中有 /assets/(可能存在),那么应该直接从您的 public/assets 物理地址找到并提供资产目录。

更新:示例 nginx 配置:

upstream example 
  server unix:/home/deployer/example/shared/tmp/sockets/puma.sock fail_timeout=0;


# main site config
server 
  listen 80;
  server_name www.example.com;

  client_max_body_size 4G;
  keepalive_timeout 10;

  error_page 500 502 503 504 /500;

  root /home/deployer/example/current/public;

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

  location @example 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://example;
  

  location = /50x.html 
    root html;
  

  location = /404.html 
    root html;
  

  location @503 
    error_page 405 = /system/maintenance.html;
    if (-f $document_root/system/maintenance.html) 
      rewrite ^(.*)$ /system/maintenance.html break;
    
    rewrite ^(.*)$ /503.html break;
  

  if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ )
    return 405;
  

  if (-f $document_root/system/maintenance.html) 
    return 503;
  


server 
  listen 80;
  server_name assets.example.com;

  client_max_body_size 4G;
  keepalive_timeout 10;

  root /home/deployer/example/current/public;

  location = /404.html 
    root html;
  

  if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ )
    return 405;
  

  if (-f $document_root/system/maintenance.html) 
    return 503;
  

【讨论】:

你能举个例子吗? 更新了我的答案 - 添加了一个示例 nginx 配置,我还意识到您可能根本不需要 try_files 指令,因为这是 nginx 默认服务的方式(来自 root 目录)。 像魅力一样工作!谢谢!

以上是关于Rails 资产子域服务于主页的主要内容,如果未能解决你的问题,请参考以下文章

Rails 3 在子目录中运行,找不到资产

Elastic Beanstalk Passenger-Standalone Rails 不提供静态资产

Rails 3.1 资产 - 奇怪的开发服务

如何通过 https 和 heroku 上的 rails 服务云端资产?

带有 Puma 和 Nginx 服务页面的 Elastic Beanstalk 上预编译资产的 Rails 4 应用程序以及旧资产链接

Rails:预编译资产缺少节点模块