Diving into Docker (Part 3) : Container
Everything you need to know about container and its lifecycle

I'm a mobile/web developer 👨💻 who loves to build projects and share valuable tips for programmers
Follow me for Flutter, React/Next.js, and other awesome tech-related stuff 😉
In the previous blog...
We learned about Images. What image is, and how it works internally. In this blog, we are gonna dive deep into Containers and learn what they are, how they differ from VMs, their use cases, their lifecycle, and much more. So let's get right into it.
What is a container?
Containers are one of the main ideas behind Docker. If you understand what a container is and how to run one, most Docker commands will start to make sense.
A container is a running copy of an image. What does that mean!!?
In the previous blog, we learned about images and saw that an image is like a blueprint/class that has everything needed to run an app. And to make use of the class what do we do in programming!!?? Yes, we make objects out of it.
That's what a container is. A container is what you get when you start that image. And you can start many containers from the same image, as you would with a class and an object.
Let's now see the difference between Containers and VMs, because hey, we had VMs earlier, which solved our problems, right? Then why container?
Containers vs Virtual Machines (VMs)
Containers and VMs both run on a host machine (your laptop, a server, or a cloud instance). But they work differently.
How VMs work
VMs use a hypervisor. You might or might not know about a hypervisor, so let me give you the basic idea about it.
Hypervisor
A hypervisor is software that lets you run multiple virtual machines (VMs) on one physical computer. It creates virtual machines, Gives each VM its own CPU, memory and storage. It keeps VMs isolated from each other and shares the physical hardware safely.
So instead of one computer running one OS, you can run: Window, Linux, Another Linux, etc all on the same machine
So each VM has, its own OS and kernel. This is why we say "Hypervisors virtualize hardware."
How do containers work?
Unlike VMs, containers do not create an OS for every app. It shares the host operating system and also shares its kernel.
What it does is split OS resources into isolated containers, meaning each container has its own filesystem, processes, and network space.
This is why we say, “Containers virtualize the operating system.”
One downside of containers is that they are less secure by default than VMs, because isolation is not as strong as that of VMs. There are ways to improve security, but they can add complexity.
Running your first container
Let's now create our first container, and the easiest way to start a container is:
docker container run <image> <app>
Example:
docker container run -it ubuntu /bin/bash
What this does:
docker container runcreates and starts a new container-itconnects your terminal to the container (interactive mode)ubuntuIs the image/bin/bashis the app (a shell) that runs inside the container
Your terminal prompt will change because you are now inside the container.
What's happening behind the scenes?
So when you hit enter after running the above command, the Docker client will send this command to the API server running on the Docker Daemon. Docker Daemon will search for the Docker host's local image repository to see if it already has a copy of the requested image. If it finds the image, it will pull it locally, otherwise, it will go to the Docker hub (image repository) and see if it can find it there.
Once the image is pulled, Docker Daemon tells containerd and runc to create and start the container (remember the Docker architecture we discussed in Part -1). Once its done you will be able to get inside the container.
A container runs as long as the main app is running. If the app exists, the container stops. If you stop the container, it stops. If you remove the container, it is gone.
Stopping, starting, and deleting containers
Common lifecycle commands:
- Stop a running container:
docker container stop <container>
- Start a stopped container:
docker container start <container>
- Remove a container forever:
docker container rm <container>
Working with container processes
If you are inside a container running /bin/bash, and you kill that main bash process, the container stops.
To exit the container but keep it running:
- Press:
Ctrl-PQ
Now you are back on your host machine, but the container is still running in the background.
Check running containers:
docker container ls
Re-attach using exec
You can open a new shell inside the running container:
docker container exec -it <container_id> bash
This creates a new process inside the container.
So if you type exit here, the container can still stay alive because the original main process is still running.
Container lifecycle
You can give a custom name to your container like this
docker container run --name boo -it ubuntu:latest /bin/bash
After running it, we will be inside the container. Let's create a file here
cd tmp
echo "Hello World" > newfile
ls -l
cat newfile
Detach without stopping it:
Ctrl-PQ
Stop it:
docker container stop boo
Start it again:
docker container start boo
Go back inside:
docker container exec -it boo bash
Check the file:
cd tmp
ls -l
cat newfile
You will see the file is still there.
So what did we learn from this?
Two important notes
That the data lives on the Docker host. If the host fails, the data is lost.
Containers are meant to be immutable, so writing data inside them is not a good habit.
That is why Docker has volumes, which store data outside the container. We will look into volumes in the upcoming blog.
Stopping containers gracefully
There is a big difference between stopping and force-killing.
docker container stopis polite.It sends a
SIGTERMto the main process (PID 1) and gives it time (usually 10 seconds) to shut down cleanly.If it does not stop in time, Docker sends
SIGKILL.docker container rm -fis not polite.It kills the container right away (no clean shutdown).
Restart policies
It’s often a good idea to run containers with a restart policy. Why do we care? Because in the real world, we might have some container that crashes or stops suddenly, and we want them to restart automatically. This is where Restart policies come into play.
Restart policies enable Docker to automatically restart them after certain events or failures have occurred.
Common policies are:
always- If we attach this policy to the container, Docker will always restart the stopped container if it's closed by Docker or fails.unless-stoppedon-failed(often written ason-failure)
Example: Let's create a container with the always policy attached.
docker container run --name zoo -it --restart always ubuntu:lastest bash
Now If you type exit, and get out of the container, the container stops, but Docker starts it again because the policy is always. Try docker container ls and see.
See how the container was created 19 seconds ago, but has only been up for 11 seconds. This is because the exit command killed it and Docker restarted it. Be aware that Docker has restarted the same container and not created a new one.
Difference between always and unless-stopped:
always: restarts even after Docker daemon restartsunless-stopped: does not restart after daemon restart if it was already in a stopped state
Let's see it in action: Create two container with name always and unless-stopped with respective policies attached
docker container run -d --name always \
--restart always \
ubuntu:latest sleep 1d
docker container run -d --name unless-stopped \
--restart always \
ubuntu:latest sleep 1d
Now check with docker container ls
Now lets run, and restart the Docker
docker container stop always unless-stopped
Now run
docker container ls -a
Notice that the “always” container has been restarted but the "unless-stopped" container has not.
The on-failure policy will restart a container if it exits with a non-zero exit code.
Let's clean up everything and remove all the container now.
docker container rm $(docker container ls -aq) -f
Be careful with this command as this command will remove every container running forcefully.
Quick list of useful container commands
docker container run— start a new containerdocker container ls— list running containersdocker container ls -a— list all containers (including stopped)docker container exec— run a command inside a running containerdocker container stop— stop a containerdocker container start— start a stopped containerdocker container rm— delete a containerdocker container inspect— detailed container infoCtrl-PQ— detach without stopping the container
Conclusion
We saw how container is beneficial and works with all the important commands to start, stop, and remove. Also we learned how restart policies plays an important role in Docker ecosystem.
In the next blog, we will implement everything we learned so far by containerizing the application. Untill then...





