How to deploy a Sails.js project on Google cloud?

2k views Asked by At

I have followed the tutorials for https://cloud.google.com/nodejs/ and I can get a node.js app running on Google cloud, but I am using Sails.js for my project and if I try to deploy it with gcloud preview app deploy app.yaml --set-default, the deploy fails.

I can't find a tutorial on how to deploy a sails app. What are the steps I should follow?

EDIT: the error I get is ERROR: (gcloud.preview.app.deploy) Not enough VMs ready (0/1 ready, 1 still deploying). Deployed Version: 20150623t154347.385222953610879860 I get this even with the default "empty" sails project created with sails new my_project.

UPDATE: I was able to deploy by using a different google project where the CPU quota wasn't maxed out, however:

Error: Server Error The service you requested is not available yet. Please try again in 30 seconds.

Any idea what can cause this?

UPDATE2: In the App engine console logs I can see:

Fatal error: Unable to find local grunt.

Shouldn't grunt be already part of my project if it was installed with sudo npm install grunt --save ?

3

There are 3 answers

0
Julien On BEST ANSWER

I managed eventually. The problem with Grunt was sorted by installing grunt and grunt-cli locally as well as a bunch of other dependencies.

Here is how to configure a Sails.js project to make it deployable on Google Cloud:

1) Add the following to the beginning of app.js:

"use strict";
var express = require('express');
var app = express();
app.use(require('./lib/appengine-handlers'));

2) Create an app.yaml file in the root of the project with the following content:

# [START runtime]
runtime: custom
vm: true
api_version: 1
module: default
# [END runtime]

# [START resources]
resources:
  cpu: .5
  memory_gb: 1.3
  disk_size_gb: 10
# [END resources]

# [START scaling]
automatic_scaling:
  min_num_instances: 1
  max_num_instances: 5
  cool_down_period_sec: 60
  cpu_utilization:
    target_utilization: 0.5
# [END scaling]

env_variables:
  NODE_ENV: production

3) Make sure the package.json file contains the following scripts and dependencies:

"scripts": {
"start": "node app.js",
"monitor": "nodemon app.js",
"deploy": "gcloud preview app deploy app.yaml"
},
"dependencies": {
"express": "^4.12.0",
"gcloud": "^0.15.0",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-coffee": "^0.13.0",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-cssmin": "^0.12.3",
"grunt-contrib-jst": "^0.6.0",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-uglify": "^0.9.1",
"grunt-contrib-watch": "^0.6.1",
"grunt-gcloud": "^0.2.0",
"grunt-sails-linker": "^0.10.1",
"grunt-sync": "^0.2.3",
"sails": "^0.11.0",
"sails-disk": "^0.10.8"
}

4) Create a Dockerfile file in the root of the project with the following content:

# [START docker]
FROM google/nodejs-runtime
# [END docker]

5) Change the default port by modifying the config/local.js file as follows:

port: process.env.PORT || 8080

6) Install all dependencies and push to cloud:

sudo npm install --save
gcloud preview app deploy app.yaml --set-default
0
coquin On

I had the same trouble. No matter what I did application failed to deploy with the same error. The problem was really simple: I named my main script file as index.js instead of app.js. After I renamed my main script to app.js everything started to work fine.

0
jdobry On

Regarding Sails.js on Google Cloud Platform

Google Cloud Platform has a tutorial for deploying a Sail.js app to Google Cloud Platform, as well as a sample app you can clone and deploy yourself.

Now it's even easier than what was described in the accepted answer. You can specify runtime: nodejs directly in the app.yaml file and you don't have to worry about a custom Dockerfile.

Basically:

  1. Generate your Sail.js app using their generator.

  2. Create the minimal app.yaml file:

    runtime: nodejs
    vm: true
    env_variables:
      PORT: 8080
    
  3. Update package.json:

    "scripts": {
      "debug": "node debug app.js",
      "start": "node app.js",
      "deploy": "gcloud preview app deploy app.yaml --promote --project <your-project-id>"
    }
    
  4. Deploy:

    $ npm deploy
    

The sample app is on GitHub, so the community can submit issues and PRs and improve things for those who come after.

Regarding new instances appearing on deployment

If you do not specify the version of an already deployed instance in your deploy command , then a new instance will be deployed and it will be assigned a generated version. The --promote flag makes the newly eployed version become the version that users will actually see. Previously deployed versions are still running, and you have to manually delete them, or keep them so you can roll back.

Depending on your use case it may be useful to keep the previous version around so that you can roll back to it at the click of a button.

If you don't want a new instance/version created when you deploy then you can deploy your app on top of the existing instance/version. Let's walk through a scenario:

  1. Clone the sample app and deploy it for the first time:

    $ git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
    $ cd nodejs-docs-samples/appengine/sails
    $ gcloud preview app deploy app.yaml --promote --project <your-project-id>
    
  2. A new instance is created and given an auto-generated version. Let's assume your new instance was given the version 1234. Now deploy again:

    $ gcloud preview app deploy app.yaml --promote --project <your-project-id>
    
  3. In your Google Cloud Developer Console (https://console.developers.google.com/project/your-project-id/appengine/versions) you'll see that you now have two versions: 1234 and 5678 (default). 5678 (default) means that the 5678 version is the one that users go to, but the 1234 version is still running, and you can still get to it at a special url in the Developer Console. You can stop, delete, or roll back to the 1234 version.

  4. Now, say you make some code changes and you want to re-deploy, but you don't want a new instance and version:

    $ gcloud preview app deploy app.yaml --version 5678 --promote --project <your-project-id>
    

    This time we specified an existing version, so the new code will just be deployed on top of the existing instance and version, and you won't end up with another running instance in your Developer Console. It can be convenient during development to re-deploy on top of an existing version, but you probably shouldn't when you need instant rollbacks to be available, like during your production releases. If you see errors that seem to indicate that you're out of VMs, you might need to go and clean up previously deployed versions.

    To delete a previously deployed version, delete it from the App Engine versions tab, not from the Compute Engine VM Instances tab.

Cheers!