5

I'm trying to deploy the following sample node application to an Azure website:

var http = require('http');
var port = process.env.port || 1337;

http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html' });

    try {

        var canvasModule = require('canvas'), 
            canvas = new canvasModule(200, 200), 
            ctx = canvas.getContext('2d');

        ctx.rotate(0.5);

        ctx.font = '30px Impact';
        var message = "Hello World";
        ctx.fillText(message, 40, 40);

        ctx.strokeRect(30, 5, 160, 50);

        res.end('<html><img src="' + canvas.toDataURL() + '" /></html>');

    } catch (e) {
        res.end('Error: ' + e);
    }

}).listen(port);

The tricky part is that I'm using a node module called "canvas" that needs to be compiled at install time using node-gyp.

According to this Microsoft page native modules are not supported on Azure Web-sites and the compiled version of the module should be copied to Azure for the app to work properly:

Native Modules

While most modules are simply plain-text JavaScript files, some modules are platform-specific binary images. These modules are compiled at install time, usually by using Python and node-gyp. One specific limitation of Azure Web Sites is that while it natively understands how to install modules specified in a package.json or npm-shrinkwrap.json file, it does not provide Python or node-gyp and cannot build native modules.

Since Azure Cloud Services rely on the node_modules folder being deployed as part of the application, any native module included as part of the installed modules should work in a cloud service as long as it was installed and compiled on a Windows development system.

Native modules are not supported with Azure Web Sites. Some modules such as JSDOM and MongoDB have optional native dependencies, and will work with applications hosted in Azure Web Sites.

I deployed everything to Azure (using the publishing Wizard) and all the files were sent to Azure (apparently at least), including the compiled modules. When running the site on Azure I obtain the following exception:

Error: The specified module could not be found.
D:\home\site\wwwroot\node_modules\canvas\build\Release\canvas.node

But that file is in-fact deployed on the server:

files on folder

Creating a VM would obviously be an option but I would prefer to use web-sites. Anyone has any idea that I can try out?

psousa
  • 6,676
  • 1
  • 32
  • 44

3 Answers3

5

The error message ""The specified module could not be found" is a bit misleading. It can mean one or more dependent dlls are not found.

I assumed you used the build instruction in Windows. If you built canvas against the GTK2 zip file in the instruction, you can copy %GTKDIR%\bin\freetype6.dll to %YourApp%\node_modules\canvas\build\Release. This dll is not copied during the build process. You would need to do this deploying to a VM as well. Or you can build canvas against the Windows GTK3 bundle.

And unfortunately even after you have all the dll, the sandbox of Azure Websites seems to prevent canvas from running. Hopefully it would be enabled in the near future.

mtian
  • 131
  • 3
  • Thanks for the info. After copying "freetype6.dll" the site no longer throws an error but I just get an empty image. I'm going to accept your answer as this does seem an impossible endeavour... – psousa Aug 06 '14 at 08:41
2

Alright got this working today!

You need to deploy your node_modules directory, in addition to that you need to copy all the contents gtk/bin to the root of your application, which makes it a bit messy, but it works. I imagine you could change the path to look elsewhere but I needed to get the app running so I didn't investigate any further.

Loktar
  • 34,764
  • 7
  • 90
  • 104
0

That last line in @mtian's answser is key. You can spend time getting it to deploy but ultimately the Azure Website VMs lack the GDI+ APIs that node-canvas relies on to execute (presumably blocked for security considerations). If you want node-canvas on Azure, you can't use Azure Websites and will instead need to setup and manage your own VMs.

Robert Levy
  • 28,747
  • 6
  • 62
  • 94
  • 1
    Actually GDI+ seems to work on Azure websites. I've got a demo WebAPI that's using GDI+ to generate map tile images: http://tile-1.azurewebsites.net/tile/10/490/391.png – psousa Aug 06 '14 at 08:36