Understanding docker and containers

What is Docker ?
Docker is a tool that lets you run your application inside a small “box” called a container, so it works the same on every computer.
Instead of installing packages, we install the docker image and run that image, in this way there won't be any problem during running our application in different platform.
Why is Docker needed?
"It works on my machine", this is a classic sarcasm that developers uses in order to explain the need of Docker. Nowadays, every major company uses Docker or similar tools like Podman, to containerize their application to run it through different devices.
But many years ago, client and developer needed to install all the package inside the project manually due to which there often comes different installation error that fails the project to execute. Often due to version mismatches, this issue was resolved in 2013 by dotCloud company who introduced Docker to the world.
Docker resolves dependency conflicts and make deployment easy relieving the pain of "It works on my machine" sarcasm.
Short reasons for docker existence
Runs the same application on any system (portability)
Bundles all dependencies with the app
Simplifies deployment and setup
Provides isolated environments for each application
Virtual machine VS Containers
So, is docker similar to virtual machine? Well, it bundles your app and dependency into a single unit and then we run that container, isn't it similar to how we run linux in VM in window host, is VM a container?
No, they sound similar but internally they are whole different concept.
Let us understand the prime difference between them:
| Virtual Machine | Docker | |
|---|---|---|
| Uses Virtualization | Uses containerization | |
| Utilizes hypervisor to allocate resource from OS | Uses Docker Engine while dockerd and containerd runs internally | |
| Heavy weighted | Light weighted |
Component of Docker
Docker Engine
Docker Daemon or dockerD
ContainerD
Docker CLI/Desktop
Basic commands:
Installing an image:
sudo docker pull hello-world
Running the image:
sudo docker -d run hello-world # -d runs image in bg
Viewing the container ( running image/process )
sudo docker ps
Stopping the container
sudo docker stop container_id
Deleting the image
sudo docker container prune #remove all sub-container of main one
sudo docker rmi image_id_or_name
How to make your project into image?
A file named Dockerfile is created at the root level of your project where you setup some commands that converts your application into a docker image.
Basic Dockerfile for NodeJs project:
#This gives us Node installed inside the container
FROM node:18
#Set working directory inside container
WORKDIR /app
#Copy package.json first
COPY package.json package-lock.json ./
#Install dependencies inside container
RUN npm install
#Copy rest of the project files
COPY . .
#Expose port
EXPOSE 3000
#Start the application
CMD ["node", "index.js"]
RUN - for setup ( Build-time )
CMD- for running the container ( Run-time )
sudo docker build -t node_project . #creates the image
sudo docker run -d -p 5000:3000 image_name
sudo docker run -itd ubuntu # to run a terminal for it
View logs of your containers
sudo docker logs container_id
Can you run image
MySqland use that image in Docker?
Yes, you can run your image and experiment with it on a separate terminal using command, this runs a terminal where you can run commands related to MySQL.
docker exec -it mysql_image_id bash
mysql -u root -p # enter root as password
Docker Networking
The process of connecting different isolated image with each other is known as docker networking.
docker network ls
There are 7 types of docker network, but 4 are the main ones:
None
Bridge ( Default )
Host
User-defined Bridge
sudo docker network create mynetwork -d bridge
# it adds a user defined bridge network
Connecting nodejs with mysql under this mynetwork
docker run -d --name mynode --network mynetwork node
docker run -d --name mysql-db --network mynetwork -e MYSQL_ROOT_PASSWORD=root mysql
In this way you can connect your NodeJs server with MySQL via "mynetwork" network that we created.
Docker Volume
A Docker volume is a persistent storage mechanism used by Docker to store data outside the container’s writable layer.
This means your data survives even if the container is deleted.
If you run a mongoDB image and store data in it, when you stop the container, the data is deleted but if you run it using volumn the data remain persistent.
Create a volume
docker volume create mongodb_data
Run mongo with volume
docker run -d --name mongodb -p 27017:27017 -v mongodb_data:/data/db mongo
Docker Compose
Docker Compose is a tool used to define and run multiple Docker containers together using a single docker-compose.yml file.
Instead of running many docker run commands manually, you define:
frontend
backend
database
networks
volumes
all in one YAML file.
Project utilizing docker compose
project/
│
├── frontend/
│ └── Dockerfile
│
├── backend/
│ └── Dockerfile
│
└── docker-compose.yml
YAML file for MERN project
version: "3.9"
services:
frontend:
build: ./frontend
container_name: frontend_app
ports:
- "3000:3000"
depends_on:
- backend
backend:
build: ./backend
container_name: backend_app
ports:
- "5000:5000"
environment:
MONGO_URI: mongodb://mongo:27017/mydb
depends_on:
- mongo
mongo:
image: mongo
container_name: mongodb
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
volumes:
mongo_data:
Running the compose
docker compose up --build
Stopping the compose
docker compose down
Conclusion
Docker packages your application and all its dependencies into a portable container so the app runs the same way everywhere — eliminating the classic “It works on my machine” problem. Since its introduction in 2013, containerization has become a standard way to simplify deployment, reduce environment-related bugs, and increase developer productivity.
Key benefits:
Portability: run the same image across machines and clouds.
Reproducible environments: dependencies are bundled with the app.
Lightweight isolation: fast startup and efficient resource use compared with full virtual machines.
Easier deployment and scaling: images can be versioned, shared, and orchestrated.
VMs vs containers (short): virtual machines virtualize hardware and include a full guest OS for each instance, making them heavier and slower to start. Containers virtualize at the OS level (sharing the host kernel), so they are much lighter and faster, though they provide a different isolation model and have distinct security and compatibility considerations.
If you want to continue, try writing a simple Dockerfile, build an image, and run it locally — then explore docker-compose or orchestration tools to see how containers streamline development and deployment workflows.

