How to deploy Meteor on Google Compute Engine

Once upon a time, a new web framework called Meteor was born. Meteor quickly became a rising star with the potential of having a big impact on the web development world.
Developers praised its velocity and its wonderful property of having the same shape (something called JavaScript) on both the front and the back. Its reactivity also impressed many stargazers.

The people of Q42 took an interest and studied this Meteor. Its material turned out to be quite valuable if used in the right way. So the question on everybody’s mind was: how to use this new phenomenon? Could its energy be harnessed to power our engines? Where could this Meteor take us?

Meteor + Compute Engine

Right, back to the real world. We’ve been building stuff with Meteor at Q42 for nearly two years now and recently decided to look at how to make it work on Google Compute Engine, since we do a lot on that platform.

In a nutshell, it comes down to bundling your Meteor app and uploading it to Google Cloud Storage. You can then create a new Virtual Machine and use a startup script to tell Google Compute Engine to download and install MongoDB, Nginx, Node.js and run your app.

We’ve created a GitHub repo that contains a readme with all the info you need to get this running. It also contains an example startup.sh script, which runs when you start up a new GCE instance.

11 steps from scratch to live

Here’s how it works:

  1. Create a new project on GCE: https://console.developers.google.com/
  2. Download the gcloud tool: https://developers.google.com/cloud/sdk/
  3. Authenticate to Google Cloud Platform: gcloud auth login
  4. Configure gcloud to use your new project by default: gcloud config set project
  5. Create a bucket in Google Cloud Storage (it needs to be unique) for example: gsutil mb gs://iloveq42
  6. Edit startup.sh to use your bucket. For example: export BUCKET=’iloveq42'
  1. Copy startup.sh (replace ‘iloveq42’ with your bucket name): gsutil cp startup.sh gs://iloveq42
  2. Bundle your Meteor app: meteor bundle ../app0.0.1.tar.gz
  3. Copy your app to your bucket (replace ‘iloveq42’ with your bucket name): gsutil cp ../app0.0.1.tar.gz gs://iloveq42/versions/default.tar.gz
  4. At this point your bucket should look like this:
  1. Create a new persistent disk for MongoDB: gcloud compute disks create “mongo-data” — size “200” — zone “europe-west1-a” — type “pd-standard”
  2. Create a compute engine instance using the startup.sh script (replace ‘iloveq42’ with your bucket name): gcloud compute instances create “meteor” — zone “europe-west1-a” — tags “http-server” — scopes storage-ro — metadata startup-script-url=gs://iloveq42/startup.sh — disk “name=mongo-data” “mode=rw” “boot=no”

This will output something like this:

Done! At this point your site should be reachable on the external IP (http://146.148.114.173 in this case).

Startup script

The great thing about the startup script is that your environment is reproducible. You can always start up a new server with exactly the same setup. You can worry less about subtle configuration bugs and you can check in the configuration together with your code.

What’s also worth pointing out is that GCE supports automatic restarts and migrations of your running server to another server in case of problems. So even if the whole datacenter would go down GCE will automatically recover and start your instance somewhere else. On the server itself forever takes care of keeping your app running.

Why?

So ehm, why are you doing all this? Well because so far we’ve been deploying our Meteor apps to meteor.com, but that’s not a production environment and has some downtime and performance fluctuations once in a while. Also, meteor.com is running in the US, while if we deploy to Compute Engine we can select a local datacenter (European in our case) which makes it much faster. For comparison: requests to meteor.com take about 200ms, while GCE returns requests for the same app in 20ms.

Another reason is that when you use GCE servers you have much more control over the scalability. You could use bigger or multiple frontend instances or set up a whole MongoDB cluster if needed.

What’s next?

Looking at the future we can imagine you can use the newly released gcloud-node library to access the Google Datastore and Cloud Storage in your app. This whole setup process could even be moved to a Docker container so you could run on Managed VMs. So many technologies to play with!

As always there’s a balance between ease of use and control. While you have much more speed and control when you deploy to GCE it’s not as easy yet as just typing meteor deploy myapp.meteor.com. Then again, making the setup process easier is just a pull request away :)

Check out our GitHub for the code:
https://github.com/Q42/meteor-on-gce


Check out our Engineering Blog for more in-depth articles on pragmatic code for happy users!