NodeJS on Singularity

By Staff

Sep 27, 2018 | Blog, How To Guides

We knode you would want NodeJS on Singularity so we you made a recipe.

Setup:

On your host, create a folder called node where we will store our files:

$ mkdir node

To create our recipe and test file run:

$ touch node/nodejs.def
$ touch node/Hello-world.js

At this point, your host’s “node folder will contain the following files:

node/
|-- nodejs.def
|-- Hello-world.js

Recipe:

Edit your nodejs.def recipe file with the following content: (you can paste using nano if you’d like– “nano node/node.js)

Bootstrap: docker
From: node:10.11.0-alpine

%environment
HOSTNAME=127.0.0.1
PORT=3000
YARN_VERSION=1.9.4
export HOSTNAME PORT YARN_VERSION

%setup
# We make the directory where we will store our NodeJS file
mkdir -p $SINGULARITY_ROOTFS/node

%files
# Copy the file in the local directory to the /node location in the Image
Hello-world.js /node/Hello-world.js

%runscript
# What is executed with "singularity run"

# Pass any arguments to the node binary directly
node "$@"

%startscript
# what is executed with "singularity instance start"

# Run node on our Hello-world.js file
node /node/Hello-world.js

In our recipe file we specify to pull node v.10.11.0 Alpine from a DockerHub base.  The environment variables defined in %environment are needed for defining the dependencies (like in the case of YARN_VERSION) or for reference later in our Hello-world.js test script (below). Remember that these variables need to be defined in the %environment section to be exported. The %files section will copy the Hello-world.js we created before from the host to the container. The %startscript section will be run after starting an instance of our created container.

Hello-world.js

To test, we will need to define the contents of the Hello-world.js file.  Use the editor of your choice. (ex. vim, emacs, nano)  In this case we will use nano:

$ nano Hello-world.js

Then add the following content to the file:

const http = require('http');

const hostname = process.env.HOSTNAME||’127.0.0.1’;
const port = process.env.PORT||3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World from node in a Singularity container!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at https://${hostname}:${port}/`);
});

Make sure you have the correct code by running:

$ cat Hello-world.js

Hello-world.js runs the “process.env” directive to obtain every environment variable from javascript. In this case we obtain process.env.HOSTNAME and process.env.PORT – the variables we set in the recipe definition file.

Building:

After this, we are ready to build our Singularity container.

$ cd node
$ sudo singularity build nodejs.sif nodejs.def

We are naming the Singularity image “nodejs.sif”

Use:

We can start an instance of our container to check that our server is up and running. In the same node/ directory on your host run:

$ singularity instance start nodejs.sif node

Since the Hello-world.js was referenced on the %startscript section from the definition file, after starting an instance you can open your browser at https://localhost:3000 to see the server up and running.  For development you can specify new files to copy from node/ on your host system by editing %files in your recipe file.  Then quickly rebuild only the files section by running:

$ sudo singularity build --section files nodejs.sif node.def

Or to rebuild both %environment and %files:

$ sudo singularity build --section files,environment nodejs.sif node.def

Join Our Mailing List

Related Posts