Migrate a Node.js application into a Docker container

To avoid repetition, for overview and language agnostic examples on application migration to containers see Migrate your application into a Docker container

Update your application

Exclude downloadable libraries

Add a Node.js-specific .gitignore file to the root of the Git repository. This is an example of a basic file.

.DS_Store
node_modules

/.cache
**/build
/public/build
.env

Read configuration values from environment variables

Node.js natively supports the reading of environment variables.

const user_name = process.env['USER_NAME']

Automate the application build

Create the init.sh file

Create the init.sh file in the source directory and enable the execution with the command:

chmod +x init.sh

This file will contain the terminal initialization steps for the application. This example

  • sets the AWS_PROFILE environment variable value
AWS_PROFILE=aws1

Create the env.list file

The env.list text file contains the list of environment variables (without values) used by the application. When we run the Docker container, the –env-file option will copy those into the environment of the container.

MY_VAR1
MY_VAR2

Create the Dockerfile

The Dockerfile contains the list of instructions to build our application into a Docker container. This generic Dockerfile can build any Node.js application, as the referenced packages are listed in the “package.json” and “package-lock.json” files.

FROM node:16

WORKDIR /app

COPY package.json ./
COPY package-lock.json ./
RUN npm install

COPY . .

ENTRYPOINT [ "node", "index.js" ]

Exclude the “node_modules” and “builds” directories from the COPY . . operation

The “COPY . “. command will copy all files and directories from the “context” directory to the image. As we already placed “node_modules” into the .gitignore file, in the CI/CD pipeline it will not be available during the build, so the “npm install” command will recreate it. To be able to test the build process on our workstation, we need to ignore it during the docker build. Create the .dockerignore file in the context directory (usually in the parent of the “node_modules” directory.

WARNING: This setting will force the Docker build process to ignore the “node_modules” and “build” directories in all COPY . . commands, so if the Dockerfile uses the two step build process, explicitly copy the “node_modules” and “build” directories with the
COPY –from=BUILD_IMAGE /app/node_modules ./node_modules
COPY –from=BUILD_IMAGE /app/build ./build
commands.

**/node_modules
**/build

Create the Makefile

In the source directory create the Makefile to automate frequently executed steps. This Makefile provides the following functionality:

  • make init ( the first and default option, so it is enough to type “make”)
    • provides instructions on how to execute the init.sh file the first time you open the terminal in this directory. (“Make” recipes execute the instructions in subprocesses, so those lines cannot update the parent environment you are calling them from. The extra dot instructs the terminal to run the init.sh script in the same process. It is same as “source” but more portable.)
  • make install
    • installs the referenced Node.js packages and saves the list in the package.json and package-lock.json files
  • make run
    • starts the application
  • make unittest
    • runs the unittest.js script
  • make docker-build
    • using the Dockerfile builds the application into a Docker container
  • make docker-run
    • runs the Docker container using the list of environment variables from the env.list file
    • configures the container to redirect the ingress port to the port watched by the application (first value is the container port, second value is the application port)
init:
	# TO INITIALIZE THE ENVIRONMENT EXECUTE
	# . ./init.sh

install:
	npm install aws-sdk
	npm install aws-sdk/credential-providers

run:
	node index.js

unittest:
	node unittest.js

docker-build:
	docker build -t aws-listener .

docker-run:
	docker run -it --env-file env.list -p 3000:3000 aws-listener

Leave a comment

Your email address will not be published. Required fields are marked *