Trying Meteor on Azure Web Apps\Websites
I’ve been starting to play around with NodeJS, the MEAN stack and now recently Meteor. As a developer, I’d like another tool in my belt. I’ve got the .Net Framework stack down, but what if I had to use something else. I’m not a huge fan of Java, although Java 8/9 looks interesting with LINQ support.
So I recently started playing around with Meteor, which is a RAILS’esque superset for NodeJS with some cool features (sharing client and server state seamlessly between the web browser and server) plus lots of plumbing abstraction.
I’m also a huge fan of Azure, but after some quick Googling l found out that Azure Websites, now Azure Web Apps, does not support Meteor. You can spin it up with a Linux VM and/or a Docker container on top of that, but that’s not the route I wanted to go through, yet.
Meteor using it’s own packaging and deployment engine. But under the hood it’s just a specialized NodeJS app. Some more Googling and I found out about Demeteorizer, which unpacks a meteor app back into it’s own NodeJS parts.
Inside your meteor app you can run the command “demeteorizer” to decompile the meteor app.
Now were not out of the woods yet. Meteor utilizes native bcrypt which requires native (Visual Studio 2010) build tools to compile. This does not work on Azure Web apps. The workaround is to run node install and compile locally then include the node_modules directory in your upload. Note that if your using the Free or Shared version of Azure Web Apps those are 32bit only, so you need to compile under a 32bit architecture..
Meteor 1.1.0.2 uses Node 0.10.36, but as of this post Azure only supports up to 0.10.32. To get around this you need to create a bin directory in the .demeteorized directory and download the correct version of node. You can follow this guide for more detailed information. Ensure you get the correct bit’ness (the default folder is 32bit and there is a folder in the npm dist directory for 64bit).
Create a file in the .demeteorized directory called IISNode.yml with the following line in it:
nodeProcessCommandLine: "D:\home\site\wwwroot\bin\node.exe"
Edit the package.json and change the version of bcrypt from 0.7.8 to 0.8.3. I had to do this to be able to build bcrypt on my system. You may need to add “–msvs_version=2013” params when building on your system if the default build chain doesn’t work. Also if your on a 64bit system and deploying to a 32bit Azure Web App instance (this is the default for free/shared) you need to add “–arch=ia32” to your npm install commands.
After you’ve manually updated the package.json run the following command in the demeteorized directory:
npm install
Next got into the programs/server directory and edit the package.json file there. You want to change fibers from a tarball to 1.0.5 so it should look like this:
"fibers": "1.0.5"
Now run the follow command in .demeteorized\programs\server:
npm install
That should get us setup to deploy our Meteor app to Azure Web Apps. Go into Azure and create your new web app. Once it’s created go into it and click the configure tab. Scroll down to the “app settings” section and supply the following variables
MONGO_URL ROOT_URL MAIL_URL
If you don’t have a MongoDB you can add one from MongoLabs as an App Service.
They have a free 500MB version you can play with. Once it’s create and in your account, click on it, then click “Connection Info” in the bottom to get your connection string. Utilizing your deployment method of choice, deploy you app to Azure.
After all this the Meteor app still isn’t running on Azure. I’m getting the following error:
Tue Jun 09 2015 15:12:51 GMT+0000 (Coordinated Universal Time): Unaught exception: RangeError: Out of memory
at Object.<anonymous> (D:\home\site\wwwroot\programs\server\boot.js:263:4)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (D:\home\site\wwwroot\main.js:9:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
Application has thrown an uncaught exception and is terminated:
RangeError: Out of memory
at Object.<anonymous> (D:\home\site\wwwroot\programs\server\boot.js:263:4)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (D:\home\site\wwwroot\main.js:9:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
A tweet form Jeremiah Billmann points to an issue with Node-Fibers and Azure (or IIS).
If you can get the following to run on Azure Websites (Node), I’d be happy. 🙂 var Fiber = require(“fibers”); Fiber(function () { }).run();
— Jeremiah Billmann (@JBillmann) April 3, 2015
So possibly the issue here is Node-Fibers not playing nice with IISNode or IIS. Hopefully I can find a solution soon as I love to zero friction deployment and management of Azure Web Apps.
Resgrid is a SaaS product utilizing Microsoft Azure, providing logistics, management and communication tools to first responder organizations like volunteer fire departments, career fire departments, EMS, search and rescue, CERT, public safety, disaster relief organizations, etc. It was founded in late 2012 by myself and Jason Jarrett (staxmanade).