1

We're having problem with user login sessions, those are caching due to nginx config file.

Our application developed in cakephp. It is not possible to stop caching the specific file with nginx.

Please find the below nginx conf file and please suggest the best way to handle user login sessions with nginx

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
events {
worker_connections 4024;
}

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;

    #keepalive_timeout   0;
    keepalive_timeout   650;
    types_hash_max_size 2048;

#        gzip         on;
#       gzip_disable "msie6";

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

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    index   index.php;


fastcgi_cache_path /home/main_domain/public_html/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=600m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";


server {
    listen   80;
    server_name main_domain.com;
    rewrite ^ http://www.main_domain.com$request_uri;
}

#server {
#    server_name main_domain.com;
#    return 301 $scheme://www.main_domain.com$request_uri;
#}
server {
    listen   80;
    server_name www.main_domain.com;

    # root directive should be global
    root   /home/main_domain/public_html/;
    index  index.php index.html;

 #   set $no_cache 0;

    access_log /home/main_domain/public_html/access.log;
    error_log /home/main_domain/public_html/error.log;

    location / {
        try_files $uri $uri/ /index.php?$1;
       # proxy_cache my_cache;
       # proxy_pass http://main_domain2.com;
       # proxy_cache_valid  200 302  60m;
       # proxy_cache_valid  404      1m;
    }

location ~* \favicon.ico$ {
        expires 6m;
    }

location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }

    location ~ \.php$ {
        try_files $uri =404;
#        fastcgi_cache my_cache;
#        fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
#        fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
#        add_header X-Fastcgi-Cache $upstream_cache_status;
#        fastcgi_cache_bypass $no_cache;  # Don't pull from cache based on $no_cache
#        fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
#        fastcgi_buffer_size 128k;
#        fastcgi_buffers 256 4k;
#        fastcgi_busy_buffers_size 256k;
#        fastcgi_temp_file_write_size 256k;

   include /etc/nginx/fastcgi_params;
        fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index   index.php;
        fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/$fastcgi_script_name;
fastcgi_read_timeout 300;
    }
}


server {
    listen   80;
    server_name www.subdomain1.main_domain.com;

    # root directive should be global
    root   /home/main_domain/public_html/dev/subdomains/subdomain1/app/webroot;
    index  index.php index.html;

    set $no_cache 0;

#    location /users {
#     try_files $uri $uri/ /index.php?$1;
#     expires off;
#    proxy_no_cache $no_cache;
#    proxy_cache_bypass $no_cache;
    if ($request_uri ~* "/users.*") {
    set $no_cache 1;
      }
#    }





#    if ($request_uri ~* "(/admin|/users|/login)") {
#   set $no_cache 1;
#    }
#    proxy_no_cache $no_cache;
#    proxy_cache_bypass $no_cache;



    access_log /home/main_domain/public_html/dev/subdomains/subdomain1/access.log;
    error_log /home/main_domain/public_html/dev/subdomains/subdomain1/error.log;

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

    location / {
        try_files $uri $uri/ /index.php?$1;
       # proxy_cache my_cache;
       # proxy_pass http://main_domain2.com;
       # proxy_cache_valid  200 302  60m;
       # proxy_cache_valid  404      1m;
    }

location ~* \favicon.ico$ {
        expires 6m;
    }

location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_cache my_cache;
        fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
        fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
        add_header X-Fastcgi-Cache $upstream_cache_status;
        fastcgi_cache_bypass $no_cache;  # Don't pull from cache based on $no_cache
        fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 4k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;


 include /etc/nginx/fastcgi_params;
        fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index   index.php;
        fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/dev/subdomains/subdomain1/app/webroot$fastcgi_script_name;
    }
}


server {
    listen   80;
    server_name subdomain2.main_domain.com;
    rewrite ^ http://www.subdomain2.main_domain.com$1 permanent;
}

server {
    listen   80;
    server_name www.subdomain2.main_domain.com;
    set $mobile_rewrite do_not_perform;

    if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino") {
  set $mobile_rewrite perform;
}

    if ($mobile_rewrite = perform) {
        rewrite ^ http://m.main_domain.com$request_uri? redirect;
        break;
    }  

    # root directive should be global
    root   /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot;
    index  index.php index.html;

 #   set $no_cache 0;

    access_log /home/main_domain/public_html/dev/subdomains/subdomain2/access.log;
    error_log /home/main_domain/public_html/dev/subdomains/subdomain2/error.log;

    location / {
        try_files $uri $uri/ /index.php?$1;
       # proxy_cache my_cache;
       # proxy_pass http://main_domain2.com;
       # proxy_cache_valid  200 302  60m;
       # proxy_cache_valid  404      1m;
    }

location ~* \favicon.ico$ {
        expires 6m;
    }

location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }

#avoid php readfile()
location ^~ /blog {
        internal;
        alias /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot/blog ;
        access_log off; log_not_found off;      expires max;
}

    location ~ \.php$ {
        try_files $uri =404;
#        fastcgi_cache my_cache;
#        fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
#        fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
#        add_header X-Fastcgi-Cache $upstream_cache_status;
#        fastcgi_cache_bypass $no_cache;  # Don't pull from cache based on $no_cache
#        fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
#        fastcgi_buffer_size 128k;
#        fastcgi_buffers 256 4k;
#        fastcgi_busy_buffers_size 256k;
#        fastcgi_temp_file_write_size 256k;


 include /etc/nginx/fastcgi_params;
        fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index   index.php;
        fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot$fastcgi_script_name;
    }
}
miknik
  • 326
  • 1
  • 7
  • It IS possible to stop caching for a specific file, you just need a location that matches that file, and don't configure it to cache. I have some Nginx config files that will give you some great examples, they're for Wordpress but you can adapt them. https://www.photographerstechsupport.com/tutorials/hosting-wordpress-on-aws-tutorial-pt1-introduction-configuration-downloads/#wpmu-nginx-configuration-files – Tim Nov 19 '16 at 20:39

1 Answers1

2

Actually you have provided only a small snippet of your Nginx config but it seems you are mixing up Nginx' cache options. The shown proxy_no_cache option is for Nginx' Web proxy functionality (forwarding a request to another Web server).

Regarding locally hosted static files (e.g. images, css, js ...) please allow Nginx to send proper caching header by using the expires option.

Regarding a PHP application you can use Nginx' FastCGI caching. As you maybe know, Nginx will forward requests to a PHP daemon such as PHP-FPM. The whole PHP magic takes place in this PHP-FPM daemon and Nginx will only get the final response to send it back to the client.

The PHP application can now decide to include caching headers into this response. If caching is allowed (e.g. a public page) PHP may return a Cache-Control header to allow caching.

<?php
...
header('Cache-Control: public, max-age=3600');
...
?>

If caching is not allowed PHP may return a different Cache-Control header to deny caching:

<?php
...
header('Cache-Control: private, no-store, max-age=0');
...
?>

If your PHP application is able to send proper caching header you can use Nginx FastCGI caching by using following config:

fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=phpfpm:64m inactive=24h max_size=512M;

server {
    listen         80;
    server_name    www.mysite.com;

    root   /var/www/xyz;
    index  index.php index.html;

    # check for static files and deliver, for everything else use /index.php
    location / {
        try_files $uri $uri/ /index.php;
    }

    # set caching header for static files
    location ~* \.(jpg|jpeg|gif|png|css|js|ico|svg|ttf)$ {
        access_log          off;
        log_not_found       off;
        expires             30d;
    }

    # set caching header for asset files, don't exec index.php just show 404
    location ^~ /assets/ {
        try_files           $uri =404;
        access_log          off;
        log_not_found       off;
        expires             30d;
    }

    # PHP handler, allow FastCGI caching
    location ~ \.php$ {
        access_log              /var/log/nginx/access.log combined;
        include                 fastcgi_params;
        fastcgi_keep_conn       on;
        fastcgi_pass            unix:/run/php/php5.6-fpm.sock;
        fastcgi_index           index.php;
        fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param           SCRIPT_NAME $fastcgi_script_name;
        fastcgi_cache           phpfpm;
        fastcgi_cache_use_stale updating error timeout invalid_header http_500;
    }
}

If your PHP application is not able to send proper caching headers, you can force caching or overwrite wrong cache headers. Watch out, this may result in publishing private data to the public!

Conclusion

It should be always the web application (here a PHP application) defining which page to cache and which not. Using a web server (Nginx, Apache or whatever) to make this decision is like controlling a car from outside by using crash barriers. It works, but using the steering wheel is smarter.

Jens Bradler
  • 6,133
  • 2
  • 16
  • 13
  • But I use the CAKEPHP Framework . How can i give the file path to specified file from MVC to Nginx server. I want to restrict this file /app/view/xyz.ctp can you anyone pls suggest me – chitroju sai hari Krishna Nov 21 '16 at 06:29
  • Take a look to http://book.cakephp.org/3.0/en/installation.html There is an example of how to use CakePHP with Nginx. And actually please disable the FastCGI caching until everything works fine even without it. Than you can try to accelerate your application by using caching. But keep in mind, that Nginx is not able to know what it should and what it should not to cache. For this Nginx requires proper caching headers by your application. – Jens Bradler Nov 21 '16 at 14:48
  • Yes I disable the NGINX present I am running CAKEPHP caching only. I posted my complete NGINX config file can you please find out solution for this problem .. – chitroju sai hari Krishna Nov 21 '16 at 17:33
  • O My Goodness. I have created a pastebin from your huge Nginx config file. So please remove it from here and add only the link to pastebin: http://pastebin.com/cuqhzMf1 – Jens Bradler Nov 22 '16 at 13:01
  • Based on your configuration I have created a new one with comments about what I have changed. http://pastebin.com/0xy72mQg – Jens Bradler Nov 22 '16 at 13:32