Please read Docker pre-requisites here
When we develop an app, we choose a language like JS, Python, Java, etc. These languages need to be executed and hence we need a runtime environment like node JS. This Node JS comes in different versions. When we are developing, we might have used newer versions, but when we are into production (i.e. in server), we might get older versions.
This is the case of production and development environment mismatch. To solve this, we might partition the system(server) into many machines. This can't be done physically like hard drive and CPU splitting but can be done by software. This concept is called Virtualization, and the corresponding software to split the resource is called Hypervisors. This idea of creating new machines is called Virtual machines.
Each virtual machine we create is independent of one another, and every app we build must have a separate OS, dependency, etc. for every virtual machine. This leads us to another problem say we have app1,app2 and app3 have the same OS(Linux); if we were to put them into VMs we need to install the same Linux OS thrice in three different VMs.
Therefore every VM has a separate OS in addition to Host OS. This OS is called 'Guest OS'. This essentially means OS is not shared across VMs.
Do remember the fact that OS consumes most of the storage because at the minimum it requires 400 MB even though your app is 10MB.
From the business perspective if there is any way to share OS across apps, then it could save billions in cost. This technology of sharing OS across apps is called 'Container'. Of course, there are many pros to containers in addition to OS sharing.
Containerization makes use of the Kernel in the host OS and kernel is the one that splits hardware like CPU, memory, etc. for a particular task.
What is Container?
Container = Self-contained running software.
Observe the words I used 'Self', 'contained', 'running', 'software'.
Self-contained - All the things are available in itself
Software - software is an app we have created that is basically a chunk of codes
Running - What the software needs to run is basically dependencies and environment
Implementation of this is basically the same as the Object-Oriented Programming concept (i.e. Classes and Object) - There will be one class and we can create as many instances we want(Object). The template is Class and Execution is done by Object.
Class equivalent in this technology is 'Image' and Object equivalent is 'Container'. These Images are a shareable part of Container technology.
As we said earlier, Images are the template for creating Containers. Therefore we can get Standard Images(from Docker hub) or Custom-made Images(on our own). Standard images are available on docker hub websites; they contain a basic setup for your app.
We create an image inside the docker file. From that, we will create many containers(i.e., instances).
Code and environment will be in images, and containers will use the code and environment while running an app - storage, memory, etc., will be decided by containers. What is run in the container is isolated from the local machine.
We can always build an image from scratch, but it is cumbersome. So we will always build an image upon an existing image like an official image like a node from docker hub. This base image will contain the required OS and setups.
We have source code and dependencies/environment in the local machine. We then copy the source code-dependencies-environment to the image at that point in time. Then we will run the containers based on the image.
But one thing to note here is when we change the source after image creation, it will not get automatically reflected in Images and hence corresponding Containers.
This proves to us that Images are snapshots of time.
Containers add another layer on top of Images. Containers execute the command needed to run the code on top of the image created. This proves us containers allocate resources, memory, and so on. It will not copy the code again from the image and hence Docker is efficient.
Images: Blueprint for creating Containers
Containers: Instances we create using blueprint(Images)
So one image but many containers