Skip to main content

Docker and Kubernetes Integration

Docker Functions

Container Inspector

# Full container inspector: exec, logs, stats, stop
fdocker() {
local container key

local out
out=$(docker ps --format \
"table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" | fzf \
--header-lines=1 \
--ansi \
--preview 'docker stats --no-stream $(echo {} | awk "{print \$1}") 2>/dev/null | tail -2' \
--preview-window 'down:3' \
--expect=ctrl-l,ctrl-s,ctrl-t,ctrl-d \
--prompt '🐳 Docker> ' \
--header $'Enter: exec bash\nCtrl+L: logs Ctrl+S: stats Ctrl+T: stop Ctrl+D: rm')

key=$(head -1 <<< "$out")
container=$(tail -1 <<< "$out" | awk '{print $1}')
[[ -z "$container" ]] && return

case "$key" in
ctrl-l) docker logs -f --tail=100 "$container" ;;
ctrl-s) docker stats "$container" ;;
ctrl-t) docker stop "$container" && echo "Stopped: $container" ;;
ctrl-d) docker rm -f "$container" && echo "Removed: $container" ;;
*)
local shell
shell=$(echo -e "bash\nsh\nzsh\nfish" | fzf --prompt "Shell> " --height=6)
[[ -n "$shell" ]] && docker exec -it "$container" "$shell"
;;
esac
}

Image Manager

fdimage() {
local image key

local out
out=$(docker images --format \
"table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}" | fzf \
--header-lines=1 \
--preview 'docker inspect $(echo {} | awk "{print \$1\":\"\$2}") | jq ".[0].Config"' \
--preview-window 'right:50%' \
--expect=ctrl-d,ctrl-p,ctrl-r \
--prompt '🖼 Image> ' \
--header $'Enter: inspect Ctrl+D: remove Ctrl+P: pull Ctrl+R: run')

key=$(head -1 <<< "$out")
image=$(tail -1 <<< "$out" | awk '{print $1":"$2}')
[[ -z "$image" || "$image" == ":" ]] && return

case "$key" in
ctrl-d) docker rmi "$image" ;;
ctrl-p) docker pull "$image" ;;
ctrl-r)
read -rp "docker run args (flags): " args
docker run -it $args "$image"
;;
*)
docker inspect "$image" | jq '.[0] | {Name:.RepoTags,Cmd:.Config.Cmd,Env:.Config.Env,Ports:.Config.ExposedPorts}'
;;
esac
}

docker-compose Manager

fdcompose() {
local service

# Find all compose files in common locations
local compose_file
compose_file=$(find . /opt /srv -name "docker-compose*.yml" -o -name "compose.yml" 2>/dev/null | fzf \
--prompt '📄 Compose File> ' \
--preview 'cat {}')
[[ -z "$compose_file" ]] && return

local dir
dir=$(dirname "$compose_file")

service=$(docker compose -f "$compose_file" config --services | fzf \
--prompt "Service ($dir)> " \
--preview "docker compose -f $compose_file logs --tail=20 {} 2>/dev/null" \
--preview-window 'down:10' \
--expect=ctrl-l,ctrl-r,ctrl-s,ctrl-d \
--header $'Enter: exec Ctrl+L: logs Ctrl+R: restart Ctrl+S: stop Ctrl+D: down')

local key
key=$(head -1 <<< "$service")
service=$(tail -1 <<< "$service")
[[ -z "$service" ]] && return

case "$key" in
ctrl-l) docker compose -f "$compose_file" logs -f "$service" ;;
ctrl-r) docker compose -f "$compose_file" restart "$service" ;;
ctrl-s) docker compose -f "$compose_file" stop "$service" ;;
ctrl-d) docker compose -f "$compose_file" down ;;
*) docker compose -f "$compose_file" exec "$service" sh || \
docker compose -f "$compose_file" exec "$service" bash ;;
esac
}

Kubernetes Functions

Pod Manager

fkube() {
local ns pod key

# Pick namespace
ns=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}' \
| tr ' ' '\n' | sort | fzf \
--prompt '🔲 Namespace> ' \
--height=40% \
--preview 'kubectl get pods -n {} --no-headers 2>/dev/null | head -20')
[[ -z "$ns" ]] && return

# Pick pod
local out
out=$(kubectl get pods -n "$ns" \
| fzf \
--header-lines=1 \
--preview "kubectl describe pod -n $ns {1} 2>/dev/null | head -40" \
--preview-window 'right:50%' \
--expect=ctrl-l,ctrl-d,ctrl-e \
--prompt "🐳 Pod ($ns)> " \
--header $'Enter: exec Ctrl+L: logs Ctrl+D: describe Ctrl+E: events')

key=$(head -1 <<< "$out")
pod=$(tail -1 <<< "$out" | awk '{print $1}')
[[ -z "$pod" ]] && return

case "$key" in
ctrl-l)
local container
container=$(kubectl get pod "$pod" -n "$ns" \
-o jsonpath='{.spec.containers[*].name}' | tr ' ' '\n' | fzf --prompt "Container> " --height=6)
kubectl logs -f -n "$ns" "$pod" ${container:+-c "$container"} --tail=100
;;
ctrl-d) kubectl describe pod -n "$ns" "$pod" | less ;;
ctrl-e) kubectl get events -n "$ns" --field-selector "involvedObject.name=$pod" ;;
*)
kubectl exec -it -n "$ns" "$pod" -- bash 2>/dev/null || \
kubectl exec -it -n "$ns" "$pod" -- sh
;;
esac
}

Kubernetes Context Switcher

fkctx() {
local context
context=$(kubectl config get-contexts -o name | fzf \
--prompt '⚙ kubectl Context> ' \
--preview 'kubectl config get-contexts {}' \
--preview-window 'down:4')
[[ -n "$context" ]] && kubectl config use-context "$context"
}

Kubernetes Resource Viewer

fkget() {
local resource
resource=$(kubectl api-resources --verbs=list --namespaced -o name | fzf \
--prompt '📋 Resource Type> ' \
--height=40%)
[[ -z "$resource" ]] && return

kubectl get "$resource" --all-namespaces | fzf \
--header-lines=1 \
--preview "kubectl describe $resource -n {1} {2} 2>/dev/null | head -50" \
--preview-window 'right:50%' \
--prompt "$resource> "
}

What's Next