What’s happening when your php/Imagick refuses to convert pdfs when invoked by cron

I just pulled my hair for a day or two about a ridiculously simple problem: we’re converting PDF files to a series of images using imagick. First, we initiated the conversion process as soon as a user had uploaded a file so the conversion ran within the preforked Apache child. That’s obviously not a good idea because those processes can run for quite a while and PHP will terminate sooner or later consuming quite a bit of our web server’s precious resources.

So we chose to decouple the processing from the upload action. I’m simplifying the outline quite a bit but it’s good enough to give you an idea what went wrong. We’re storing the original file in some location and have a job running that’s converting open processing requests. This solution worked fine on our dev boxes and our staging server that resembles our prod environment quite well. Without further ado we deployed the new solution to soon find out our solution was breaking.

Take this insanely simple script:

<?php
$f = '/usr/local/www/home/test.pdf';
$ick = new \Imagick();
$ick->readImage($f);
echo $ick->getNumberImages();

when run on command line this works great. When run from cron it fails giving only one useless exception message: “Unable to read file …“. We were comparing pecl-imagick versions and supported file formats but everything seemed very legit, tried to fumble with ImageMagick’s resource settings, played with the command line tools when we finally noticed that our PATH on cron differs from our stage’s PATH.

Imagick seems to execute the Ghostscript binary for PDF conversion instead of using it as a library so Ghostscript had to be on our path which wasn’t the case on our live box’ cron. Adding PATH=$PATH:/usr/local/bin to our crontab has solved the issue.