Thursday, 13 September 2012

Meteor.js on Appfog

is a great framework but it can be a little problematic to deploy somewhere other than the hosting provided by , such as the provider .

First was the task of getting the environment variables from Appfog to match up to the ones expected by Meteor. Meteor uses MongoDB, so first I added a MongoDB service on appfog. This is done easily by clicking on:

And selecting the MongoDB service:

This gives you MongoDB, but unfortunately the environment variables it exposes to your application aren't in the form that Meteor expects. To solve this, I added the MongoHQ add-on. Similar to before, I went to the add-ons section:

And selected the MongoHQ add-on:

I got a suitable URL environment variable when I added the 'MongoHQ' add-on, but the URL was under the name $MONGHQ_URL instead of $MONGO_URL. This is quite easily solved by going to the environment variables:

And setting up the following variable:

I also also set the ROOT_URL environment variable for my application as I wanted to generate absolute urls from meteor.

Previously, I also needed to set the PORT environment variable to $VMC_APP_PORT but this no longer appears to be necessary. If it is necessary for future deployments, the same process is used as for the MONGO_URL variable.

After the environment was correct, I encountered issues from the fibers package bundled with meteor. This was solved by removing the bundled package and reinstalling the fibers package from NPM with the bundled code. As this is needed each time, I wrote the following short script to automate the process (and also store the code that was released).

With this script in place, I can now deploy to Appfog reliably whenever I need to, without having to remember a set of file modifications.

Thanks go to as the starting point for my deployment.


  1. Thanks for the mention David. Glad I could be of some assistance.

  2. Credit where it's due I always feel :) I wouldn't have managed to automate things without your starting point.

  3. How is that you get npm to re-install fibers in the "server"/node_modules? Mine always installs directly into node_modules?

    1. The fibers package doesn't need to be reinstalled into the 'server/node_modules' directory. The bundled README makes this clearer, as it sets out that the entire bundled directory is a node.js application that needs the fibers package, not just the server/ directory.

      It wouldn't surprise me if removing the server/node_modules/fibers package is unnecessary now (or becomes so in the future as meteor matures), but I did need to do it initially.

  4. Also, in order to make sure this works as of this comment, be sure to
    npm install fibers@0.6.9.

    Current version is of fibers is 1.0.0 and I was scratching my head for a bit before I figured out that meteor does not work with the latest version.

    1. Thanks for this, I've updated the sample script to reflect the explicit version requirement.

  5. thanks for the good start - i took it just a step further for compiled modules with shrinkwrap - see:

    a little hacky to use 2 essentially duplicate package.json file - probably a cleaner way to do that

    currently appfog only supports up to meteor 0.5.4 as they only offer node 0.8.14, so it didnt work out for my needs - script works fine with fibers 1.0.0 + meteor 0.5.7 up until meteor complains about the node version

  6. Do you know if there is a work around for this ? I notice that Heroku had the same problem and that it was solved by using the Meteor node binaries.

  7. Forgive the duplication of my comment on Phil's post, but deployment became a lot easier with demeteorizer:

    My deploy script is as follows:

    rm -rf $OUTPUT_DIR
    demeteorizer -n v0.8.14 -o $OUTPUT_DIR
    cd $OUTPUT_DIR
    npm install
    npm shrinkwrap
    af update $APPNAME

    Note, we have to force the required node version down to the latest supported by AppFog (at time of writing, 0.8.14). I'm not sure what the implications are, but for now my app is working great.

  8. Thanks for the good article. :)