Here's a with self-reminders and shortcuts for docker management that I'm trying to optimize. Forking / optimization by others is very welcome.
Key features:
- Validates Docker Compose file existence and handles both .yml/.yaml extensions
- Uses
docker-compose exec
for better service handling - Shows numbered list of services from compose file
- Allows complex commands with spaces/special characters
- Handles command quoting through
sh -c
- Loops until user chooses to exit
- Works with relative paths and different compose file names
Usage example:
- Save as
docker-shell.sh
- Make executable:
chmod +x docker-shell.sh
- Run:
./docker-shell.sh
- Follow prompts to select service and command
The script uses docker-compose exec
which automatically handles container names based on the service definition, making it more reliable than working with raw container names. Commands are executed through sh -c
to properly handle complex commands with spaces and special characters.
#!/bin/bash
find_compose_file() {
local input_path="$1"
if [ -d "$input_path" ]; then
compose_file=$(find "$input_path" -maxdepth 1 \( -name "docker-compose.yml" -o -name "docker-compose.yaml" \) -type f | head -n 1)
[ -z "$compose_file" ] && return 1
elif [ -f "$input_path" ]; then
compose_file="$input_path"
else
return 1
fi
echo "$compose_file"
}
default_path="./"
while true; do
read -e -p "Enter directory/location of docker-compose.y*ml [default: $default_path]: " input_path
input_path=${input_path:-$default_path}
compose_file=$(find_compose_file "$input_path")
if [ $? -eq 0 ]; then
compose_file=$(realpath "$compose_file")
compose_dir=$(dirname "$compose_file")
break
else
echo "Error: No valid docker-compose file found in '$input_path'" >&2
fi
done
services=($(docker-compose -f "$compose_file" config --services 2>/dev/null))
if [ $? -ne 0 ] || [ ${#services[@]} -eq 0 ]; then
echo "Error: Failed to get services from compose file" >&2
exit 1
fi
while true; do
echo -e "\nAvailable services:"
for i in "${!services[@]}"; do
echo "$((i+1)). ${services[i]}"
done
while true; do
read -p "Select service (1-${#services[@]}): " service_num
if [[ "$service_num" =~ ^[0-9]+$ ]] && [ "$service_num" -ge 1 ] && [ "$service_num" -le ${#services[@]} ]; then
selected_service="${services[$((service_num-1))]}"
break
fi
echo "Invalid input. Please enter a number between 1 and ${#services[@]}." >&2
done
read -e -p "Enter command to execute (default: bash): " command_input
command_input="${command_input:-bash}"
echo -e "\nExecuting: docker-compose exec '$selected_service' sh -c \"$command_input\"\n"
docker-compose -f "$compose_file" exec "$selected_service" sh -c "$command_input"
read -p "Do you want to start another shell? [Y/n]: " restart
[[ "$restart" =~ ^[Nn]$ ]] && break
done
echo "Exiting container shell script."
With loop:
#!/bin/bash
# Stop and remove all containers (incl. running and volumes (-v))
docker ps -aq | xargs -r docker rm -vf
#Remove orphaned resources (volumes, networks, build cache) via loop
for resource in volume network system; do
if [ "$resource" = "system" ]; then
docker "$resource" prune -f # System-Prune ohne --all (Keep images!)
else
docker "$resource" prune -f
fi
done
or
#!/bin/bash
docker ps -aq | xargs -r docker rm -vf
# Only volume/network prune in Loop
for resource in volume network; do
docker "$resource" prune -f
done
# separate system prune (Keep images)
docker system prune -f
With xargs:
#!/bin/bash
# Stop and remove all containers (incl. running and volumes (-v))
docker ps -aq | xargs -r docker rm -vf
# Remove orphaned volumes
docker volume prune -f
# Remove orphaned networks
docker network prune -f
# Delete build cache, keep images
docker system prune -f
#!/bin/bash
# Stoppe und entferne alle Container (auch laufende) mit zugehörigen Volumes
docker ps -aq | xargs -r docker rm -vf
# Lösche alle unbenutzten Volumes (z. B. von früheren Containern)
docker volume prune -f
# Optional: Lösche ungenutzte Netzwerke, Images und Build-Cache
docker system prune -af --volumes
https://docs.docker.com/compose/how-tos/use-secrets/ #Shortcuts
Can port mappings be conslidated and externalized by means of variables in order to keep track in case of a multitude of containers and mappings?