Running Node.js applications from GitHub in generic Docker Container image 56

Running Node.js applications from GitHub in generic Docker Container

This article shows how I create a generic Docker Container Image to run any Node.JS application based on sources for that application on GitHub. The usage of this image is shown in this picture:



Any Node.JS application in any public GitHub repo can be run using this Docker Container Image. When a container is run from this image, the url for the GitHub Repo is passed in as environment variable – as well as (optionally) the directory in the repo to run the application from, the name of the file to run and the specific version of the Node runtime to use. An example of the command line to use:

docker run -e “GIT_URL=” -e “APP_PORT=8080” -p 8005:8080 -e “APP_HOME=part1”  -e “APP_STARTUP=requestCounter.js”   lucasjellema/node-app-runner

This command will run the script requestCounter.js in the part1 directory in the repo found in GitHub at the URL specified. It passes an additional environment variable APP_PORT to the runtime – to be used in the node application (process.env.APP_PORT). It maps port 8080 inside the container to port 8005 on the host in the standard Docker way.

To run an entirely different Node.js application, I can use this command:

docker run -e “GIT_URL=”  -p 8010:8888 -e”PORT=8888″ -e “APP_HOME=.”  -e “APP_STARTUP=app.js”   lucasjellema/node-app-runner

The same image is started, passing a different GIT_URL and different instructions regarding the directory and the script to run – and also a different environment variable called PORT.

Note: this work is based on the Docker Image created by jakubknejzlik – see and

My own sources are part of the GitHub Repository at – with resources for a workshop on Microservices, Choreography, Docker, Kubernetes, Node.jS, Kafka and more.

The steps described in this article:


1. Docker file to build the container

2. file to run when the container is started

3. Create image from the container

4. Push image to public Docker Hub Registry (

(5. Create Node.js application and push to GitHub)

6. Run Node.js application from GitHub repository by starting a Docker container from the image created in the previous steps


1. Docker file to build the container

The Docker file is shown here

FROM node


# JUST_RUN specifies whether node should be installed and git should be cloned

COPY ./docker-work /code


#RUN chown -R app:app /code/*
RUN chmod +x /code/

RUN npm install -g n --silent
RUN n stable

ENTRYPOINT ["/code/"]

It starts from the Docker Image node – the official base image (see for details). The scripts defines a number of environment variables with (default) values; these values can be overwritten when a container is run. The contents of directory docker-work (off the current working directory) is copied into directory /code inside the Docker image. The file – which is in that docker-work directory – is made executable. NPM package n is installed ( for doing version management of Node.js and the currently stable release of Node.js is installed – in addition to the version of Node.js shipped in the Node Docker image . Finally, the entrypoint is set to – meaning that when a container is started based on the image, this file will be executed.


2. file to run when the container is started

The file is executed when the container is started. This file takes care of

* install a special version of the Node.js runtime if required

* cloning the Git repository – to bring the application sources into the container

* installing all required node-modules by running npm install

* running the Node.js application

The file uses a number of environment variables for these actions:

– NODE_VERSION – if a specific version of Node runtime is required

– GIT_URL – the URL to the Git repository that contains the application sources

– APP_HOME – the directory within the repository that contains package.json and the start script for the application to run

– APP_STARTUP – the file that should be executed (node $APP_STARTUP); when this parameter is not passed, the application is started with npm start – based on the start script in package.json

– JUST_RUN – when this variable has the value Y, then the container will not attempt to install a new version of Node.js nor will it clone the Git repo (again)


if [ "$JUST_RUN" = "N" ]; then
  echo switching node to version $NODE_VERSION
  n $NODE_VERSION --quiet

echo node version: `node --version`

if [ "$JUST_RUN" = "N" ]; then
  git clone $GIT_URL app

cd app

echo Application Home: $APP_HOME

if [ "$JUST_RUN" = "N" ]; then
  if [ "$YARN_INSTALL" = "1" ]; then
    yarn install --production --silent
    npm install --production --silent

if [ "$APP_STARTUP" = "" ]; then
  npm run $NPM_SCRIPT


3. Build container image

In my environment, I am working on a Windows7 laptop. On this laptop, I have installed Docker Tools. I am running in the Docker Tools Quickstart terminal (fka boot2docker) – Docker Machine on a Linux client running a small Oracle VirtualBox VM.

Using this command I build the container image from the Dockerfile:

docker build -t lucasjellema/node-app-runner .


To inspect whether the image contains the setup, I can run the image and start a Bash shell – just check on the contents of the file system:

docker run  -it –entrypoint /bin/bash  lucasjellema/node-app-runner

I can now try out the image, using a command like this:

docker run -e “GIT_URL=″ -e “APP_PORT=8080” -p 8004:8080 -e “APP_HOME=part1”  -e “APP_STARTUP=requestCounter.js”   lucasjellema/node-app-runner


This runs a container, clones the Git repo at the indicated URL to directory /code/app , navigate into directory /code/app/part1, performs an npm install to get required modules and runs requestCounter.js with Node.js, listening at port 8004 for http requests on the host that are forwarded to port 8080 inside the container.

In order to access the application on my Windows host, I need to know the IP address of Docker Machine – the Linux VM instance that runs the Docker server inside VirtualBox. This is done using

docker-machine ip default

which will return the IP address assigned to the VM.


I can then access the Node.js application at http://IP_ADDRESS:8004.




4. (optional) Push image to public Docker Hub Registry (

The image has proven itself, and we can now push it to a public or private registry. To push to Docker Hub:

docker login

docker push lucasjellema/node-app-runner


5. Create Node.js application and push to GitHub


6. Run Node.js application from GitHub repository by starting a Docker container from the image created in the previous steps

I have several Node.js applications that I would like to run – each in their own container, listening at their own port. This is now very simple and straightforward – using several calls to docker run, each with different values for GIT_URL, APP_HOME and APP_STARTUP as well as APP_PORT or PORT.

For example – run three containers in parallel:

docker run -e “GIT_URL=″ -e “APP_PORT=8080” -p 8001:8080 -e “APP_HOME=part1”  -e “APP_STARTUP=requestCounter.js”   lucasjellema/node-app-runner

docker run -e “GIT_URL=″ -e “APP_PORT=8080” -p 8005:8080 -e “APP_HOME=part1”  -e “APP_STARTUP=requestCounter-2.js”   lucasjellema/node-app-runner

docker run -e “GIT_URL=”  -p 8010:8888 -e”PORT=8888″ -e “APP_HOME=.”  -e “APP_STARTUP=app.js”   lucasjellema/node-app-runner

We can look at the logging from a container:

docker logs <container id>

We can stop each container:

docker stop <container id>

list all containers – running and stopped:

docker container ls -all

restart a container (now the time to restart is very short):

docker start <container id>

7. Turn Container into Image

Note: it is easy to turn one of these containers running a specific Node.js application itself into an image from which subsequent containers can be run. This image would contain the correct version of Node.js as well as the application and all its dependent modules – allowing for a faster startup time. The steps:


for example:

docker commit a771 request-counter

Subsequently we can run a container based on this image; note that this time we do not specify the GIT_URL – because the application and all node_modules are baked into the image. The environment variables used in and in the application can still be passed. The startup time for this container should be very short – since hardly any preparation needs to be performed:

docker run  -e “APP_PORT=8080” -p 8004:8080 -e “APP_HOME=part1” -e “JUST_RUN=Y” -e “APP_STARTUP=requestCounter.js”   request-counter



Note: remove old containers

list exited containers:

docker ps -aq -f status=exited

remove them (

docker rm -v $(docker ps -a -q -f status=exited)

remove dangling images

list them:

docker images -f “dangling=true” -q

Remove them:

docker rmi $(docker images -f “dangling=true” -q)