Skip to main content

Docker Cleaning Up Cli Lab

· 3 min read

Lab 1: The "Junk Generator" (Visualize the problem)​

  • Check Space: docker system df (Note the numbers).

  • Create Junk:

  • Run a container: docker run -d --name junk-app alpine sleep 1000

  • Stop it: docker stop junk-app

  • Pull an image: docker pull busybox

  • Check Space Again: docker system df (Reclaimable space increased).

  • Clean Up: docker system prune -f

  • Verify: docker ps -a (The stopped container is gone). docker images (Busybox is still there! Why? Because it is not "dangling", just unused).

  • Deep Clean: docker system prune -a -f

  • Verify: docker images (Busybox is gone).

Lab 2: The "Orphan Volume" Hunt​

  • Create Volume: docker volume create orphan-vol

  • Check List: docker volume ls

  • Prune: docker volume prune -f

  • Check List: docker volume ls (It’s gone).


Lab 1: The "Time Machine" Clean (Using Filters)​

Goal: Automate cleanup safely by only deleting old junk.

  • Create "Old" and "New" Junk:

  • We can't actually fake time easily, so we will use the logic.

  • Pull an image: docker pull hello-world (This is "New").

  • The Command:

  • docker system prune -a --filter "until=24h"

  • Explanation: This command looks for junk created more than 24 hours ago.

  • Result: Since you just pulled hello-world, it is preserved.

  • The Comparison:

  • Now run: docker system prune -a (Without filter).

  • Result: hello-world gets deleted because it is not currently running.

  • Lesson: Use until=24h in your cron jobs (automated scripts) to avoid deleting images you just built but haven't started yet.

Lab 2: The "Dependency Hell" (Why can't I delete this?)​

Goal: Understand image layers and why Docker sometimes refuses to delete.

  • Create Base Image:

  • Create file Dockerfile.base: FROM alpine

  • Build: docker build -t my-base:v1 -f Dockerfile.base .

  • Create Child Image:

  • Create file Dockerfile.child: FROM my-base:v1

  • Build: docker build -t my-child:v1 -f Dockerfile.child .

  • Attempt Deletion:

  • docker rmi my-base:v1

  • Result:

  • Error: image is being used by ...

  • Why? Docker protects you. If you delete the base, the child breaks.

  • Fix:

  • Delete the child first: docker rmi my-child:v1

  • Now delete the base: docker rmi my-base:v1

  • Success!


Lab 3: The "Silent Disk Killer" (Log Explosion)​

Goal: Simulate a container filling the disk with logs and fix it without restarting.

  • Create the Problem:

  • Run a container that spams logs endlessly.

  • docker run -d --name spammer alpine sh -c "while true; do echo 'CRITICAL ERROR: Disk is filling up fast...'; sleep 0.01; done"

  • Observe the Growth:

  • Let it run for 30 seconds.

  • Find the log file: LOG_PATH=$(docker inspect --format='{{.LogPath}}' spammer)

  • Check size: ls -lh $LOG_PATH (It will grow by MBs every second).

  • Attempt Prune (Fail):

  • Run docker system prune.

  • Result: Does nothing. The container is running, so logs are "active."

  • The Architect Fix (Truncate):

  • You cannot delete the file while open, but you can empty it.

  • truncate -s 0 $LOG_PATH

  • Check size again: ls -lh $LOG_PATH (It is now 0 bytes!).

  • The Permanent Fix (Log Rotation):

  • Stop the spammer: docker rm -f spammer

  • Run with limits: docker run -d --log-opt max-size=1m --log-opt max-file=3 alpine ...

  • Result: Docker will now automatically delete old logs when they reach 1MB.