ImageMagick on Azure Functions for Linux with Node.js

Since you cannot install any additional dependencies on function instances, you have to include any missing tools, that you need, as static binaries in your deployment.

To prepare a static build of ImageMagick, which will work on Azure Functions, spin up a Debian 10 x64 VM (the DigitalOcean one works fine), and run the following commands. (Based on the instructions for AWS from https://gist.github.com/bensie/56f51bc33d4a55e2fc9a.)

apt install libpng-dev libjpeg-dev libtiff-dev build-essential
wget https://imagemagick.org/download/ImageMagick-6.9.11-49.zip
unzip ImageMagick-6.9.11-49.zip
cd ImageMagick-6.9.11-49
./configure --prefix=/home/site/wwwroot/imagemagick --enable-shared=no --enable-static=yes
make
make install
tar zcvf ~/imagemagick.tgz /home/site/wwwroot/imagemagick/

Create an imagemagick/bin folder, inside your project, which will be included in the deployment. Download the imagemagick.tgz archive from the VM, and extract just the binaries you need (e.g. convert) into the bin folder. Also include the etc folder as imagemagick/etc. The rest of the files can be ignored.

In your function script, at initialization, use chmod to mark the binaries as executable. For Node.js, this can be done as follows.

const bins = fs.readdirSync('/home/site/wwwroot/imagemagick/bin');
for (let i = 0; i < bins.length; i++) {
    fs.chmodSync('/home/site/wwwroot/imagemagick/bin/' + bins[i], 0o755);
}

For testing purposes, set up a function to output the ImageMagick version information.

const { exec } = require("child_process");
const convert = '/home/site/wwwroot/imagemagick/bin/convert';
module.exports = function (context, req) {
  return exec(convert + ' -version', function (error, stdout, stderr) {
      context.res = {
          body: stdout + '\n' + stderr
      };
      context.done();
  }); 
}

You can use /dev/shm to pass data, between processes, using temporary files in memory (alternatively/tmp for regular disk-backed temporary files), or use stdin and stdout to stream files in and out of the process. Streaming may have more overhead if you have more complex pipelines (when the stream has to pass through your Node.js process). Or you can pipe through multiple commands in one exec call, where practical. Files allow more flexible command line options when combining multiple images, but you need to take care to delete your temporary files.