Deploy an Ember.js app to Google Cloud

We typically deploy our Ember.js applications to Heroku. Having a Heroku instance to serve the few static files that make up an Ember application is overkill, but Heroku’s CLI and UI make it so easy to deploy and maintain we have hard time turning away from it.

A recent client had the requirement the Ember application hit the API from a static IP address. We initially looked into sticking with Heroku and one of the add-ons that provides a static IP address for an instance, but that approach got messy quickly. We looked at a few other options and settled on creating a Google Cloud (GC) Storage bucket and mounting that from a GC Compute instance with a dedicated IP address. This article details how to get that set up.

In your Ember app

We’ll be using ember-cli-deploy for deployment to GC. Install the necessary add-ons:

ember install ember-cli-deploy ember-cli-deploy-build ember-cli-deploy-display-revisions ember-cli-deploy-gcloud-storage ember-cli-deploy-gcs-index ember-cli-deploy-revision-data

Set your config/deploy.js to the following:

Don’t forget to set the projectId and bucket variables to your own.

On Google Cloud

Sign in to Google Cloud.

Set up a Compute Engine instance

All you need to do here is create a Compute Engine instance. I’d stick with the default Debian instance and the smallest instance size available.

Create a bucket

Follow Google’s guide on creating a bucket.

Make the bucket and its object readable to the public by setting permissions on both the bucket and its objects. Add a permission with Entity: User, Name: allUsers, Access: Reader.

Setup a deploy user

In order for the ember deploy add-ons to have permission to deploy to your Google Cloud Storage bucket, you’ll need to create a special type of account on Google Cloud called a Service Account.

Navigate to IAM & Admin > Service Accounts in the GC console. Create a service account and save the credentials to /config/gcs-service-account-creds.json in your Ember application.

Set a static ip on the instance

Reserve a static IP address and assign it to your Compute Engine instance.

Connect the instance to the bucket

Follow Google’s great article on how to mount a bucket as a file system from an instance. This includes setting up Cloud Storage FUSE. The instructions for installing GCS Fuse work correctly with the small modification of needing to allow all users to access the mounted bucket. This allows your web server (see NGINX below) to access the files in the bucket.

Before you mount the bucket with GCS Fuse, uncomment user_allow_other in /etc/fuse.conf on your instance.

sudo vim /etc/fuse.conf

Then mount with the allow_other option.

gcsfuse -o allow_other [BUCKET_NAME] /mnt/gcs-bucket

Set up NGINX

Install NGINX on the instance in order to serve the index file and assets for your Ember app:

sudo apt-get install nginx

Create directories for the NGINX logs:

sudo mkdir /logs
sudo mkdir /logs/nginx

Set up your NGINX config to proxy request from your Ember app to api/ endpoints to your API’s IP address or URL.

sudo vim etc/nginx/nginx.conf

Don’t forget to set the proxy_pass value in the config to your API’s IP or URL.

Now you should be able to run the normal ember deploy commands e.g., ember deploy production --activate=true. If all goes well, you’ll be able to:

  1. See the index and assets for your Ember app appear in your GCS bucket
  2. Visit the static IP you assigned to your instance and see the Ember app load.

That’s it!