Understanding Container Management in Docker and Dangling Images

When using Docker, we frequently create, stop, and remove containers. If not managed properly, leftover containers and images — especially dangling images (unreferenced image layers) It can make your system messy and use up a lot of disk space.

Benefits of Proper Docker Management:

  • Keeps your system organized

  • Ensures smooth container performance

  • Frees up unused disk space

  • Boosts overall Docker efficiency


1. Dangling Images

Dangling images are like leftover junk files they’re image layers without a tag and not used by any container.

What Happens If You Delete an Image Used by a Running Container?

In Docker, if an image is mapped to a container and the container is in a Running state, and you try to delete that imageThe Repository and Tag go to <none>

  • The image is NOT deleted; it is just untagged.

Lets see how its works

We have this image on our system: kkkeduction123456/javawebappp:1.3.0

We’ll start a container using the image kkkeduction123456/javawebappp:1.3.0 and name the container one

The container named one is now running and actively using the image.

Delete the Image Using Its Name

Deleting the image using its Image ID is not possible; we need to use the image name only and not the image ID if it's still used by a running container.

To forcefully delete a specific image by name:

docker rmi -f kkeduction123456/javawebappp:1.3.0

You’ll now see: the image is now untagged have no tag (<none>) , but it’s not dangling because it’s still in use by the running container one.

Why remove them?
They eat up disk space. Over time, your system becomes slow or runs out of space.

Command to check:

docker images -f dangling=true

Looks like a dangling image, right? But then you ran: docker image prune

Why docker image prune Didn’t Clean Anything (Even When an Untagged Image Exists)

And Docker said: Total reclaimed space: 0B

Here's Why: It’s Not Really Dangling

That image:

  • Has no repository or tag → <none> / <none>

  • BUT it's still being used by a running container — in your case, the container named one

So, even though it looks like a dangling image, Docker knows it’s still in use.

Docker will never delete an image that’s currently used by any container — even if it’s untagged.

True Dangling Images

A truly dangling image is:

  • Untagged (<none> / <none>)

  • Not used by any running or stopped container

Only then will docker image prune remove it.


What You Need to Do

To actually remove this image:

  1. Stop the container:

docker stop one
  1. Delete the container:

docker rm one
  1. Now run prune again:

docker image prune

This time, Docker will detect the image is not in use anymore, and it will be safely deleted.


Container Management in Docker

2.Create and Run Containers

You can run as many containers as you want from the same image — for example, kkeducation12345/javawebapp:latest

But you must follow two rules:

  1. Each container must have a unique name (--name)

  2. Each must use a different host port (-p <host>:<container>)

docker run -d -p 8080:8080 --name one kkeducation12345/javawebapp:latest
docker run -d -p 8081:8081 --name two kkeducation12345/javawebapp:latest

  • Container one maps port 8080 on the host to port 8080 inside the container.

  • Container two maps port 8081 on the host to port 8081 inside the container.

Why different ports?
If both containers try to use the same host port (like 8080), Docker will throw an error:

“port is already allocated”

Even though both containers are running the same internal app (on port 8080), they're exposed to the host on different ports.


3. Create Container Without Running

It creates the container but does not keep it running — the container immediately goes into "Created" state, and you need to start it again manually using docker start."

If your goal is only to create the container (not to run it immediately),don't use -d in that case!

docker run -p 7070:7070 --name three kkeducation12345/javawebapp:latest 
docker start three

Container three is in an create state.you need to start it again manually using docker start

Now container three has been started and is running.


4. Rename Container

Sometimes, you might name a container incorrectly — a typo or unclear name. Instead of deleting and recreating it, you can simply rename it, just like using mv in Linux.

docker rename oldname newname
  • oldname → The current name of the container (source)

  • newname → The new name you want to give it (target)

docker rename one order-mgnt

Here, we have changed the container name from "one" to "order-mgnt."


5. Interact Inside Container

To access the container’s terminal and explore its filesystem, use the following command.

docker exec -it <container_name> /bin/bash (or) docker exec -it <container_id> /bin/bash

Going inside the container's terminal is very useful for debugging or checking the application deployment, especially in cases like Java web apps deployed in Tomcat.


6. Inspect Container

docker inspect gives a detailed report in JSON format, showing all the important technical details about Docker items like containers or images. It provides information about their configuration, environment variables, network settings, and more. This metadata is useful for debugging, monitoring, or understanding how your Docker objects are configured and connected.

docker inspect <container name or id >

What you get when you inspect a container:

  • Container ID and Name

  • Image used by the container

  • Command and arguments used to start the container

  • Environment variables set inside the container

  • Mapped ports (which host ports are forwarded to which container ports)

  • Mounted volumes and their paths inside the container

  • Network details such as IP address and network mode

  • State information (running, paused, exited, etc.)


7. Stop vs Kill

The difference between docker stop and docker kill lies in how they terminate a container:

  • docker stop sends a SIGTERM signal first, asking the application inside the container to shut down gracefully. If the container doesn’t stop within a timeout period, Docker then sends a SIGKILL signal to forcefully stop it. This gives the app a chance to clean up and exit properly.

  • docker kill immediately sends a SIGKILL signal, which forces the container to stop right away without any cleanup or warning.

When to use each?
Use docker stop when you want to shut down containers normally, like during maintenance. Use docker kill only when the container is stuck, unresponsive, or not stopping with the normal command.

docker stop <container>
docker kill <container>

Both docker stop and docker kill are used to stop a container, making it go into the Exited state.

  • Stop = Graceful (like asking app to shut down nicely)

  • Kill = Immediate (like pulling the plug)


8. Pause and Unpause

You can temporarily pause a running container using:

docker pause <container name or ID>
docker pause two

This freezes all processes in the container — like pressing a pause button.

When you want to resume its activity, simply run:

docker unpause two

Pausing a container temporarily freezes all its processes without shutting the container down.


9. Check Logs

To view the logs (output) of a container from the beginning:

docker logs <container name or id >
docker logs two

This shows all the logs generated by the application running inside the container — useful for debugging, monitoring, or checking startup status.

To stream live logs use:

docker logs -f two

The -f flag stands for "follow", meaning it continuously updates the logs as new output comes in — perfect during live debugging or watching a deployment.

you can also use docker exec -it mycontainer bash to go inside thne container and check logs in files manually (like /var/log/...). But for quick access, docker logs is faster and easier.

Example:

Your app is not starting, and users are complaining. Instead of entering the container, just run docker logs

You might see an error like:

Exception: Could not connect to database

Problem identified instantly.


10. See Running Processes in a Container

To view the processes running inside a container, use:

docker top <container name or id>
docker top two

docker top shows which processes are running inside the container, like how ps works in Linux.
It helps you check if your app (like Java or Tomcat) is running properly or stuck.


11. Monitor Resources

docker stats

This shows real-time usage of CPU, memory, network, and disk I/O for each running container.

Example Use Case:
Your team says, “Jenkins is very slow today.”
You run docker stats and notice one container is using 90% of the system’s RAM.
Now you know where the problem is — and can take action like restarting it or setting memory limits.


12. Set Memory Limits

You can restrict how much memory a container is allowed to use:

By default, Docker containers can use as much system memory as available — unless you explicitly set a limit.

You can check a container’s live memory usage using: docker stats four

This means the container is currently using 91.84MiB of the 512MiB limit set during container creation (via --memory flag).

If no limit is set, the right-hand value shows total system memory instead.

  • If you set a memory limit using --memory="512m" and the container tries to use more than 512MiB:

  • The container will be killed automatically by the Docker runtime (OOM – Out of Memory error).

  • It does not swap or get more memory — the limit is strict.

  • If you set the memory too low, the container will start, but it might crash or exit immediately during execution.

Now let's look at an example of what happens when you try to run a container with very low memory.

We’ll create a container named six with only 64MB of RAM:

docker run --memory="64m" -d -p 6060:6060 --name six kkeducation12345/javawebapp

  • At first, when you run docker ps, the container six appears as Up 5 seconds.

  • But moments later, docker ps -a shows it has Exited (137) — a common exit code for memory issues.

To confirm the cause: you can check the reason by running docker inspect <container>

docker inspect six | grep -iC5 "OOMKilled"
  • -i: Makes the search case-insensitive.

  • -C5: Displays 5 lines before and after the matching line.

"OOMKilled": **false** → The container did not exceed memory or was stopped/killed for some other reason.

"OOMKilled": **true** → The container was killed by the Docker runtime because it exceeded the memory limit set with --memory.

Note:

  • Docker doesn’t have built-in alerts when memory crosses 90%. For that, you'd need external monitoring tools (like Prometheus + Alertmanager).

  • Unlike Kubernetes, Docker only supports setting resource limits with --memory; it does not support resource requests vs limits.


13. How to Copy Files Between Host and Docker Container (Both Ways)

Docker containers are like mini virtual machines — isolated, self-contained, and running your applications. But sometimes, you need to move files in or out of them.

  • From your local machine (host) to a running Docker container — e.g., uploading a .war file, config, or script.

  • Or from the container to the host — e.g., retrieving logs, build artifacts, or reports.

Copy File From Container to Host:

To copy the catalina.2025-05-17.log log file to your host:

docker cp two:/usr/local/tomcat/logs/catalina.2025-05-17.log catalina.2025-05-17.log

  • two is the name of your container.

  • This will place the log in your current working directory on the host.

Copy File From host to container:

To copy a file (e.g., demo.txt) from your current project directory on your host into the container:

docker cp demo.txt two:/usr/local/tomcat/

Verification Inside Container

docker exec -it two /bin/bash

demo.txt is listed, confirming it was successfully transferred.

  • This injects demo.txt into the container’s /usr/local/tomcat/.

14. Create Docker Image from a Container

What is docker commit?

docker commit means creating a new Docker image from an existing container (which is already running or stopped).

For example:

  • You take a container and make some changes inside it — like installing software, copying files, or doing some setup.

  • Now, you want to save that modified container as an image, so that you can use it later or run the same setup again.

Use the container Name or ID to create a new image.

You’ll see updatedimage listed there with a unique IMAGE ID.

In short:

"docker commit takes a snapshot of the current container and saves it as a new image."


Why All This Matters?

In real projects, Docker is not just about running containers. You will need to:

  • Debug when something breaks

  • Clean disk when images pile up

  • Control memory to avoid container crashes

  • Interact with logs and files

  • Deploy same image in different ways for testing, staging, production

Usecase Summary

You’re working at a software company. You deployed your Spring Boot app in 3 containers (dev, test, prod). Now:

  • Logs not visible? → docker logs

  • Want to monitor RAM usage? → docker stats

  • App crashed? → docker exec, debug logs

  • Multiple clients? → Use same image, different ports

  • Too many old images? → docker image prune

0
Subscribe to my newsletter

Read articles from Kandlagunta Venkata Siva Niranjan Reddy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kandlagunta Venkata Siva Niranjan Reddy
Kandlagunta Venkata Siva Niranjan Reddy