Skip to main content

Command Palette

Search for a command to run...

Docker Container Lifecycle: Every Command You Need to Know

If you are learning Docker seriously, there is one thing you need to accept early. Knowing what a container is means very little if you do not know how to manage one. Starting, stopping, pausing, logging in, copying files, checking memory usage, saving images, and cleaning up - all of this is what makes the difference between someone who has heard of Docker and someone who can actually work with it. This article walks through everything a working Docker environment demands. We are going through the full container lifecycle with real commands, real explanations, and the kind of detail that actually stays with you. By the end, you will have a solid reference for your daily work and your interviews.

Updated
15 min read
Docker Container Lifecycle: Every Command You Need to Know
S
Passionate about Cloud and DevOps engineering. I write structured technical notes and beginner-friendly articles on AWS, Linux, CI/CD, networking, system architecture and modern software delivery workflows.

Docker Architecture: A Quick Recap

Before touching commands, it helps to remember what is actually happening when you type something into your terminal.

The Docker architecture has three pieces that talk to each other. You have the Docker CLI, which is what you type into. The CLI sends your request to a REST API. The REST API then talks to the Docker daemon. The daemon is the engine that actually does the work.

So the flow is:

Docker CLI  >  REST API  >  Docker Daemon

The daemon must always be running. If you type a Docker command and the daemon is not up, nothing works. You will see an error that says it cannot connect to the daemon. That is your first hint that the service needs to be started.


Installing Docker and Starting the Daemon

On an Amazon Linux or any RHEL-based system, installation is one command:

yum install docker -y

Once installed, start the Docker service:

systemctl start docker

To confirm the version:

docker -v

Now you are ready. Without starting the daemon first, every Docker command you run will fail with a connection error. Think of the daemon as the engine. The CLI is just the steering wheel. If the engine is off, turning the wheel does nothing.


Basic Commands to Get Oriented

These are the commands you will type more than anything else:

List all images on your machine:

docker images

List all containers (running and stopped):

docker ps -a

List only the currently running containers:

docker ps

The difference between docker ps and docker ps -a is simple. docker ps shows you only what is alive right now. docker ps -a shows you everything, including containers that have been stopped or exited. In practice, you will almost always use docker ps -a because you want to see the full picture.


Pulling Images from Docker Hub

Before you can create a container, you need an image. Images are pulled from Docker Hub. Think of Docker Hub as a registry, a library of pre-built images that you can grab and use.

To pull Amazon Linux:

docker pull amazonlinux

To pull Ubuntu:

docker pull ubuntu

After pulling, run docker images again and you will see both listed. The output shows the image name, tag, image ID, when it was created on Docker Hub, and the size.

Here is a helpful analogy. In AWS, you have AMIs, Amazon Machine Images. An AMI is a copy of an operating system that you use to launch an EC2 instance. A Docker image works the same way. It is a packaged copy of an operating system, and sometimes an application on top of it. From that image, you create containers, just like from an AMI you launch instances.


Creating Containers: Interactive and Detached Modes

Now let us create a container. The command is docker run, and you will use it constantly.

Interactive Mode

To create a container and log into it immediately:

docker run -it --name amazon-linux-container amazonlinux

Breaking this down:

  • docker run creates and starts the container

  • -it puts you into interactive mode, meaning your terminal connects directly to the container's shell

  • --name amazon-linux-container gives the container a human-readable name

  • amazonlinux is the image to use

The moment you hit enter, you are inside the container. Your prompt changes to show you a different shell. That is the container. You can install software inside it, create files, do whatever you need. It is like a very lightweight virtual machine, except it is not actually a virtual machine. It is a package running on top of your host system.

For example, inside an Amazon Linux container, you can run:

yum install git -y

Git installs inside the container. Your EC2 instance does not get Git. Only the container does.

Exiting a Container Without Stopping It

This is something that trips up a lot of people. If you press Ctrl + D inside a container, you exit and the container stops. If you do not want to stop the container, use this key combination instead:

Ctrl + P, then Ctrl + Q

This detaches your terminal from the container while leaving the container running. When you run docker ps -a, the container status will still show as Up, not Exited.

Detached Mode

Sometimes you do not want to log into the container at all. You just want it running in the background. For that, add -d:

docker run -itd --name ubuntu-container ubuntu

The -d flag stands for detached. The container starts, runs in the background, and you stay on your host machine. No automatic login. You get back your prompt immediately.

After running this, do docker ps -a. You will see the container listed as running, with a container ID. The container ID is the full identifier, though the output shows only the first few characters.


Logging Into a Running Container

Once a container is running, there are two ways to get inside it.

docker attach

docker attach ubuntu-container

docker attach connects your terminal to the main process of the container. This is the primary process that keeps the container alive. The problem is that if you exit from an attached session with Ctrl + D, you terminate that main process, and the container stops.

docker exec

docker exec -it ubuntu-container /bin/bash

This is the preferred way. docker exec creates a new process inside the container rather than attaching to the main one. When you exit this session, the container keeps running because you never touched its main process.

The difference in plain terms:

docker attach hooks you into the container's main thread. If you leave, the thread is gone and the container dies.

docker exec spawns a fresh shell process. When you leave, only that shell dies. The container carries on.

For day-to-day work, always use docker exec. It is safer and does not risk accidentally killing a running container.

To exit cleanly from either method without stopping the container:

Ctrl + P, then Ctrl + Q

Container Lifecycle: Start, Stop, Restart, Kill

Containers can be in several states. Running, stopped, paused, and dead. Here is how you move between them.

Stopping a Container

docker stop ubuntu-container

docker stop sends a graceful shutdown signal (SIGTERM) to the container's main process. It gives the process time to finish what it is doing, save any state it needs to, and then shut down cleanly. Only after that does the container stop.

Starting a Container

docker start ubuntu-container

If a container is stopped, this starts it again. Run docker ps -a after and the status changes from Exited to Up.

Restarting a Container

docker restart ubuntu-container

This stops and starts the container in one command.

Killing a Container

docker kill ubuntu-container

docker kill sends an immediate SIGKILL signal. It does not wait for the process to finish anything. The container is gone right now. No graceful cleanup, no waiting.

The difference between stop and kill is one of the most common interview questions on Docker:

docker stop gracefully stops the container. It waits for running processes to finish before shutting down.

docker kill forcefully stops the container immediately. Processes inside it are terminated without warning.

In production, always prefer docker stop. Use docker kill only when a container is stuck and not responding to stop.

Pausing and Unpausing a Container

docker pause ubuntu-container

Pausing freezes all processes inside the container. The container is still there, still consuming memory, but nothing inside it is executing. Think of it as hitting a pause button on a video.

When you try to log into a paused container, you will get an error saying the container is paused and cannot be executed. To resume:

docker unpause ubuntu-container

Removing Containers

Once you are done with a container and do not need it anymore, remove it.

First, stop it:

docker stop ubuntu-container

Then remove it:

docker rm ubuntu-container

If you try to remove a running container, you will get an error. You must stop it first, or use the force flag:

docker rm -f ubuntu-container

The -f flag force removes a running container without needing to stop it first. It is the equivalent of kill and remove in one step.


Inspecting Containers

docker inspect

docker inspect ubuntu-container

This command dumps the complete configuration and state of the container in JSON format. Container ID, creation time, current state (running, paused, dead), the image it was built from, environment variables, network settings, volume mounts, the process ID it is using, the platform it runs on, and much more.

If you ever need to debug why a container is behaving a certain way, docker inspect is your first stop. It tells you everything Docker knows about that container.

docker logs

docker logs ubuntu-container

This shows the stdout and stderr output from inside the container. If your application running inside the container is logging anything, this is where you see it. If the container is new and nothing has been run, the logs will be empty.

In real deployments, checking container logs is how you debug application errors.

docker top

docker top ubuntu-container

This shows all the processes currently running inside the container. It is the container equivalent of the top command in Linux. If you have an application server running inside the container, you will see that process listed here along with its PID.

docker stats

docker stats ubuntu-container

This shows live resource usage for the container: CPU percentage, memory usage, memory limit, network I/O, and block I/O. The output refreshes continuously, similar to the top command.

To stop the live output, press Ctrl + C.

This is the command you reach for when you want to know how much CPU or memory a container is consuming at any given moment. In production, this is your quick check before deeper investigation.


Copying Files into a Container

There are times when you have a file on your host machine and need it inside a running container. The command for this is docker cp.

Say you have a file called hello.txt on your EC2 instance and you want it inside the container at /tmp/:

docker cp hello.txt ubuntu-container:/tmp/

To verify it arrived:

docker exec -it ubuntu-container /bin/bash
cd /tmp
ls

You will see hello.txt sitting there. This is useful when you need to inject configuration files, certificates, or any other files into an already-running container without rebuilding the image.


Saving and Loading Images as TAR Files

This is not something you do every day, but it is good to know.

If you have built an image and need to share it with someone who cannot pull from Docker Hub, you can package the image into a TAR file:

docker save ubuntu > ubuntu.tar

This compresses the entire image into a single TAR archive. You can then copy this file to another machine using SCP or any file transfer method.

On the receiving end, to load that TAR file back as a Docker image:

docker load -i ubuntu.tar

After loading, run docker images and the image will appear as if it had been pulled from Docker Hub.

The ideal way to share images is through Docker Hub: push from one machine, pull on another. But when Docker Hub is not an option, save and load get the job done.


Cleaning Up Unused Images

In any active environment, images accumulate. Developers pull images, build images, experiment, and then leave old ones sitting around eating up disk space. Docker has a built-in command to clean all of that up:

docker image prune

This deletes all unused images, meaning images that no running or stopped container is currently using. It will not touch images that are actively being used.

This is an important command to know for interviews. The question often comes up as: "How do you clean up unused Docker images?" The answer is docker image prune.


Creating an Image from a Container

Normally, the right way to create a Docker image is through a Dockerfile, which gives you a repeatable, automated, version-controlled build process. But there is another way that is worth knowing.

If you have been working inside a container, installing software, making configurations, and you want to capture that state as a new image, you can use docker commit.

Here is the scenario. Start with a Ubuntu base container:

docker run -it --name uc ubuntu

Inside it, install a few things:

apt update -y
apt install apache2 python3 mysql-server -y

Exit the container without stopping it:

Ctrl + P, then Ctrl + Q

Now commit the container state to a new image:

docker commit uc uc-new-image

Run docker images and you will see uc-new-image listed. This new image contains Ubuntu with Apache, Python 3, and MySQL all pre-installed. Anyone who creates a container from this image gets all of that automatically.

To verify:

docker run -it --name uc-new-cont uc-new-image

Inside the new container, check if Python 3 is there:

python3 --version

It is there. Because that container was created from an image that had it baked in.

Again, in real-world practice, Dockerfiles are the way to build images. But docker commit is useful when you need to quickly snapshot a working container state, or when you are experimenting and do not want to write a Dockerfile yet.


Quick Reference: All Commands Covered

Here is a clean reference of every command discussed in this session.

Installation and setup:

yum install docker -y          # Install Docker on Amazon Linux / RHEL
systemctl start docker         # Start the Docker daemon
docker -v                      # Check Docker version

Images:

docker images                  # List all local images
docker pull <image-name>       # Pull an image from Docker Hub
docker rmi <image-name>        # Remove an image
docker save <image> > <file.tar>    # Save image to TAR file
docker load -i <file.tar>           # Load image from TAR file
docker image prune             # Delete all unused images

Containers - creating and running:

docker run -it --name <name> <image>      # Create and log in interactively
docker run -itd --name <name> <image>     # Create in detached mode (background)

Containers - logging in:

docker attach <container-name>                    # Attach to main process (risky)
docker exec -it <container-name> /bin/bash        # Open a new shell (preferred)

Containers - lifecycle:

docker ps                      # List running containers
docker ps -a                   # List all containers
docker stop <name>             # Gracefully stop a container
docker start <name>            # Start a stopped container
docker restart <name>          # Restart a container
docker kill <name>             # Forcefully stop a container
docker pause <name>            # Freeze all processes in a container
docker unpause <name>          # Resume a paused container
docker rm <name>               # Remove a stopped container
docker rm -f <name>            # Force remove a running container

Containers - inspection and monitoring:

docker inspect <name>          # Full container details in JSON
docker logs <name>             # View container output logs
docker top <name>              # Show running processes inside container
docker stats <name>            # Live CPU and memory usage

Files and images from containers:

docker cp <file> <container>:<path>       # Copy local file into container
docker commit <container> <new-image>     # Create image from container state

stop vs kill: The Interview Question

This comes up in nearly every Docker interview, so it deserves its own summary.

docker stop sends SIGTERM to the main process inside the container. The process can catch this signal, finish its current work, write anything to disk, and shut down cleanly. Docker waits a default of ten seconds for this to complete. If the process has not stopped by then, Docker sends SIGKILL automatically.

docker kill sends SIGKILL immediately. There is no waiting, no grace period, no chance for the process to clean up. The container stops right now.

Which one to use: In production, always use docker stop for containers running databases, web servers, or any stateful application. Use docker kill only when a container is hung and not responding to stop.


Summary

What we covered in this session represents the complete operational lifecycle of Docker containers. Starting from pulling base images off Docker Hub, to creating containers in interactive and detached modes, to managing their state through start, stop, restart, pause, and kill, to logging in safely using docker exec, to monitoring resources with docker stats and docker top, and finally to cleaning up images with docker image prune and saving images as TAR files when Docker Hub is not available.

The commands here are not theoretical. These are the exact commands DevOps engineers type every day. Whether you are debugging a running container, checking its resource footprint, copying a config file into it, or snapshotting its state with docker commit, all of this belongs in your working vocabulary.

Practice each command, run them on a real EC2 instance, and the muscle memory builds fast. Docker is not hard. It just takes repetition.

A

This was a really clear breakdown of the Docker container lifecycle. I like how you kept it focused on the actual commands we use day to day instead of getting lost in too much theory. For someone trying to get comfortable with Docker beyond just docker run, this kind of structured walkthrough is super helpful.

What I appreciated most is that you grouped the commands by stage (create, start, stop, inspect, clean up) — it makes it much easier to build a mental model instead of memorizing a random list of flags. That’s exactly the kind of foundation that pays off later when you start working with orchestration tools and CI/CD pipelines.

I’ve been spending more time on containers and DevOps lately, and posts like this really help solidify the basics. Great work, looking forward to more content like this.

S

Thanks for the feedback, I really appreciate it. Glad the structured approach helped make the Docker container lifecycle easier to follow. Mastering these fundamentals is important before moving deeper into CI/CD and DevOps workflows. More practical content coming soon!

A

Thanks for taking the time to reply, really appreciate it.

I’ll keep an eye out for your upcoming posts – I’m trying to build a habit of reading and learning from practical content like this regularly.

I’ve also started writing weekly technical posts myself around Docker, AWS, and DevOps, mainly to document my own learning journey, so it’s always great to come across writers who explain fundamentals this clearly.

More from this blog

Ansible Playbooks Explained: From First YAML File to Managing Real Servers

If you have already run a few Ansible ad hoc commands and seen how they work, you already understand the core idea: one command, many servers. But ad hoc commands only take you so far. When you need to install software, start services, create users, copy files, and print confirmation messages, all in one automated run across multiple servers, that is when you move to playbooks. Playbooks are where Ansible truly earns its place in a DevOps workflow. Everything you do in Ansible at scale, you do through playbooks.

Jun 19, 202613 min read
Ansible Playbooks Explained: From First YAML File to Managing Real Servers

You Have 400 Servers to Configure. Now What? Let Ansible Do the Work.

Picture this. You have four EC2 instances running in your AWS account, and someone asks you to install Apache on all four of them. What do you do? The obvious answer most people go with is SSH into each machine, run the install command, repeat. Simple enough when it is four servers. But what happens when it is forty? Or four hundred? In a real enterprise environment, that number is not exaggerated at all. That is exactly the problem that Ansible was built to solve. And once you understand what it does and how it thinks, you will wonder how anyone managed large infrastructure without it.

Jun 18, 202612 min read
You Have 400 Servers to Configure. Now What? Let Ansible Do the Work.

Building Production-Ready Docker Deployments with Secrets, Stacks, and Distroless Images

This post wraps up the core Docker Swarm curriculum by covering four important topics that complete the picture of production-ready containerized deployments. We start with Docker Secrets, which solves the real-world problem of passing sensitive credentials into containers without hardcoding them. We then look at Docker Stack, which is how you run multi-service Docker Compose files across a Swarm cluster instead of a single host. After that we cover the distinction between replicated and global services, which is a concept that appears in Kubernetes as well. We close with a look at Portainer for those who prefer a visual interface, and a brief introduction to distroless images. Each of these topics builds on everything covered so far. If you have your Swarm cluster running, you can follow along with every command shown here.

Jun 17, 202614 min read
Building Production-Ready Docker Deployments with Secrets, Stacks, and Distroless Images

Beyond One Server: Solving Docker Scaling with Swarm and Container Networks

This post covers three separate but deeply connected topics. We start by finishing what was started with Docker Hub, pushing all four bank service images to a remote registry so they survive beyond any single machine. From there, we identify a real architectural problem with single-host Docker deployments and introduce Docker Swarm as the solution. Finally, we close with Docker networking, explaining how containers communicate with each other both on the same host and across different hosts. By the end of this article, you will understand how to push and pull images from Docker Hub, how to set up a multi-node Docker Swarm cluster, how to create and scale services across that cluster, what self-healing means in practice, and how Docker networking works under the hood.

Jun 17, 202618 min read
Beyond One Server: Solving Docker Scaling with Swarm and Container Networks

Docker Compose in Action: Multi-Container Apps, Nginx Load Balancing & Docker Hub

We built four containerized microservices for an bank application in the last post. Internet banking, mobile banking, insurance, and loans, each running in its own container, each exposed on a separate port. The setup worked. But the process of building and running each container individually by hand was repetitive, error-prone, and simply not practical at scale. This post introduces Docker Compose, and by the end, you will understand not just how to use it, but why it exists, what its real limitations are, how to combine it with Nginx to build a working high availability architecture, and how to push your images to Docker Hub so they are available beyond your local machine. There is also a hands-on project included here that builds a Flask-based Python application behind an Nginx load balancer, which you are expected to complete as a practical exercise.

Jun 16, 202617 min read
Docker Compose in Action: Multi-Container Apps, Nginx Load Balancing & Docker Hub
S

Sai Praneeth's Blogs

37 posts

From SDLC and Agile to DevOps and CI/CD, this blog is where I share structured technical notes, concepts and practical insights in Cloud and DevOps engineering.