Commands
Creating and Running a Container
docker run -d --name my-container nginx
List all containers
docker ps -a
List of available images
docker images
To stop the container
docker stop my-container
To run iteractively
docker run -it --name <name> <image>
To run with volume mounted for persistence
docker run -d --name <name> -v new-volume:/data <image>
Chatgpt DockerFile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
To build the container
docker build -t my-node-app
To run
docker run -d -p 3000:3000 my-node-app
Creating a network for containers
By default, Docker containers are isolated from each other. They must be on the same network to communicate with each other. When containers are on the same network, they can resolve each other by name instead of using IP addresses. Prevents port issues and has better security.
docker network create my-network
docker run -d --name my-db --network my-network mongo
docker run -d --name my-db --network my-network node
Now, the node app can connect to MongoDB using
mongodb://my-db:27017
Production ready Node js Dockerfile
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production // installing production dependecies
COPY . .
RUN addgroup -S appgroup && adduser -S adduser -G appgroup=
USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
npm ci layer for faster builds, ensures clean install
Multi Stage Build for even Smaller, Faster Build
# Build Stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production Stage
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
# To add the volume
VOLUME ["/app/uploads]
# To Modify the dockerfile to exclude .env
RUN rm -f .env
# While running the container
docker run -d --env-file .env -p 3000:3000 my-node-app
# For better security, mention the read-only flag
docker run -d --read-only -p 3000:3000 my-node-app
# To improve performance by disabling dev-only features, Modify the Dockerfile
ENV NODE_ENV=production
# To run the container (Named Volume)
docker run -d -p 3000:3000 -v my-app-data:/app/uploads my-node-app
# To check the volume
docker volume ls
# For Bind Mount (Specific location)
docker run -d -p 3000:3000 -v $(pwd)/uploads:/app/uploads my-node-app
DockerFile for a react app (Without a web server)
FROM node:19.6-slim-bullseye AS base
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Docker-compose.yml
version: "3.8"
services:
frontend:
build: ./frontend
container_name: frontend
restart: always
ports:
- "3000:3000"
depends_on:
- backend
volumes:
- ./frontend:/app
- /app/node_modules
backend:
build: .
container_name: "container-name"
ports:
- "3000:3000"
environment
- MONGO_URI=mongodb://mongodb:27017/mydatabase
depends_on:
- mongodb #ensures MONGODB starts before nodejs app
volumes:
- .:/app #syncs current directory with the container (any changes is reflected inside the container as well)
- /app/node_modules #prevents overwriting node_modules inside the container
mongodb:
image: mongo:latest
container_name: mongo-container
restart: always
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db # persistent Mongodb Storage
volumes:
mongo_data: # named container to store all the collections, indexes, metadata etc, mounded it /data/db by default
docker-compose up --build
# For logs
docker logs backend
docker logs mongo-container