Running a Gulp build on OpenShift

I experimented with OpenShift for the first time yesterday. The project is a Node web application that uses Gulp for builds. Since NPM modules cannot be installed globally on OpenShift, apparently, it is not clear to me how you can get Jenkins to run Gulp on OpenShift. I tried various build and pre_build action hooks (including one posted on StackOverflow to address this issue, but that caused the build to quit). Surely I can't be the only one trying to get OpenShift to work with a Grunt/Gulp build file, but I can't seem to find any answers.

If you add gulp as a dependency in package.json you can just call the bin file with an action_hook

Create the file .openshift/action_hooks/build

#!/bin/bash
OLD_HOME=$HOME
export HOME=$OPENSHIFT_REPO_DIR
if [ -f "${OPENSHIFT_REPO_DIR}"/Gulpfile.js ]; then
 (cd "${OPENSHIFT_REPO_DIR}"; node_modules/.bin/gulp)
fi
export HOME=$OLD_HOME

Remember to chmod +x .openshift/action_hooks/build

So Gulp can be installed to the gear (non-globally) by adding gulp to your package.json. However when I put the gulp.js in root of my project I got the following:

Error: EACCES, permission denied '/var/lib/openshift'
at Object.fs.readdirSync (fs.js:654:18)
at Glob._readdir (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:662:20)
at Glob._process (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:446:15)
at Glob.iterator (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:181:10)
at Array.forEach (native)
at new Glob (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:179:22)
at glob (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:57:11)
at Function.globSync [as sync] (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js:76:10)
at /var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/lib/findup-sync.js:32:19
at Function.map (/var/lib/openshift/53fe6bdee0b8cdad4c00035f/app-root/runtime/repo/node_modules/lodash/dist/lodash.js:3508:27)

As I'm sure you can tell, this means that something (I'm suspecting liftoff) is trying to access a directory (/var/lib/openshift) but it doesn't have permissions to do so (which is as designed). Basically what I'm getting at, is that until you work out a way to containerize gulp and everything that comes with it, you'll likely have a really difficult time getting this up and running on Openshift. A good thing you might want to check out, is to see if this can work inside a docker container.

I just got gulp working on OpenShift! The main idea is, to use the in app gulp, instead of globally installed gulp, and then write an action hook to trigger the gulp task during some stage of the deployment.

Here are the detailed steps:

  1. Rewrite the gulpfile.js and make the task into a POJO, so that you can trigger the task outside the gulp.

Here is an example:

function buildJS() {
  return gulp.src('client-app.js')
   .pipe(browserify())
   .pipe(concat('bundle.js'))
   .pipe(gulp.dest('public/javascript/dist'))
   .pipe(rename('bundle.min.js'))
   .pipe(uglify())
   .pipe(gulp.dest('public/javascript/dist'));
}

gulp.task('scripts', buildJS);

...

module.exports = buildJS; //export this function in the end
  1. Write an action hook. I wanted the JS processing part to happen after build but before the application starts, so the deploy is the stage I wanted.

At /.openshift/action_hooks, create a file called deploy

#!/bin/bash
cd $OPENSHIFT_REPO_DIR
node -e 'require("./gulpfile.js")()'
  1. Make the action hook file deploy executable by:

    chmod +x .openshift/action_hooks/deploy

  2. Commit the changes and push the changes to remote. Now it should work.