How to install Ghost.js on IBM Bluemix

Step 1 out of 1: Follow instructions on this blog

(https://developer.ibm.com/bluemix/2014/03/17/deploying-ghost-js-ibm-bluemix/)

Remarks

  • I found it easier to install Cloud Foundry CLI to install the app and the services. However I wasn't able to install the Cloudant service from CLI. The docs on Bluemix didn't show the CLI syntax for javascript. I don't know if it's a failing on the docs, the service or on my part. I've deployed Cloudant from the Bluemix dashboard instead
  • The most recent release of Ghost downloadable was 0.8.0 by time of writing, but the version number specified in the package.json file was still 0.6.4

Issues

1. Cannot install mysql service

To install the service you can use:

$ cf create-service mysql 100 my_mysql_server_name

but when I did that it failed with an error.

It turns out, that (to date), you have to use US South data centre. At the time of my attempt, It doesn't work with Sidney data centre, because ClearDB mysql is not available there. I haven't try the United Kingdom data centre. The symptom error thrown by the CLI is Service offering mysql not found

2. Ghost app fails to start

after finally deploying the Node.js app and the two dependant services (Mysql & Cloudant), Ghost still failed to launch.
After summoning the logs with

cf logs myapp --recent

I saw this:

ERR Ghost needs Node version ~0.10.0 || ~0.12.0 you are using version 1.2.0

That surprised me in two ways, I normally use Node 4.* these days and the 1.2.0 installed by Bluemix SDK for Node.js as runtime seems suspiciously old.
But more surprising to me was the hard requirement that the most recent build of Ghost (to date) has on an even older version of Node.

I found explanation for the latter here:
(https://github.com/TryGhost/Ghost/issues/5821)

and a way forward here
(http://support.ghost.org/supported-node-versions/)

Now the issue is how to get Node 4.2+ on Bluemix for my instance of Ghost.
This article came to the rescue as it mentioned support for node 4.3:
(https://developer.ibm.com/bluemix/2016/05/05/node-buildpack-update-fips-mode/)

which is the version installed for my app on Bluemix (well it says 3.x), now I'm confused...

Than I stumbled upon this snippet:

The buildpack uses a default Node.js version of 0.12.7. To specify the versions of Node.js and npm an application requires, edit the application’s package.json, as described in “node.js and npm versions” in the nodejs-buildpack repo.

from (https://docs.cloudfoundry.org/buildpacks/node/node-tips.html#buildpack)

So the solution, so I thought, was to update the package.json file with an explicit recent version for Node:

Replacing:

"engines": {
  "node": "~0.10.0 || ~0.12.0",
  "iojs": "~1.2.0"
},

with:

"engines": {
  "node": "~4.4.4",
  "iojs": "~1.2.0"
},

but the error became:

ERR Ghost needs Node version ~4.4.4 you are using version 1.2.0

Where is that 1.2.0 coming from?

I tried to delete the app and push again with no avail.

Tried the following commands with no success either:
$ cf set-env myapp NODE_MODULES_CACHE false $ cf restage myapp

After sucessfully playing a little with IBM Bluemix's own node-helloworld sample app (https://github.com/IBM-Bluemix/node-helloworld)

it occured to me that the fact that 1.2.0 appears in the error and as version requirement for iojs couldn't be just a coincidence.

I didn't realised what IO.js was. Now I know... (but wondering why Bluemix picked up on that one rather than Node, given that IO.js has merged into Node a while back, the current build pack for Node.js should have ignore it, shouldn't it?)

So, I've decided to get rid of the engines section all-together.

After deleting and recreating the app (restaging wasn't enough), it eventually worked.

The sign of resolution for that issue in the log was:

-----> Installing binaries
       engines.node (package.json):  unspecified
       engines.npm (package.json):   unspecified (use default)
       Resolving node version (latest stable) via 'node-version-resolver'
       Installing IBM SDK for Node.js (4.4.4) from cache

3. Error installing SQLite

in the logs:

2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! [email protected] install: `node-pre-gyp install --fallback-to-build`
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! Exit status 1
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR!
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! Failed at the [email protected] install script 'node-pre-gyp install --fallback-to-build'.
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! This is most likely a problem with the sqlite3 package,
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! not with npm itself.
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! Tell the author that this fails on your system:
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR!     node-pre-gyp install --fallback-to-build
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! You can get information on how to open an issue for this project with:
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR!     npm bugs sqlite3
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! Or if that isn't available, you can get their info via:
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR!
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR!     npm owner ls sqlite3
2016-06-20T14:56:51.24+0800 [STG/0]      OUT        npm ERR! There is likely additional logging output above.
2016-06-20T14:56:51.78+0800 [STG/0]      OUT        npm ERR! Please include the following file with any support request:

I replaced in the package.json file,

"sqlite3": "3.0.8",

with the latest version to date:

"sqlite3": "3.1.4",

Then, I did delete the app and pushed it again and it worked. Although I think setting NODE_MODULES_CACHE to false and restaging the app might have been enough.

4. Ghost fails to test the version of node installed

2016-06-20T15:08:25.79+0800 [App/0]      ERR /home/vcap/app/core/server/utils/startup-check.js:36
2016-06-20T15:08:25.79+0800 [App/0]      ERR             !semver.satisfies(process.versions.node, packages.engines.node)) {
2016-06-20T15:08:25.79+0800 [App/0]      ERR                                                                      ^
2016-06-20T15:08:25.79+0800 [App/0]      ERR TypeError: Cannot read property 'node' of undefined
2016-06-20T15:08:25.79+0800 [App/0]      ERR     at Object.checkNodeVersion [as nodeVersion] (/home/vcap/app/core/server/utils/startup-check.js:36:70)

The solution to Issues #3 above needs to be amended to have this block in the package.json file:

"engines": { "node": "~4.4.5", },

5. Ghost throws an exception because email dependancy is missing

In the log:

2016-06-20T15:32:50.46+0800 [App/0]      ERR WARNING: Ghost is attempting to use a direct method to send email.
2016-06-20T15:32:50.46+0800 [App/0]      ERR It is recommended that you explicitly configure an email service.
2016-06-20T15:32:50.46+0800 [App/0]      ERR Help and documentation can be found at http://support.ghost.org/mail.
2016-06-20T15:32:50.94+0800 [App/0]      ERR module.js:327
2016-06-20T15:32:50.94+0800 [App/0]      ERR     throw err;
2016-06-20T15:32:50.94+0800 [App/0]      ERR     ^
2016-06-20T15:32:50.94+0800 [App/0]      ERR Error: Cannot find module 'intl-messageformat'

The solution was mentioned in this comment:
[https://developer.ibm.com/bluemix/2014/04/24/enhancing-ghost-js-cloudant-ibm-codename-bluemix/#comment-137269]

which is to add the missing dependency in the package.json file:
"intl": "1.0.0", "intl-messageformat": "1.1.0"

Then we can proceed to email configuration:
in the config.js file, uncomment the mail: block and follow the link above it for configuration instructions:

production: {
  // URL constructed from data within the manifest.yml file.
    url: appurl,

    // Example mail config
    // Visit http://docs.ghost.org/mail for instructions
    //
    //  mail: {
    //      transport: 'SMTP',
    //      options: {
    //          service: 'Mailgun',
    //          auth: {
    //              user: '', // mailgun username
    //              pass: ''  // mailgun password
    //          }
    //      }
    //  },
    //

6. Ghost throws exception for many other missing dependencies

2016-06-20T16:36:22.29+0800 [App/0]      ERR Error: Cannot find module 'lodash.tostring'

This is when I've decided to do a diff between the vanilla package.json form the Ghost 0.8.0 release and the one from IBM_Bluemix repository.

and fixed all the discrepancies in the dependencies list, keeping the changes needed for Bluemix (see next issue below).

7. Issue about js-yaml module missing

2016-06-20T17:24:15.46+0800 [App/0]      ERR Error: Cannot find module 'js-yaml'

Bluemix version of config.js needs js-yaml, so it needs to be re-added to the dependencies list if it has been removed while solving issue #6

"js-yaml": "^3.3.1",

I had same issue with nano and when, then need to be added back to the package.json file:

"nano": "^6.1.4",
...
"when": "^3.7.3",

They are needed to enable support for Cloudant (see section below)

What's next?

The author of the original blog post mentioned at the top of this post, published a follow-up on how to integrate Ghost with Cloudant for storing image away from the ephemeral filesystem and in a way that allows Ghost.js to scale out:

(https://developer.ibm.com/bluemix/2014/04/24/enhancing-ghost-js-cloudant-ibm-codename-bluemix/)