Installing Node.js dependencies with Yarn via s2i builds and OpenShift

Building a docker formatted container image for a Node.js application

There are 2 main strategies for building an image for a Node.js Application. The most common strategy is simply using a Dockerfile with a base image of something like FROM node:4-onbuild. Then do a docker build. This will produce an image with your application in it, ready to be run. This strategy is known as the Docker strategy in an OpenShift BuildConfig.

Another strategy is using the s2i tool for taking the application source from a repository and producing the image. A typical command would be.s2i build git@github.com/me/myrepo.git bucharestgold/centos7-s2i-nodejs:latest myapp. With this strategy, there is no explicit Dockerfile. It is known as the Source strategy in an OpenShift BuildConfig.

Alternatives to npm

Both of these strategies will install any Node dependencies using the npm tool. However, there are other tools available for managing dependencies in Node.js applications. Yarn is one such tool that has gained popularity due to the speed of dependency installation and locking mechanism for dependency versions.

To use Yarn for installation of dependencies with an s2i strategy, the s2i builder image needs a couple of modifications. The first change is to install the Yarn binary. For these examples, the CentOS s2i builder image maintained at https://github.com/bucharest-gold/centos7-s2i-nodejs will be used. Installing the Yarn binary is a simple enough change to contrib/etc/install_node.sh.

# Install yarn
npm install -g yarn -s &>/dev/null

The second change is to use Yarn when installing Node.js dependencies. Since Yarn is not the official dependency install tool, it would be nice to use npm by default and allow developers to choose Yarn if they wanted. An environment variable can help with that. Developers may also want to pass additional flags to Yarn. This change to s2i/assemble will allow both scenarios:

if [ ! -z "$YARN_ENABLED" ]; then
 echo "---> Using 'yarn install' with YARN_ARGS"
 yarn install $YARN_ARGS
else
 echo "---> Using 'npm install'"
 npm install -s
fi

Doing a make all will produce create a new s2i builder image with above changes.

S2I builder in action with Yarn

Environment variables can be passed to s2i with the -e flag. The following command uses Yarn to install dependencies:

s2i build -e "YARN_ENABLED=true" git@github.com:david-martin/nodejs-ex docker.io/bucharestgold/centos7-s2i-nodejs:latest myapp

---> Installing application source
---> Building your Node application from source
---> Using 'yarn install' with YARN_ARGS
yarn install v0.24.5
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 1.79s.

Using it in OpenShift

To use it in OpenShift, there are 2 small changes to your BuildConfig. The first is to tell it to use a different s2i build image. Then configure it to use Yarn by setting an environment variable.

  strategy:
    type: Source
    sourceStrategy:
      from:
        kind: DockerImage
        name: 'bucharestgold/centos7-s2i-nodejs:latest'
      env:
        - name: YARN_ENABLED
          value: 'true'

Trigger a build using the oc build command, and the build logs will look similar to above. That’s all there is to it. You can extend on this idea to allow other dependency management or installation tools to be used.

Links

Share