Why Does Your JavaScript Project Deserve Docker?
\n\nHave you ever heard the phrase: "It worked on my machine!"? If you are a JavaScript developer, you have likely encountered a situation where the application runs perfectly locally but crashes on the server or a colleague's machine with a mysterious error. Containerization of JavaScript applications with Docker solves this problem once and for all.
\n\nDocker allows you to package your code, all dependencies (npm packages), environment variables, and even the Node.js version into a single lightweight "container." This container will run identically on your laptop, on an AWS server, and on a beginner's computer that just installed Git. In this article, we will explore how to integrate JavaScript and Docker, write real code, and create a production-ready image for your next pet project.
\n\nDocker Basics for the JavaScript Developer
\n\nBefore diving into the code, let's understand the key concepts. Docker is like a virtual machine, but much lighter. Instead of emulating an entire operating system, it uses the host kernel and isolates only your application.
\n\nDockerfile — The Recipe for Your Application
\n\nThis is a text file where you describe how to build the image. For a Node.js application, a typical Dockerfile looks like this:
\n\n# Use the official Node.js image\nFROM node:18-alpine\n\n# Set the working directory inside the container\nWORKDIR /app\n\n# Copy package.json and package-lock.json\nCOPY package*.json ./\n\n# Install dependencies\nRUN npm ci --only=production\n\n# Copy the source code\nCOPY . .\n\n# Expose the port\nEXPOSE 3000\n\n# Command to run\nCMD ["node", "server.js"]\n\nNotice: we first copy package.json, and then the entire code. This is not accidental. Docker caches layers, and if you haven't changed the dependencies, the npm ci step will not be re-executed with every code change. This significantly speeds up the build.
Images and Containers
\n\n- \n
- Image — is a template. You build it once. \n
- Container — is a running instance of an image. You can create 10 containers from one image. \n
Creating a Node.js Application from Scratch and Containerizing It
\n\nLet's write a simple Express application and package it into Docker. This will be our first practical step in JavaScript containerization.
\n\nStep 1: Write the Application
\n\nCreate a folder docker-node-app and inside it, a file server.js:
const express = require('express');\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\napp.get('/', (req, res) => {\n res.json({ \n message: 'Hello from the container!',\n nodeVersion: process.version,\n environment: process.env.NODE_ENV || 'development'\n });\n});\n\napp.listen(PORT, () => {\n console.log(`Server running on port ${PORT}`);\n});\n\nInitialize npm and install express:
\n\nnpm init -y\nnpm install express\n\nNow we have a working application. Run it locally: node server.js. Open http://localhost:3000 — you will see JSON.
Step 2: Create the Dockerfile
\n\nCreate a file named Dockerfile (no extension) in the project root:
FROM node:18-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY . .\nEXPOSE 3000\nCMD ["node", "server.js"]\n\nAdd a .dockerignore file to avoid copying unnecessary files into the image:
node_modules\nnpm-debug.log\n.git\n.gitignore\n.env\nDockerfile\n\nStep 3: Build and Run
\n\nOpen a terminal in the project folder and run:
\n\ndocker build -t my-node-app .\ndocker run -p 3000:3000 my-node-app\n\nThe flag