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
- Images are the blueprint (environment setup, app code).
- Containers are the live, running instances of those images.
- Multiple containers can use the same image — they are isolated from each other.
Creating & Sharing Custom Images
- Write a Dockerfile to define environment & dependencies.
- Build the image (docker build -t codebro-image .).
- Push it to Docker Hub.
- 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