π³ Dockerizing a Node.js Express App
This guide walks you through packaging your Node.js Express app into a Docker container so it runs the same everywhere β your laptop, your teammateβs machine, or any cloud server. π
π₯ Key Terms (Quick Recap)
- Image: A blueprint for your app β like a recipe.
- Container: The actual running app built from that recipe.
- Dockerfile: The file that tells Docker how to build your image.
- Port Mapping: Connecting your machineβs port to the containerβs port.
π The Simple 3-Step Flow
1οΈβ£ Your Express App Files
π (You run: docker build)
2οΈβ£ A Docker Image (Your app, packed and ready) π¦
π (You run: docker run)
3οΈβ£ A Running Server β Hit it at http://localhost:4000 π
π 1. Project File Structure
Hereβs what your project folder should look like:
express/βββ node_modules/ β auto-generated, don't touchβββ Dockerfile β Docker instructionsβββ .dockerignore β files to exclude from the imageβββ index.js β your Express appβββ package-lock.json β auto-generated lockfileβββ package.json β app metadata & dependenciespackage.json
{ "name": "express", "version": "1.0.0", "main": "index.js", "scripts": { "start": "node index.js" }, "type": "commonjs", "dependencies": { "express": "^5.2.1" }}π 2. Create a .dockerignore
Keep the image lean. Create .dockerignore in your project root:
node_modules.git.gitignorenpm-debug.logThis stops Docker from copying your local
node_modulesinto the image β itβll install its own fresh copy instead.
π³ 3. Create the Dockerfile
Create a file named Dockerfile in your project root:
# Use the lightweight Node.js 22 imageFROM node:22-alpine
# Set the working directory inside the containerWORKDIR /app
# Copy package files first (this helps Docker cache layers)COPY package*.json ./
# Install dependenciesRUN npm install
# Copy the rest of your app filesCOPY . .
# Set a default port via environment variableENV PORT=3000
# Start the appCMD ["node", "index.js"]What does
ENV PORT=3000do? It sets a default environment variable inside the container. Your app reads it withprocess.env.PORTβ just like a normal.envfile, but baked into the image.
π‘ 3 Ways to Pass Environment Variables
β Baked into the Dockerfile (default)
ENV PORT=3000The container always uses 3000 unless you override it.
β‘ Using a .env file (recommended for real projects)
Create a .env file in your project root:
PORT=4000DB_URL=mongodb://localhost:27017/mydbSECRET_KEY=supersecretThen pass it to docker run:
docker run -p 4000:4000 --env-file .env --rm express-app--env-file .envβ Loads all variables from your.envfile into the container.
β οΈ Add
.envto your.dockerignoreso it doesnβt get copied into the image itself β just pass it at runtime.
β’ Inline with -e (quick one-off overrides)
docker run -p 5000:5000 -e PORT=5000 --rm express-appπ 4. Your index.js
Hereβs the basic Express app that runs inside the container:
const express = require('express');const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => { res.send('Hello World from a Docker container! π³');});
app.listen(port, () => { console.log(`App listening on port ${port}!`);});The app reads
PORTfrom the environment, so you can change it at runtime without touching the code.
π οΈ 4. Build the Docker Image
Run this in your project root:
docker build -t express-app .What this means:
docker buildβ Build an image from the Dockerfile-t express-appβ Name (tag) the imageexpress-app.β Use the current folder
π 5. Run the Container
docker run -p 4000:3000 --rm express-appWhat this means:
-p 4000:3000β Map your machineβs port 4000 to the containerβs port 3000--rmβ Auto-delete the container when it stops (keeps things tidy)express-appβ The image to run
Now open: π http://localhost:4000 π
βοΈ Override the Port at Runtime
Want to run on a different port? Pass the PORT environment variable:
docker run -p 5000:5000 -e PORT=5000 --rm express-app-e PORT=5000β Sets thePORTenv variable inside the container-p 5000:5000β Maps your machineβs 5000 to the containerβs 5000
β Quick Summary
- Create
.dockerignore - Create
Dockerfile - Build image:
Terminal window docker build -t express-app . - Run container:
Terminal window docker run -p 4000:3000 --rm express-app - Open: http://localhost:4000 π
π Notes
- Change the
-pflag ports anytime β just keephost:containerformat. --rmis optional but great during development to avoid orphan containers piling up.- For production, consider running with
-d(detached mode) so it runs in the background:Terminal window docker run -d -p 4000:3000 express-app