File change on a LAMP development server not taken into account

I set up a small LAMP virtual machine for PHP development.

It works fine, excepted that when an image which has already been served is modified on disk, then requested again, the "old" image is still being served (I get a 304 Not Modified answer from apache2). This caching behaviour is desirable on a server, but is a pain on a development environment where files are frequently edited.

The only (inconvenient) ways I found to access the new file content are:

  1. rebooting the VM,
  2. or issuing sync; echo 3 > /proc/sys/vm/drop_caches

Is there an apache directive I can use to ensure that apache will check if a file has changed on disk each time it is requested?

Update : Loaded Apache modules:

# apache2ctl -t -D DUMP_MODULES
Loaded Modules:
 core_module (static)
 log_config_module (static)
 logio_module (static)
 mpm_prefork_module (static)
 http_module (static)
 so_module (static)
 alias_module (shared)
 auth_basic_module (shared)
 authn_file_module (shared)
 authz_default_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 php5_module (shared)
 setenvif_module (shared)
 status_module (shared)
Syntax OK

Edit: actually, my DocumentRoot is stored on a shared VirtualBox folder. It seems like when a file is overwritten, the virtualbox module does not notify linux to invalidate its cache. Hence the counterintuitive behavior. When I perform the same overwriting operation on a "regular" linux directory, no such thing happen.


Solution 1:

OK, I found the explanation on a VirtualBox ticket: the "sendfile" optimization seems not to be implemented by the vboxsf module.

Until this issue is fixed, a workaround is to use this Apache directive :

EnableSendfile Off 

Using this, server-side images changes are taken into account immediately.

Solution 2:

Since this is a development server only, where files changes often, the easiest solution is to disable caching entirely for the server (or at least for the VirtualHost responsible for the website being modified). You can use the CacheDisable Directive to instruct mod_cache in Apache to handle this.

The CacheDisable directive instructs mod_cache to not cache urls at or below url-string.

CacheDisable /local_files

Other options include looking at the available directives for mod_disk_cache and mod_mem_cache and using them to control caching on your server. You can also run htcacheclean as a daemon to control/limit the disk cache used by mod_disk_cache.

Update: If mod_cache is not enabled, then the above directives will not work. It also means that any caching is being done at the operating system level instead of Apache - as far as I know only mod_cache (with mod_mem_cache/mod_disk_cache) or mod_file_cache are the only two ways to accomplish caching in Apache. You can see more information about this by reading the Operating System Caching section in Apache's Caching Guide.

You could also see the answers to this question (Disable all disk caching for apache2 on linux) also posted on ServerFault. It does not provide a way to disable caching at the Linux level but it does indicate that you could constantly run the following:

watch -n 1 `sync; echo 3 > /proc/sys/vm/drop_caches`

This can be used to flush the contents of everything cached in memory.

Solution 3:

Apache does check - sounds like the timestamps are not being set to the current time when the file is deployed.

See my answer here. Basically, conditional request are a PITA and usual worsen performance rather than improving them. Although that answer is in relation to caching performance it will also solve your problem.

C.