NginX fast CGI don’t cache static file

fastcginginx

I configure fastCGI to cache with NginX. It work with .php file, but i can't cache static file like .jpg, .mp4…

My infomation when check with cURL:

curl -I http://192.168.1.223/music.php
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 07 Dec 2015 20:21:48 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.3.3
X-Cache: HIT

curl -I http://192.168.1.223/b2.jpg
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 07 Dec 2015 20:24:51 GMT
Content-Type: image/jpeg
Content-Length: 18103
Last-Modified: Mon, 07 Dec 2015 20:06:27 GMT
Connection: keep-alive
ETag: "5665e6c3-46b7"
Expires: Fri, 05 Feb 2016 20:24:51 GMT
Cache-Control: max-age=5184000
Accept-Ranges: bytes

My NginX config:

user nginx nginx;
worker_processes 1;
lock_file /run/lock/nginx.lock;


events {
    worker_connections 1024;
}

rtmp {
    server {
        listen 1935;
        application pullfromwowza {
           live on;
           pull rtmp://192.168.1.222:1935/vod;
        }
     }
}

http {
    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay off;
    keepalive_timeout 5;

    #include /etc/nginx/mime.types;
    default_type application/octet-stream;

    #gzip on;
    #gzip_static on;
    #gzip_comp_level 2;
    #gzip_disable "msie6";
    #gzip_proxied any;
    #gzip_types application/javascript application/json application/vnd.ms-fontobject application/x-font-ttf image/svg+xml #text/css text/plain text/xml;
    #gzip_vary on;

    fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=fastcgicache:200m inactive=200m max_size=640m;
    fastcgi_cache_key $scheme$request_method$host$request_uri;
    # note: can also use HTTP headers to form the cache key, e.g.
    #fastcgi_cache_key $scheme$request_method$host$request_uri$http_x_custom_header;
    fastcgi_cache_lock on;
    fastcgi_cache_use_stale error timeout invalid_header updating http_500;
    fastcgi_cache_valid 5m;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

    index index.php;


    server {
        listen   80;

        server_name example.com;


 root /usr/local/nginx/html;
        #root /var/www/example.com;
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        # example FastCGI cache exception rules
        set $fastcgi_skipcache 0;

        if ($query_string) {
            set $fastcgi_skipcache 1;
        }

    if ($http_x_custom_header) {
            set $fastcgi_skipcache 0;
        }

        if ($uri ~ "/path/matches/") {
            set $fastcgi_skipcache 1;
        }

        if ($http_cookie ~ "users_login_cookie") {
            set $fastcgi_skipcache 1;
        }

        #include /etc/nginx/conf/phpfastcgicache;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ "\.php$" {
            fastcgi_index index.php;
            if (!-f $document_root$fastcgi_script_name)
            {
                return 404;
            }
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

            # note: adds a HTTP response header "X-Cache" returning HIT/MISS/BYPASS/EXPIRED for cache use status
            add_header X-Cache $upstream_cache_status;
            fastcgi_cache fastcgicache;
            fastcgi_cache_bypass $fastcgi_skipcache;
            fastcgi_no_cache $fastcgi_skipcache;

            include /usr/local/nginx/conf/fastcgi_params;
             fastcgi_pass 127.0.0.1:9000;
     #   fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
        location ~* \.(?:manifest|appcache|html?|xml|json)$ {
  expires -1;
  # access_log logs/static.log; # I don't usually include a static log
}

# Feed
location ~* \.(?:rss|atom)$ {
  expires 1h;
  add_header Cache-Control "public";
}

# Media: images, icons, video, audio, HTC
  location ~* \.(jpg|jpeg|gif|css|png|js|ico|gz) {
            expires 60d;

           # proxy_pass http://192.168.11.11:8888;
           # proxy_redirect     off;

            #proxy_set_header   Host             $host;
           # proxy_set_header   X-Real-IP        $remote_addr;
           # proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            fastcgi_cache fastcgicache;
           # proxy_cache_key "$request_method|$host|$request_uri";
           # proxy_cache_valid 1d;
      }

# CSS and Javascript
location ~* \.(?:css|js)$ {
  expires 1y;
  access_log off;
  add_header Cache-Control "public";
}
    }
}

Thanks !

Best Answer

I would like to complete other answers.

Saying the a file is already cached because it's on disk is not a satisfactory answer. For exemple, Apache2 is very slow at serving static files that are on disk, thus a proxy cache as nginx or varnish totally makes sense for a high trafic website.

In nginx case, it is designed to be very efficient to serve static content.

But you should ensure you have "sendfile on" enabled (it is the case in your configuration). Senfile() replace the classe couple read()/write() at kernel level and makes the files access very quick.

The quickness is high enough to be as performant as if the content was cached.

By the way I recommand you to enable tcp_nodelay as well. It allows nginx to send a short TCP packet immediately if there is no other data expected.

See also: