Apache not caching static content - apache

I read the official caching guide of the latest Apache httpd version, but did not understand how to get a minimal caching setup for static content.
Googling around, I finally added these rules to my /etc/apache2/apache2.conf (I'm using Ubuntu):
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
</IfModule>
<IfModule mod_headers.c>
Header set Cache-Control "public"
</IfModule>
FileETag None
Obviously, I already enabled expires, headers, cache modules.
When I try to access an image, a css or js file, I see 200 OK the first time, and 304 the next ones. So, I thought I was right... but Google Pagespeed (for example) still complains about files that are not cached.
Actually, I had some suspects that I'm missing something:
I didn't activate mod_cache or mod_cache_disk. Should I? What's the basic set of rules for doing so?
Why is it necessary to disable the ETag?
I absolutely need my cache to expire suddenly when the file is changed: ideally, the expiration time (for css, js) could be very long, let's say, two weeks, but if the file changes after one hour, the user should mandatory get the updated file! Is that behavior automatically managed by Apache?

I absolutely need my cache to expire suddenly when the file is changed
TWhen you use mod_expires to send an Expires header the client doesn't have to make sure the file is fresh and you can't force a change ever.
If you drop mod_expires, your static files will have an ETAG and a last-modified-time which allows browsers to make sure the file hasn't changed (these are the 304 responses).
You'll need to a) scrutinize the pagespeed messages more closely B) assess them against your requirement and C) look at real world traffic in your access log wrt 304s.
You do not want mod_cache for static files.

Related

Managing/Updating headers in Apache Server

We are using Apache as our Web server for our CRM application (Siebel) . We continuosly deploy new JS and CSS files on the CRM application in 15 days Currently we have the following setting.
FileETag None
ExpiresActive On
<IfModule mod_expires.c>
ExpiresByType text/css "access plus 5 days"
ExpiresByType text/javascript "access plus 5 days"
ExpiresByType image/gif "access plus 5 days"
ExpiresByType image/jpg "access plus 5 days"
ExpiresByType image/png "access plus 5 days"
ExpiresByType application/x-shockwave-flash "access plus 5 days"
ExpiresByType application/x-javascript "access plus 5 days"
AddType image/x-icon .ico
ExpiresByType image/x-icon "access plus 5 days"
</IfModule>
In this case if we have a Hotfix release we have to ask the end users to clear their cache so that the new files can be reflected from their side else they have to wait till the objects expire and are auto refreshed.
If we set it to a lower value than the requests to the web server increase and the load increases on web server.
I would like to know is there any mechanism.
1) To auto update the new files on end user machine automatically when a new file is placed .
2) To set expiration of folder level rather than a file level.
Thanks
In response to point 1)
I'd suggest using versioning at the URL level.
I.E mysite.com/lib/js.js?v=1, mysite.com/lib/style.css?v=1 (etc.. etc..)
When you roll out a new version, update this to v=x (and so on).
There is no way of forcing a client to flush it's cache, mainly due to all the browsers being implemented different (they'd all have to implement this), and it would no doubt be some risk of security.
As for point 2) maybe this question might help:
ServerOverflow - Apache: ExpiresByType per directory?

PHP site not showing cache-control. Not caching anything

INTRO
I have a task to fix existing site's problem that nothing is being cached (except for browser session). When closing session and opening browser again, page loads a lot of images, JS and CSS again. As I have ~60 items every time, there is a big load problem.
PROBLEM
Looking at Chrome console, Audit shows The following resources are missing a cache expiration...
And in Network item in "Response Headers" doesn't even show "cache-control" line.
TRIED SOLUTIONS
I have set info in .htaccess file and made sure mod_expires is active:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
I added Cache-control meta-tag in html head that is also showing in page's code source so it is compiled.
<meta http-equiv="Cache-control" content="public" content="max-age=604800">
And I'd like to add that it most likely isn't a server issue as production page's host has set it to a usual default. (And I don't have access to that server anyways)
I'd be super delighted, if someone could give me some pointers of what I am missing or haven't checked or simply don't understand.
Added main.css headers
Thanks!
You can set the headers through php since this is a php site.
<?php
header("Cache-Control: max-age=2592000"); //30days (60sec * 60min * 24hours * 30days)
?>
Also you can use the FilesMatch like this in your .htaccess
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
Well, although stupid (as I expected), but I didn't read about it anywhere and just forget about the need of it.
Solution
It turned out all those things changed (as I said everything was activated on server, access files etc). And the problem was that I didn't clear the cache after changing caching info. Now after three days I started working on some CSS, needed to reset the cache and boom - all the new headers are active for all the items.

Caching compiled css and js and clears cache on changes in files

I have been going through lots of article, where a proper example for caching mechanism is not penned down. All tutorials describes about that and a single line demo which, I guess, never really optimizes. I have compiled css and js using grunt.
I have included
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
in my .htaccess file.
This, actually says, to cache the content and whenever any changes occur force the browser to use new files.
I do not actually see any changes in DOM Loaded content or in Load Time and everytime, the compiled css and js takes files from server and caches after 5-7 reloading. I guess the cache, which it performs, uses default browser cache.
So How would I use a caching mechanism so that it serves pages quickly and clears the cache when any changes effects the css and JS?
I am using PHP as my application. A better example for doing that with code would be really helpful.

Browser caching after deploy

I have this caching commands on my server:
# BEGIN Expire headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 2 days"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType text/css "access plus 7 days"
ExpiresByType text/javascript "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
</IfModule>
# END Expire headers
I've checked and the caching is working fine. I have Capistrano set up for deploying to server, my question is what will happen after deploy? Will the browser cache the files again because they changed the path on the server or user will have to wait for time to expire?
Thanks...
my question is what will happen after deploy? Will the browser cache the files again because they changed the path on the server or user will have to wait for time to expire?
Unfortunately users will have to wait for browsers to expire the cached data since browsers have no way to know whether these files have changed. However if you can change the src paths of these files then browser will hit the server again and fetch a fresh copy.

Setting ExpiresByType for entire server

I run a server with several websites on it. I would like to implement default cache control behavior for all of these websites. Can I just do this by adding the following code to httpd.conf or must I make the changes in the configuration of each virtual host separately?
<IfModule mod_expires.c>
ExpiresActive on
# Your document html
ExpiresByType text/html "access plus 12 hours"
# Media: images, video, audio
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# CSS and JavaScript
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
# Default
ExpiresDefault "access plus 1 month"
</IfModule>
Documentation can be found in the Apache HTTP Server web site. In the "Documentation" section on the left pane, click on your server version. I'll assume 2.4. Since you are looking for reference on specific directives, you can click on the Directives link. You'll get an alphabetical index.
I won't copy the complete information, just a little sample for ExpiresActive. The important bit is the top table:
Description: Enables generation of Expires headers
Syntax: ExpiresActive On|Off
Default: ExpiresActive Off
Context: server config, virtual host, directory, .htaccess
Override: Indexes
Status: Extension
Module: mod_expires
At "Context" we can read that the directive can be set at several places, including server config. So this answers your question: in theory, it should work. You should check the rest of the directives in order to make sure (or just test it).