0

I'm in the process of moving some Joomla sites that I host onto a LEMP stack from a LAMP stack. I've followed a guide to get FastCGI Cache up and running, and with a single time.php file in the document root, I can see that the caching is working.

However, when I load my Joomla site from the same web server, the cache isn't coming into action.

If I use CURL to analyse the headers when visiting the home page of the Joomla site, I can see the following:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
X-Cache: MISS

That last X-Cache entry is a custom header I added as part of the guide, just to indicate whether the cache is being utilised. However, the other two entries must be generated by Joomla at some point, and it seems as if this has something to do with the fact that the cache is not being used. (Those two lines are missing when I CURL the time.php file I mentioned earlier, since that's not part of the Joomla site.)

I'm aware that there is probably something Joomla-specific going on here, and so I'll be asking a how I can change Joomla's behaviour on the Joomla forums.

My question for SE is slightly different: Are the Cache-Control and Pragma entries responsible for stopping my site from using the FastCGI cache, and is there anything I can add to the nginx conf file that will remove these entries?

Rob Methven
  • 38
  • 1
  • 4
  • Are you logged in to Joomla? Try browsing while not logged in (e.g. from a private browsing window). Most CMSes disable caching for logged in users for their privacy. – Michael Hampton Dec 16 '18 at 21:09

1 Answers1

1

Two questions, two answers:

Are the Cache-Control and Pragma entries responsible for stopping my site from using the FastCGI cache?

Yes, they are.

Actually it's the "Cache-Control" header. The "Pragma" header was never designed to be a HTTP response header (should be only a HTTP request header) in the good old times of HTTP 1.0.

Is there anything I can add to the Nginx conf file that will remove these entries?

Yes, you can - but maybe you shouldn't.

Caching private content could result in a disaster as you could show the CMS admin panel every unknown visitor. You have to check if the CMS creates for each visitor a new session or if this is only for backend users. If the CMS creates a session for each visitor I would recommend not to cache. If this is not the case but the CMS provides these "not cacheable" header, you can overwrite this behavior with Nginx.

In my humble opinion you shouldn't overwrite in the web server what programmers have done in the CMS code. But we don't live in a perfect world. There are too little good CMS coders knowing what they are doing regarding the Cache-Control header.

The overwrite I describe here ignores the Cache-Control header of the CMS as long as there is no session cookie. So it would be possible to cache public pages. But if a client opens the login page of the backend a session will be started and a session cookie will be set. All subsequent requests of this client will be answered without using cached data because of the session-cookie.

How to overwrite:

1) You have to identify the name of the session cookie (e.g. PHPSESSID).

2) Adapt your Nginx config. See my example below:

# deliver static files or handle URL by CMS
location / {
    try_files               $uri @php;
}

# execute directly addressed PHP files
location ~ \.php$ {
    try_files               /467e1r1afrptaubui2oum6r95ssy9zbe.htm @php;
}

# common php handler
location @php {
    try_files               $uri /index.php?url=$uri&$query_string;

    include                 fastcgi_params;

    fastcgi_pass            unix:/run/php/php7.2-fpm.sock;
    fastcgi_index           index.php;
    fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param           SCRIPT_NAME      $fastcgi_script_name;

    # caching
    fastcgi_cache           phpfpm;
    fastcgi_cache_key       "$request_method $scheme://$host$request_uri";
    fastcgi_cache_use_stale updating error timeout invalid_header http_500;
    # overwrite: cache web pages and permanent redirects for one hour
    fastcgi_cache_valid     200 301 3600s;

    # pass header Set-Cookie and Cookie
    fastcgi_pass_header     Set-Cookie;
    fastcgi_pass_header     Cookie;
    # ignore header Cache-Control, Expires and Vary
    fastcgi_ignore_headers  Cache-Control Expires Vary;
    # hide headers Expires, Pragma, Vary
    fastcgi_hide_header     Expires;
    fastcgi_hide_header     Pragma;
    fastcgi_hide_header     Vary;

    # do not cache if cookie PHPSESSID exists
    fastcgi_no_cache        $cookie_PHPSESSID;
    fastcgi_cache_bypass    $cookie_PHPSESSID;
}

3) Test your setup.

Jens Bradler
  • 6,503
  • 2
  • 17
  • 13