I have a nginx + thin + Rails 3.2 setup. Currently I am trying to setup nginx so it can serve cached pages directly.
However nginx still pass *.html request to Rails in the following nginx configuration files. The html files exists in public folder, and nginx does find them, just that they are still passed to Rails.
upstream site {
server unix:/home/site/deploy/site/shared/pids/thin.0.sock;
}
server {
listen 80;
server_name www.example.com;
rewrite ^(/.*) http://example.com$1 permanent;
}
# asset server
server {
listen 80;
server_name assets.example.com;
expires max;
add_header Cache-Control public;
charset utf-8;
root /home/site/deploy/site/current/public/;
}
# frontend
server {
listen 80;
server_name .example.com;
charset utf-8;
root /home/site/deploy/site/current/public/;
index index.html;
location ~* ^.+.(jpg|jpeg|gif|png|swf|zip|rar|doc|xls|exe|pdf|ppt|txt|tar)$ {
root /home/site/deploy/site/current/public/;
expires max;
break;
}
# serve static files
if (-f $request_filename) {
break;
}
gzip on;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (-f $request_filename) {
break;
}
if (-f $document_root/cache/$host/$uri/index.html) {
rewrite (.*) /cache/$host/$1/index.html break;
}
if (-f $document_root/cache/$host/$uri.html) {
rewrite (.*) /cache/$host/$1.html break;
}
if (-f $document_root/cache/$host/$uri) {
rewrite (.*) /cache/$host/$1 break;
}
proxy_pass http://site;
break;
}
}
I am new to nginx, and this configuration file is copied from previous projects I have not worked on, so this is probably a very newbie question.
To allow nginx to serve static cached pages you need to use try_files, let me share the config:
Here is a more general theoretical answer (SO editors rejected my edit to explain in the answer above.):
Nginx has a
ngx_static
module which is on by default. This module runs at end of the content phase. It will serve static files if no other content command in that location block can work in the request. It will also only work if the uri does not end with slash.So to serve static files, one need to make sure the uri is a valid path name by the end of content phase, and there is no other content phase command that can serve stuff in the same location block.
In my case, I want to access cached page, I can use
try_files
to rewrite the uri.try_files
works in a phase just before the content phase, which will check for existence of files. If one of them exist, then the uri is changed to that file. Then in the content phase it will be served.What if I want to serve static file if it exists, or serve dynamic content if it does not? Usually serving dynamic content will prevent static file to be served. In this case a different location block can be used. If no static file is found during
try_files
, we jump to another location block (in the example@thin
, where all dynamic contents are served. But if static file exists, we stay in the original location block, and as we enter the content phase, since there is no other content serving command, the static file is served.