3

I'm deploying a Drupal 7 application in an environment where the web server's DocumentRoot is mounted read-only (so Drupals root directories and all directories below are not writable). For storing files a separate directory outside of DocumentRoot is provided which is mounted read/write. This directory is accessible from a separate web server instance (which only serves static files without executing PHP code, e.g. static.example.com).

What I did:

  • setting file_public_path to said writabke directory
  • implementing hook_file_url_alter to modify URIs in the public scheme to point to the separate web server instance

Everything seems to work fine (CSS, ...), except for delivering images. Drupal's concept for delivering images is whenever a requested image resolution isn't found on disk, the thumbnailing mechanism is invoked instead. The thumbnailer creates a new image, which is delivered to the requesting browser and stored below sites/default/files. Subsequent requests deliver the image directly from the disk (using Apache's rewrite rules, so PHP isn't involved any more).

Since we are using varnish in front of the web server, I'd prefer a different way of handling images:

  • images are served from a different virtual host (e.g. image.example.com)
  • thumbnailed images are never written to disk
  • instead a Cache-Control header is sent using a reasonable long max-age value, so varnish's LRU expiration mechanism can keep the often used images in memory and discard unused images

Any ideas how to accomplish this?

2
  • Sounds like something impossible without some serious hacking. I prefer other way around - configure all paths so that images are always served from /sites/*/files/images and then mount a share from image.example.com to that directories. The rest is minor and can be accomplished at theming level, for example.
    – Mołot
    Commented Oct 14, 2013 at 8:49
  • 1
    It would require some serious work yes, but I wouldn't call it hacking as this can be done from a custom module without modifying any Drupal core files. However I would call hacking accomplishing anything but pure presentation (ie. HTML, CSS and JavaScript to alter them) in a theme's files. Commented Oct 14, 2013 at 10:32

2 Answers 2

3

When an generated image is not available, the page callback is image_style_deliver(). This callback first generate the image (after some access and concurrency checks) and then stream the file as response (through the file_transfer() function).

Using hook_menu_alter(), you can override the image generation callback to redirect to the static domain once the image has been generated. Ensuring the generated files are always served from the static domain. On the static server, you can add a rewrite rule to redirect request for a not yet generated image to the non-static domain. Ensuring the files are generated, even when requested from the static domain. Because of the redirections, Varnish should be able to cache the files as soon as they have been generated.

Edit: Not creating the image derivatives as files on disk does not seems to be an option. Drupal uses its Image Toolkits wrapper API (GD and ImageMagik are usually used a backend) to generate the image and this API does not seems to offer a way to generate images in memory. If you really want/need to remove the generated files, you can do it in a cron job using image_style_flush() via hook_cron().

1
  • hook_outbound_url_alter() may be an option for forcing the images to use the static domain.
    – mpdonadio
    Commented Oct 14, 2013 at 19:19
2

A response of sorts:

1.~images are served from a different virtual host (e.g. image.example.com)

You can use NFS to mount Drupal's sites/default/files directory to an images.example.com document root, or perhaps an equivalent network directory mount method for your OS.

2.~thumbnailed images are never written to disk

I don't know if that is possible in Drupal, maybe you can override the file stream wrapper handler, so that relevant file operations are handled differently.

3.~instead a Cache-Control header is sent using a reasonable long max-age value, so varnish's LRU expiration mechanism can keep the often used images in memory and discard unused images

The virtual definition host for images.example.com can set the relevant response headers for Varnish to cache those images.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.