Step-by-step: Building a Node.js server (2021 edition) — Part 2/4 — Docker

Koa.js, GraphQL, MongoDB, Docker, Mocha, Typescript

Robin level: dockerize the server

(Eventually update the node and typescript versions)
  1. We request a first container as the builder. It copies our entire working directory into /usr/src/app on the container (line 2 & 4).
  2. It installs the devDependencies and builds the project (line 6).
  3. We use a second container (runtime-container) that only contains the generated files, with no “useless” dev dependency (line 8 to 14).
  4. Line 10 and 16 we are defining and exposing ${SERVER_PORT}. We won’t use it yet, and it will remain undefined. However, the Koa server (src/server.ts) defaults to 3100 and we can explicitly expose the container’s port by using the -p argument when running Docker. We will only use the ${SERVER_PORT} argument later in this tutorial.
docker build -t <name> .
docker run -p 3100:3100 -d <name>

Batman level: dockerize the whole back-end

  • Starting from docker-compose version 3.4, we can set local variables. That’s what we’re doing here with DB_NAME because we’re going to use it many times in the file. Consider it as an alias for the string “database”.
  • We are setting up many Environment Variables for both containers (all the variables prefixed with a dollar ($) sign). More info on that below.
  • We are defining 3 containers/services:database, mongo-express and server.
  • For database we’re using the Docker image made by the community (mongo:4).
  • The database container is using volumes. The first volume is used to copy/paste a database initialization script into the container. More info on that below. The second one (mongodb_data_container) is used to persist data on the host when the container is turned off. It’s managed by Docker.
  • mongo-express is a “Web-based MongoDB admin interface” (repo). It will be super useful to browse the database from our machine through the database container. 🤯
  • For server we’re using the custom Docker image we prepared at the previous step with the Dockerfile (see line 39).
The back-end architecture (Docker containers)
The back-end architecture

🔐 A way to manage environment variables


A script to initialize our database

Final touches

docker-compose up [-d if you want to start the containers in detached mode] [--build if you want to force rebuild]
  • Browse http://localhost:3100/health and get a 200 — OK as before. This is our server.
  • Browse http://localhost:8081 and log in, using the mongo express credentials you listed in the .env file. This is a way to visualize the database we created with our script and which is living inside the database container.
  • Note: To turn the containers off, use docker-compose down.

Injecting variables at runtime

npm i -D dotenv
"exec": "npx ts-node --require dotenv/config ./src/server.ts"
const port = process.env.SERVER_PORT || 3100
src/server.ts, line 6
docker-compose up [-d] [--build] database mongo-express
npm run start



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store