简体   繁体   中英

Rails page cache multiple servers with nginx unicorn

I am using the page caching gem on Rails 4. I have a web server running nginx, app server running unicorn and rails, and db server running postgre.

When page cache is generated on the app server, nginx will not serve the static files. Only after I set

config.serve_static_assets = true

where the page cache will work in production. I don't think this is ideal though given that now rails is serving the static file.

How do I get nginx to serve my page caches located on the app server?

Here is my nginx config:

upstream unicorn {
  server <%= app_private_ip %>:8080 fail_timeout=0;
}

server {

  # listen [::]:80 ipv6only=on default_server;

  listen 80 default deferred;
  server_name <%= domain %>;
  # rewrite ^(.*) https://<%= domain %>$1 permanent;


  root <%= current_path %>/public;
  sendfile on;

  if (-f $document_root/system/maintenance.html) {
    return 503;
  }
  error_page 503 @maintenance;
  location @maintenance {
    rewrite  ^(.*)$  /system/maintenance.html last;
    break;
  }

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;
  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
  server_tokens off;

}

server {
  listen                443;
  server_name           <%= domain %>;
  ssl                   on;
  ssl_certificate       /home/<%= user %>/ssl/<%= domain %>.pem;
  ssl_certificate_key   /home/<%= user %>/ssl/<%= domain %>.key;


  root <%= current_path %>/public;
  sendfile on;

  if (-f $document_root/system/maintenance.html) {
    return 503;
  }
  error_page 503 @maintenance;
  location @maintenance {
    rewrite  ^(.*)$  /system/maintenance.html last;
    break;
  }


  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;
  location @unicorn {
    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 https;
    proxy_set_header  Host $http_host;
    proxy_redirect    off;
    proxy_pass        http://unicorn;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
  server_tokens off;
}

The nginx try_files directive lets you set cascading ways to resolve the static file for a URI in different locations/backends.

It looks like you need to move your try_files directive into a location block for it to work properly:

location / {
  try_files $uri @unicorn;
}

This should tell nginx to try resolve paths locally by URI before passing the request to your unicorn backend.

The page caching gem asks you to set the cache directory to 'public/cache' in application.rb;

config.action_controller.page_cache_directory = "#{Rails.root.to_s}/public/cache"

so your try_files line should be;

try_files /cache/$uri/index.html /cache/$uri @unicorn;

otherwise you can just set the page_cache_directory to; "#{Rails.root.to_s}/public" and not change your current nginx config.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM