Docker Essentials for Beginners: What I Learned Building My First Node.js App

Over the past few days, I’ve been diving into Docker and learning how it simplifies development and deployment. I started with a basic Node.js app and ended up understanding key Docker concepts that I’m sharing below — explained in simple terms from a beginner’s point of view.

Why Docker?

Docker simplifies application development, deployment, and scaling by packaging your app along with its dependencies into containers. These containers run the same way in development, testing, or production — ensuring consistency across environments.

First rule: Make sure Docker Desktop is running before executing any Docker commands.

Basic Docker Commands I Learned

docker run -it ubuntu         # Image
docker container ls           # List running containers
docker container ls -a        # List all containers (including stopped)
docker start <container>      # Start a stopped container
docker stop <container>       # Stop a running container
docker exec <container> ls    # Run commands inside the container from host
docker exec -it <container> bash  # Open shell inside the container

Understanding Images vs Containers

  1. Images are the blueprint (environment setup, app code).
  2. Containers are the live, running instances of those images.
  3. Multiple containers can use the same image — they are isolated from each other.

Creating & Sharing Custom Images

  1. Write a Dockerfile to define environment & dependencies.
  2. Build the image (docker build -t codebro-image .).
  3. Push it to Docker Hub.
  4. Your teammates can run it using:
docker pull your-dockerhub/codebro-image
docker run -it your-dockerhub/codebro-image

Docker Networking

Bridge Network (Default)

  • Isolated network created by Docker.
  • Containers can talk to each other using names (if on custom bridge).
docker network inspect bridge

Host Network

  • Shares host machine’s network.
docker run -it --network=host your-image

None Network

  • No network access (complete isolation).
docker run -it --network=none alpine

Create a Custom Network

docker network create my-custom-network

Port Mapping & Environment Variables

  • Expose ports from container to host:
docker run -it -p 1025:1025 image-name

  • Pass environment variables:
docker run -it -p 1025:1025 -e key=value -e key=value image-name

Volume Mounting

  • Attach host folders to containers for persistent storage:
docker run -it -v /Users/tejhagargi/Desktop:/home/abc ubuntu

Changes in /home/abc inside container reflect on your desktop and vice versa.

Layer Caching

  • Each line in a Dockerfile becomes a layer. Docker reuses unchanged layers to speed up builds.
FROM node:18           # Layer 1
WORKDIR /app           # Layer 2
COPY package.json .    # Layer 3
RUN npm install        # Layer 4
COPY . .               # Layer 5
CMD ["node", "index.js"]  # Layer 6

Multi-Stage Builds

  • Build your app in one stage and copy only the necessary files to a clean final image.
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

FROM node:18-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]

Try My Dockerized Node App

docker pull tejhagargi/myfirstnodeapp_docker
docker run -it -p 3000:3000 tejhagargi/myfirstnodeapp_docker

`FROM ubuntu

RUN apt-get update

RUN apt-get install -y curl

RUN curl -sL https://deb.nodesource.com/setup_18.x | bash –

RUN apt-get upgrade -y

RUN apt-get install -y nodejs

COPY package-lock.json package-lock.json
COPY package.json package.json
COPY main.js main.js

RUN npm install

ENTRYPOINT [ “node”, “main.js” ]
`

Wrapping Up

Learning Docker has helped me understand how to ship applications reliably. Whether you’re working solo or with a team, containerization is a powerful tool that makes life easier.

If you’re also learning Docker, feel free to drop questions or tips in the comments!

🧑‍💻 Happy Dockering!
— Tej Hagargi

Similar Posts