Skip to content

Instantly share code, notes, and snippets.

@deardooley
Created July 20, 2018 17:11
Show Gist options
  • Save deardooley/011ce72d1e2ad3c03045879f0ea41b25 to your computer and use it in GitHub Desktop.
Save deardooley/011ce72d1e2ad3c03045879f0ea41b25 to your computer and use it in GitHub Desktop.
Some extra CLI sugar to make working with the Docker command line a bit less painful. Curated from around the web and extended with prompts, regex matching and extra aliases and shortcuts.
#!/bin/bash
# Use these in your .dotfiles to help make Docker more manageable
#alias dip='dmachine ip 2> /dev/null'
alias drund="docker run -d -P"
alias drun="docker run -t -i -P"
alias dimg="di"
alias dexec='dx'
alias dc='docker-compose'
# portable xargs, handles the missing support for -r|--no-run-if-empty
# on non-gnu implementations of xarts
function gxargs() {
is_gnu=$(xargs -r 2>&1 >> /dev/null)
if (( $? )); then
stdin=$(cat <&0)
if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]]
then
# shift the arguments to get rid of the "-r" that is not valid on OSX
shift
# wc -l return some whitespaces, let's get rid of them with tr
linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d '[:space:]')
if [ "x$linecount" = "x0" ]
then
exit 0
fi
fi
# grep returns an error code for no matching lines, so only activate error checks from here
set -e
set -o pipefail
echo $stdin | xargs $@
else
echo $stdin | xargs $@
fi
}
function dmachine() {
if [[ -z "$2" ]]; then
dm_vm=default
else
dm_vm="$2"
fi
docker-machine $1 ${dm_vm}
}
# Build an image with the given name/tag using the Dockerfile in the
# current directory
function dbuild() { docker build -t="$1" .; }
# handles ouptut formatting
function dockererror() {
unset containername;
# Detect whether output is piped or not.
if [[ -t 1 ]]; then
printf '%b\n' "\033[1;31m${@}\033[0m"
else
print $@
fi
} >&2
function di() {
if [[ -z "$1" ]]; then
dimagelike all | sed -e $'s# #\\\n#g' | grep -v "^REPOSITORY:TAG"
else
dimagelike $1 | sed -e $'s# #\\\n#g' | grep -v "^REPOSITORY:TAG"
fi
}
#
# Display tags for an image
#
function ditags {
for Repo in $* ; do
if [[ -z $( echo "$Repo" | grep "/" ) ]]; then
fullRepo="library/$Repo"
else
fullRepo="$Repo"
fi
curl -s -S "https://registry.hub.docker.com/v2/repositories/$fullRepo/tags/" | \
python -mjson.tool | \
sed -e 's#,#,\n#g' -e 's#\[#\[\n#g' | \
grep '"name"' | \
awk -F\" '{print $4;}' | \
sort -fu | \
sed -e "s#^#${Repo}:#"
done
}
# Stop one or more running containers. If none are provided, you will
# be promped with a list of containers.
function dstop() {
# if the user does not provide a container, let them pick one
dwhich $1
if [[ -z "$containername" ]]; then
dockererror "Please specify one or more containers to stop."; return 1;
fi
docker stop $containername;
}
function dtail() {
# if the user does not provide a container, let them pick one
dwhich $1
docker logs --tail=100 -f $containername
}
function dcbounce {
if [[ -z "$@" ]]; then
dc stop
dc rm -f
dc up -d
else
for i in "${@}"; do
dc stop "$i"
dc rm -f "$i"
dc up -d "$i"
done
fi
}
function dcabounce {
if [[ -z "$@" ]]; then
dca stop
dca rm -f
dca up -d
else
for i in "${@}"; do
dca stop "$i"
dca rm -f "$i"
dca up -d "$i"
done
fi
}
function dcbbounce {
if [[ -z "$@" ]]; then
dcb stop
dcb rm -f
dcb up -d
else
for i in "${@}"; do
dcb stop "$i"
dcb rm -f "$i"
dcb up -d "$i"
done
fi
}
function dbounce {
docker restart "$@"
}
function dps() {
if [[ -z "$1" ]]
then
dwhich all
elif [ "$#" -eq 1 ] && [ "$1" == "-a" ]
then
dwhich -a all
else
dwhich "$@"
fi
}
# Remove one or more stopped containers. If none are provided, you will
# be promped with a list of containers.
function drm() {
# if the user does not provide a container, let them pick one
dwhich "$@" '-a'
if [[ -z "$containername" ]]; then
dockererror "Please specify one or more containers to remove."; return 1;
fi
docker rm $containername;
}
# Remove one or more images. If none are provided, you will be promped
# with a list of images. Partial matches and regex are supported.
function drmi() {
# if the user does not provide an image, let them pick one
imagename=$(dimagelike "$@")
if [[ -z "$imagename" ]]; then
dockererror "Please specify one or more partial image names and/or versions to remove or all to remove all images"; return 1;
fi
docker rmi "$imagename";
}
# Docker exec into a container
function dx() {
# if the user does not provide a container, let them pick one
dwhich "$1"
if [[ -z "$containername" ]]; then
dockererror "Please select a valid container to exec."; return 1;
# if the user does not provide a container, or argument, just run the default command
elif [[ -z "$1" ]]; then
docker exec -i -t $containername $2;
# pop the container name from the argument list and run the rest as the command
else
shift
docker exec -i -t $containername "$@";
fi
}
# Does a basic docker exec into a container's bash shell. If the container name isn't provided
# the user is promted for the container name from a list.
function dbash() {
dwhich "$1"
if [[ -z "$containername" ]]; then
dockererror "Please select a valid container to exec."; return 1;
else
dx "$containername" '/bin/bash';
fi
}
# Does a basic docker exec into a container's shell. If the container name isn't provided
# the user is promted for the container name from a list.
function dsh() {
dwhich "$1"
if [[ -z "$containername" ]]; then
dockererror "Please select a valid container to exec."; return 1;
else
dx "$containername" 'sh';
fi
}
# Display realtime info for one or more running containers. If none
# are provided, you will be promped with a list of images. Partial
# matches and regex are supported.
function dstats() {
# if the user does not provide an image, let them pick one
dwhich "$@"
if [ -z "$containername" ]; then
docker stats $(echo $(dps))
else
docker stats $(echo $containername)
fi
}
# removes all untagged images
function dtidy() {
docker images | grep "^<none>" | awk '{print $3}' | gxargs --no-run-if-empty docker rmi
}
# Smokes every container removes every untagged image
function dclean() {
docker ps -aq | gxargs --no-run-if-empty docker rm -f
docker images | grep "^<none>" | awk '{print $3}' | gxargs --no-run-if-empty docker rmi
}
# Smokes every container and every tagged image
function dnuke() {
docker ps -aq | gxargs --no-run-if-empty docker kill
docker ps -aq | gxargs --no-run-if-empty docker rm -f
docker images -q | gxargs --no-run-if-empty docker rmi -f
}
function dlog() {
# if the user does not provide an image, let them pick one
dwhich "$@"
if [ -z "$containername" ]; then
dockererror "Please specify one or more containers for which to display realtime stats."; return 1;
fi
docker logs --tail=500 -f $containername
}
# validates a user-supplied container name. If none is supplied
# the user is prompted to select from a list of containers on the current system
function dwhich() {
containername=''
INCLUDE_STOPPED=''
if [[ "$#" == "0" ]]
then
# nothing to do here
INCLUDE_STOPPED=''
else
iter=1
for i in "$@"
do
if [[ '-a' == "$i" ]]
then
INCLUDE_STOPPED="-a"
shift
#else
# echo -e "leaving argument $i in place\n"
fi
iter="$[iter+1]"
done
fi
containerids=( $(docker ps $INCLUDE_STOPPED | grep -v '^CONTAINER' | awk '{print $NF}') )
if [[ -z "$1" ]]; then
for i in "${!containerids[@]}"
do
echo "[$i] ${containerids[$i]}"
done
echo -n "Select container(s) []: "
eval "read containerresponse"
containerresponse=( $containerresponse )
else
containerresponse=( "$@" )
fi
re='^[0-9]+$'
# if empty, none was provided and none was selected
if [[ -z "$containerresponse" ]]; then
dockererror "Unknown container name. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1;
else
for i in "${!containerresponse[@]}"
do
# validate the numeric selection
if [[ "${containerresponse[$i]}" =~ $re ]] ; then
if [ ${containerresponse[$i]} -ge ${#containerids[@]} ]; then
dockererror "Invalid choice. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1;
else
containername=$(echo -e "${containerids[${containerresponse[$i]}]}\n${containername}")
# echo "${containername}"
fi
# return all containers
elif [ "all" == "${containerresponse[$i]}" ] || [ "*" == "${containerresponse[$i]}" ]; then
containername="${containerids[@]}"
#echo "${containername}"
# validate the provided value
else
containermatches=$(docker ps $INCLUDE_STOPPED | grep -v '^CONTAINER' | awk '{print $NF}' | grep "${containerresponse[$i]}")
if [[ -n "$containermatches" ]]; then
foundmatching=1
containername=$(echo -e "${containermatches}\n$containername")
#echo "${containername}"
else
dockererror "Unknown container name ${containerresponse[$i]}. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1;
fi
#for i in "${!containerids[@]}"
#do
# if [[ "$containername" == "${containerids[$i]}" ]]; then
# foundmatch=1
# containername="${containerids[$i]}"
# break
# fi
#done
#if [ -z "$foundmatch" ]; then
# dockererror "Unknown container name. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1;
#fi
fi
done
# print results | strip duplicates | reverse and delete empty newlines | replace spaces with newlines
echo "${containername}" | awk '!a[$0]++' | sed -ne '1!G;h;$p' | tr " " "\n"
fi
#echo "$containername"
}
# validates a user-supplied image name and/or version based on partial match. If none is supplied
# the user is prompted to select from a list of images on the current system
function dimagelike() {
imagenames=( $(docker images | grep -v '^<none>' | awk '{print $1,":",$2; }' | sed -e 's# ##g') )
if [[ -z "$1" ]]; then
for i in "${!imagenames[@]}"
do
echo "[$i] ${imagenames[$i]}"
done
echo -n "Select imag(e) []: "
eval "read selectedimage"
else
selectedimage="$1"
fi
re='^[0-9]+$'
# if empty, none was provided and none was selected
if [[ -z "$selectedimage" ]]; then
dockererror "Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1;
# validate the numeric selection
elif [[ "$selectedimage" =~ $re ]] ; then
if [ $selectedimage -ge ${#imagenames[@]} ]; then
dockererror "Invalid choice. Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1;
else
echo "${imagenames[$selectedimage]}"
fi
# return all containers
elif [ "all" == "$selectedimage" ] || [ "*" == "$selectedimage" ]; then
echo "${imagenames[@]}"
# validate the provided value
else
# selectedimage=( "${selectedimage[@]}" )
# for j in "${#selectedimage[@]}"
# do
# match the selected value against the existing image name and tag
imgmatches=$(docker images | grep -v '^<none>' | awk '{print $1,":",$2; }' | sed -e 's# ##g' | grep "$selectedimage")
if [[ -n "$imgmatches" ]]; then
foundmatching=1
echo "${imgmatches}"
fi
# done
if [[ -z "$foundmatching" ]]; then
dockererror "Invalid image value. Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1;
fi
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment