Nginx – Adding Cache-Control to Nginx for images, css, js, and fonts

cachenginx

I'm trying to get Cache-Control working on Nginx for assets on my server and it is not taking as expected. Here is my server config for Nginx.

Everything but Cache-Control is working.

Server Blocks

server {
   listen 80;
   server_name www.example.com;
   rewrite ^ https://$server_name$request_uri? permanent;
}

server {
   listen 80;
   server_name example.com;
   rewrite ^ https://www.$server_name$request_uri? permanent;
}

server {
   listen 443 ssl;
   server_name default;
   root /app/public;

   ssl_certificate /etc/nginx/ssl/default/crt/server.crt;
   ssl_certificate_key /etc/nginx/ssl/default/crt/server.key;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   index index.html index.htm index.php;
   charset utf-8;
   add_header "X-UA-Compatible" "IE=Edge,chrome=1";

   location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
       expires 1d;
       access_log off;
       add_header Pragma public;
       add_header Cache-Control "public, max-age=86400";
       add_header X-Asset "yes";
   }

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

   location = /favicon.ico { access_log off; log_not_found off; }
   location = /robots.txt { access_log off; log_not_found off; }
   access_log off;
   error_log /var/log/nginx/default-error.log error;

   error_page 404 /index.php;
   location ~ \.php$ {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
      fastcgi_index index.php;
      include fastcgi_params;
   }

   location ~ /\.ht {
      deny all;
   }
}

Here is my server's response for https://www.example.com/icons/facebook.png:

Accept-Ranges:bytes
Cache-Control:public, max-age=120
Connection:keep-alive
Content-Length:416
Content-Type:image/png
Date:Tue, 04 Oct 2016 14:46:26 GMT
ETag:"57f2a0fd-1a0"
Last-Modified:Mon, 03 Oct 2016 18:18:37 GMT
Server:nginx/1.11.2

The max-age is 120 where I am expecting 86400 and there is no custom X-Asset header too.

HTTP Block

The /etc/nginx/conf.d/ folder is empty.

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 5;
    # gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Best Answer

Is your origin sending back a Cache-Control header? Or is this one of the files that would be served directly from file system.

If so, perhaps you just have not reloaded nginx after the change? sudo nginx -s reload

Separate from your direct question, but just a note that the line:

add_header "X-UA-Compatible" "IE=Edge,chrome=1";

won't apply on any location that contains it's own add_header directive (you can see this in your pasted output).