As I embark on exploring docker containers and their capabilities, I find that very quickly I have an excessive sprawl of containers and images that are in use or not in use but it’s exceptionally difficult to find out aggregated information across all of the containers.
This is my part 1 of my series in an attempt to try and ease the operational aspect of dockers.
Github Repository is available here –> https://github.com/TheScriptGuy/docker-operations
containers_exited_days.sh
This script’s intention is to allow one to find all containers that have exited after <x> number of days on the server.
The idea being that it becomes exceptionally difficult after you have a server that’s been overloaded with some “operational friction”.
#!/bin/bash
# Check if Docker is installed
if ! command -v docker &> /dev/null; then
echo "Docker command not found. Please install Docker and try again."
exit 1
fi
# Validate script arguments
if [[ "$#" -ne 1 ]] || ! [[ "$1" =~ ^[0-9]+$ ]]; then
echo "Usage: $0 <number_of_days>"
exit 1
fi
# Number of days threshold
days_threshold=$1
# Get all containers (including exited ones) with their info
mapfile -t docker_containers < <(docker ps -a --format "{{.ID}} {{.Image}} {{.Status}}")
# Display relevant images
echo "Images with containers exited more than $days_threshold day(s) ago:"
# Iterate through each line (container) of docker_containers
for container in "${docker_containers[@]}"; do
# Extract container ID, image, and status
container_id=$(echo "$container" | awk '{print $1}')
container_image=$(echo "$container" | awk '{print $2}')
container_status=$(echo "$container" | cut -d' ' -f3-)
# Check if the container is exited
if [[ "$container_status" == Exited* ]]; then
# Extract the age part of the status, if present
age_string=$(echo "$container_status" | sed -n -e 's/Exited ([0-9]\+) \(.*\) ago/\1/p')
# Check if age_string contains "day", "month", or "year"
if [[ "$age_string" == *day* ]]; then
age_days=$(echo "$age_string" | awk '{print $1}')
elif [[ "$age_string" == *month* ]]; then
age_months=$(echo "$age_string" | awk '{print $1}')
age_days=$((age_months * 30))
elif [[ "$age_string" == *year* ]]; then
age_years=$(echo "$age_string" | awk '{print $1}')
age_days=$((age_years * 365))
else
# Set age_days=0 if age is in minutes/hours/weeks or unrecognized
age_days=0
fi
# Check if the age is greater than the threshold
if [[ $age_days -gt $days_threshold ]]; then
echo "- $container_image (Container ID: $container_id, Status: $container_status)"
fi
fi
done
An example for usage would be something like this:
$ ./containers-exited-days.sh 10
Images with containers exited more than 10 day(s) ago:
- server/prod:1.0 (Container ID: 0e2848ed8d89, Status: Exited (1) 2 months ago)
- server-dev/container5:latest (Container ID: 80389c50ecf2, Status: Exited (0) 2 months ago)
- server-prod/container1:latest (Container ID: abf9a8314cbd, Status: Exited (137) 12 months ago)
- server/container2:latest (Container ID: e7c73292fb7f, Status: Exited (137) 2 years ago)
- server/container1:2.3 (Container ID: 111624e70ac1, Status: Exited (130) 2 years ago)
This should allow you to more easily find the containers that are “no longer in use”.
