You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
3.4 KiB
Markdown
73 lines
3.4 KiB
Markdown
---
|
|
draft: false
|
|
title: "How to find that one volume you're pretty sure you didn't lose"
|
|
date: "2024-06-25"
|
|
series: []
|
|
author: "Nick Dumas"
|
|
cover: ""
|
|
tags: ["bash", "docker"]
|
|
summary: "Docker volumes can be opaque, so I wrote a small bash script to help you troubleshoot."
|
|
showFullContent: false
|
|
---
|
|
|
|
## What I expect you to know
|
|
This article is only relevant if you know about and use Docker volumes and have some fluency in bash. I'll explain the code as I go, if it helps.
|
|
|
|
## The Problem
|
|
Over the lifetime of a Docker host machine, it's likely that orphaned volumes and other detritus will accumulate over time. You might find yourself fumbling a configuration and orphaning a volume yourself. However we got here, we have a bunch of volumes and we need to know if any of them are important. In a perfect world, they'll have decent names.
|
|
|
|
We don't live in a perfect world.
|
|
## Make a list
|
|
Luckily, we have tools at our disposal to handle this. My thought process almost always starts with "Can I make a newline separated list of the things I care about?" If I can do that, I can start automating my troubleshooting.
|
|
|
|
Let's start with `docker volume ls`. This is how we list volumes, but the default output isn't quite what I'm looking for:
|
|
```
|
|
docker volume ls
|
|
DRIVER VOLUME NAME
|
|
local d35fce052fbce42b94b2f9b2957be0f77090fa006b1a192030eff07db3675af2
|
|
local grafana-storage
|
|
local plausible_db-data
|
|
local plausible_event-data
|
|
```
|
|
This is human readable, and we could even do some slicing with `cut` or `awk`, but Docker gives us a flag that will take us exactly where we need to go: `--format`. Docker uses Go's `text/template` library to power this feature and individual flags (usually) [document](https://docs.docker.com/reference/cli/docker/volume/ls/#format) the template verbs available. Here, we want `Name`.
|
|
```
|
|
docker volume ls --format "{{.Name}}"
|
|
d35fce052fbce42b94b2f9b2957be0f77090fa006b1a192030eff07db3675af2
|
|
grafana-storage
|
|
plausible_db-data
|
|
plausible_event-data
|
|
```
|
|
|
|
We now have a newline separated list of volume names.
|
|
## Process of elimination
|
|
The next part is fairly straightforward. We loop over this list and ask Docker to create a temporary container based on alpine, with a single volume mounted at `/test/`.
|
|
```
|
|
#! /bin/bash
|
|
|
|
# Newline separated list of volume names
|
|
volumes=$(docker volume ls --format="{{.Name}}")
|
|
for volume in $volumes; do
|
|
# Help the user keep track of which volume they're exploring
|
|
echo "Mounting $volume in a temporary image."
|
|
docker run --rm -v $volume:/test/ -it alpine /bin/sh
|
|
done
|
|
```
|
|
Running this script should do something like this:
|
|
```
|
|
./cycle-volumes.sh
|
|
Mounting d35fce052fbce42b94b2f9b2957be0f77090fa006b1a192030eff07db3675af2 in a temporary image.
|
|
/ # ls /test/
|
|
clickhouse-server.err.log clickhouse-server.log.1.gz clickhouse-server.log.4.gz clickhouse-server.log.7.gz
|
|
clickhouse-server.log clickhouse-server.log.2.gz clickhouse-server.log.5.gz clickhouse-server.log.8.gz
|
|
clickhouse-server.log.0.gz clickhouse-server.log.3.gz clickhouse-server.log.6.gz
|
|
/ #
|
|
Mounting grafana-storage in a temporary image.
|
|
/ # ls /test
|
|
alerting csv file-collections grafana.db plugins png
|
|
/ # exit
|
|
Mounting plausible_db-data in a temporary image.
|
|
/ # exit
|
|
Mounting plausible_event-data in a temporary image.
|
|
/ # exit
|
|
```
|
|
You can use bash to explore the volume and identify its contents, make note of which ones are which, and proceed accordingly. |