What is the best way to set up server caching on Apache 2.4?
I have searched the internet and found a few resources and tutorials specific to Apache 2.2 - but apache have dropped modules since 2.2 and renamed others. Specifically, I would like to set up caching on my Ubuntu environment using the equivalent of Apache 2.2 "mod_cache", "mod_disk_cache" and "mod_mem_cache".
For example, existing documentation refers to enabling: mod_cache, mod_disk_cache and mod_mem_cache
In my /etc/apache2/mods-available directory and the mods there that seem relevant are: cache and cache_disk (notice different naming conventions), also there is nothing even similar to mem_cache (there are other references to socache etc but those are different)
Here's a good resource that's helped me get this far here (and another). The apache documentation does a decent job of explaining what the modules do but not HOW to set them up.
UPDATE: I'm running Ubuntu 14.01.1 LTS Found confirmation that apache removed mem_cache in 2.4 - still looking for any up to date cache resources/ tutorials though
UPDATE2: It seems there are actually no resources out there specifically for configuring caching on apache 2.4, so here are the steps I've taken so far which may help future searches:
#Check which modules are available
ls /etc/apache2/mods-available
#Enable cache modules
sudo a2enmod cache
sudo a2enmod cache_disk
#restart apache
sudo service apache2 restart
#edit the cache_disk.conf file
sudo vim /etc/apache2/mods-available/cache_disk.conf
uncomment the line CacheEnable /disk so that the conf file looks like:
<IfModule mod_cache_disk.c>
# cache cleaning is done by htcacheclean, which can be configured in
# /etc/default/apache2
#
# For further information, see the comments in that file,
# /usr/share/doc/apache2/README.Debian, and the htcacheclean(8)
# man page.
# This path must be the same as the one in /etc/default/apache2
CacheRoot /var/cache/apache2/mod_cache_disk
# This will also cache local documents. It usually makes more sense to
# put this into the configuration for just one virtual host.
CacheEnable disk /
# The result of CacheDirLevels * CacheDirLength must not be higher than
# 20. Moreover, pay attention on file system limits. Some file systems
# do not support more than a certain number of inodes and
# subdirectories (e.g. 32000 for ext3)
CacheDirLevels 2
CacheDirLength 1
</IfModule>
restart apache again for changes to take effect
sudo service apache2 restart
Next we need to make sure when the cache fills up it's cleaned using an apache utility and configuring htcacheclean:
aptitude install apache2-utils
#cleans the cache every 30 min and makes sure it doesnt get bigger than 100M
htcacheclean -d30 -n -t -p /var/cache/apache2/mod_disk_cache -l 100M -i
#configure htclean to start every time the server restarts
sudo vim /etc/rc.local
#add the following lines before the exit 0 line
[...]
/usr/sbin/htcacheclean -d30 -n -t -p /var/cache/apache2/mod_disk_cache -l 100M -i
[...]
...And that's as far as I've managed to get so far.
UPDATE 3: I've tried testing in a browser using a new file test.php:
<?php
header("Cache-Control: must-revalidate, max-age=300");
header("Vary: Accept-Encoding");
echo time()."<br>";
?>
I should be able to hit return on the url a 2nd time and the timestamp should not have changed, but this isn't the case so I think I've missed something/ not completed this.
Above article is almost perfect, also this one might help: http://www.jonasjohn.de/snippets/php/caching.htm
But still you'll probably face problems like "CACHE MISS, ATTEMMPTING ENTITY SAVE" or no caching at all.
First of all it seems caching does not work if Content-length is unknown. So if caching is not working for your script, turn on cache headers and check all headers first. Otherwise you might get always X-Cache-Detail: "cache miss: attempting entity save".
Easiest way how to determine if cache is working is probably:
curl -s -D - http://xxx.yyy.com/yorsite | head -n 15
Then you see if cache hit occurs after second try and all other headers sent. Adjust -n parameter to how many lines your headers have in particular case.
Of course setting logging for mod_cache might help.
LogFormat "%h %l %u %t \"%r\" %{cache-status}e %>s %b" cache
CustomLog ${APACHE_LOG_DIR}/mod_cache.log cache
Setting proper session_cache_limiter is important (to "" or "public", "must_revalidate", try it...)
To summarize common issues with cachig (for Apache 2.4.7) are:
So for caching of dynamic content (php etc) you probably need to do:
ob_start();
...your code...
$PageContent = ob_get_contents();
ob_end_clean();
// Set header for content length
header('Content-Length: ' . strlen($PageContent));
// Send the full content
print $PageContent;
Then, you can enjoy boost of performance :)
Finally working configuration:
<VirtualHost *:80>
ServerName devel.artikul.cz
DocumentRoot /var/www/xxx.com
ErrorLog ${APACHE_LOG_DIR}/xxx.com.log
CustomLog ${APACHE_LOG_DIR}/xxx.com.access.log combined
LogFormat "%h %l %u %t \"%r\" %{cache-status}e %>s %b" cache
CustomLog ${APACHE_LOG_DIR}/mod_cache.log cache
CacheQuickHandler off
CacheRoot /var/cache/apache2/mod_cache_disk
CacheIgnoreHeaders Set-Cookie
CacheLock on
CacheLockPath /tmp/mod_cache-lock
CacheLockMaxAge 5
CacheDetailHeader on
#example disk caching
CacheEnable disk "/xxxx.php"
CacheEnable disk "/blog"
CacheEnable disk "/content"
CacheHeader on
CacheDefaultExpire 600
CacheMaxExpire 86400
CacheLastModifiedFactor 0.5
CacheMaxFileSize 1000000
CacheMinFileSize 1
ExpiresActive on
ExpiresDefault "access plus 5 minutes"
Header merge Cache-Control public
FileETag All
</VirtualHost>