ExpressJS & Docker

Tharakesh Pulikonda
2 min readJan 5, 2021

A simple example for dockerizing a ExpressJS RESTful API

  1. Prerequisites
    Install Docker Desktop from https://docs.docker.com/docker-for-mac/install/ (if you are a mac user)
  2. Clone the code from the following URL
    https://gitlab.com/tarakeshp/expressjs-docker.git
  3. Install packages
    `> npm install .`
  4. Change the docker-build.sh file mode to 777 aka executable
    `> chmod 777 docker-build.sh`
  5. execute the file
    `> ./docker-build.sh`

Though there are many blogs available to explain this stuff, this blog primary concentrates on a problem with docker file interpolation. Docker file consists of two types of variables
1. ENV
This variable is mapped when docker run command is issued along with environment variables in -e key=value format as arguments.

2. ARG
This variable is mapped when docker build command is issued.

The interpolation works like any other programming language with templating engine support. In this Docker and Dockerfile, a variable that is defined can be interpolated. For example,
…..
ARG PARAM1=value1
ENV PARAM2=value2

RUN echo “printing variable param1, param2: ${PARAM1}, ${PARAM2}”. In the above screenshot, you can refer to

=> [6/6] RUN echo “internal mapping port APP_PORT, APP_NAME 3000, app-01”

After series of step in a Dockerfile, the last steps usually ends with CMD or ENTRYPOINT commands. These commands are not compile time statements rather run time. That mean the interpolation will not work when they are passed as into the array.

CMD [“node”, “app.js”, “ — port=${PARAM1}”]

This is a known interpolation problem and here are couple of references
https://github.com/moby/moby/issues/34772
https://stackoverflow.com/questions/40902445/using-variable-interpolation-in-string-in-docker

In your local development environment, you can easily arguments from inline. For example
> nope bin/www — port=3001 — name=app-name
However this is not true for docker CMD as mentioned above. As a work around to support for Docker containers as well standalone VM, process.env, yargs becomes really handy. There may be some situations where you want to run the same docker image of the same application with different internal ports.

docker run -d — name=docker-image-express-api-01 -p 7001:3000 -e APP_PORT 3000 -e APP_NAME =api-01 docker-image-express-api

The APP_PORT and APP_NAME are available as process.env.APP_PORT, process.env.APP_NAME in the application.

If you want to handle dynamic configuration files or properties by environment, this helps. Of course there are 100,000 other efficient ways to solve this problem but today this is my solution :).

Happy Coding..!

--

--

Tharakesh Pulikonda

No certifications, Not a IITian, Not a celebrity but a coder, systems builder, solutioneer