Created
June 30, 2026 15:27
-
-
Save cb1kenobi/43d6607180a1f90ca8ec36ececb3d903 to your computer and use it in GitHub Desktop.
Check whether live Docker container volumes exist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # check-container-volumes.sh | |
| # | |
| # Iterates over all running Docker containers and, for each mount/volume, | |
| # reports whether the associated directory on the host exists. | |
| # | |
| # Notes: | |
| # - Must be run ON the Docker host (paths are checked on the local | |
| # filesystem). For named volumes the source lives under | |
| # /var/lib/docker/volumes/<name>/_data, which usually requires root, | |
| # so you may need to run this with sudo. | |
| # - Exits non-zero if any expected source path is missing. | |
| # | |
| set -uo pipefail | |
| # Make sure docker is available. | |
| if ! command -v docker >/dev/null 2>&1; then | |
| echo "Error: docker command not found." >&2 | |
| exit 1 | |
| fi | |
| # Field separator for parsing inspect output. We use ASCII Unit Separator | |
| # (0x1F) instead of a tab: tab is IFS-whitespace, so `read` would collapse | |
| # the empty .Name field of bind mounts and shift every column over by one. | |
| sep=$'\x1f' | |
| # Collect running container IDs (container IDs contain no whitespace, | |
| # so word-splitting the output here is safe). | |
| containers=$(docker ps -q) | |
| if [ -z "$containers" ]; then | |
| echo "No running containers found." | |
| exit 0 | |
| fi | |
| exit_code=0 | |
| for cid in $containers; do | |
| name=$(docker inspect --format '{{.Name}}' "$cid" | sed 's#^/##') | |
| echo "=== Container: $name ($cid) ===" | |
| # One line per mount, fields separated by 0x1F: | |
| # TYPE <sep> NAME <sep> SOURCE <sep> DESTINATION | |
| fmt="{{range .Mounts}}{{.Type}}${sep}{{.Name}}${sep}{{.Source}}${sep}{{.Destination}}{{\"\\n\"}}{{end}}" | |
| mounts=$(docker inspect --format "$fmt" "$cid") | |
| if [ -z "$mounts" ]; then | |
| echo " (no volumes or bind mounts)" | |
| echo | |
| continue | |
| fi | |
| while IFS="$sep" read -r type vol_name source destination; do | |
| [ -z "$type" ] && continue | |
| # Build a readable label, e.g. "volume:mydata" or "bind". | |
| label="$type" | |
| [ -n "$vol_name" ] && label="$type:$vol_name" | |
| if [ -z "$source" ]; then | |
| # tmpfs and similar have no host source path. | |
| echo " [$label] -> $destination : no host source path" | |
| elif [ -d "$source" ]; then | |
| echo " [$label] DIR EXISTS $source -> $destination" | |
| elif [ -e "$source" ]; then | |
| # Bind mount of a single file rather than a directory. | |
| echo " [$label] EXISTS (not a dir) $source -> $destination" | |
| else | |
| echo " [$label] MISSING $source -> $destination" | |
| exit_code=1 | |
| fi | |
| done <<< "$mounts" | |
| echo | |
| done | |
| exit "$exit_code" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment