Skip to content

KB Flooris Hosting - Docker migrate all volumes

Docker heeft niet standaard de mogelijkheid om alle volumes te exporteren en importeren, wat handig kan zijn als je bijvoorbeeld je ontwikkelomgeving wil migreren naar een nieuwe machine.

In deze knowledge base zijn 2 scripts die je kan gebruiken om de migratie te doen. Deze scripts kunnen ook gebruikt worden om een backup te maken van je volumes.

Niet production ready

Let op dat dit script niet per-se bedoeld is voor productieomgevingen.

Grote kans dat het wel gewoon werkt, het is alleen niet getest of gecontroleerd op robuustheid en data integriteit.

Dit script houdt ook rekening met de Docker volume labels van Docker Compose, je zal hierna dus ook geen waarschuwingen moeten krijgen over dat een volume extern is gecreëerd wanneer je een Docker Compose project start.

Export script

Dit script zal al je Docker volumes exporteren naar /tmp/docker_volumes_backup.

Stop alle containers

Om ervoor te zorgen dat de export successvol verloopt, moeten alle containers gestopt zijn.

Als bijvoorbeeld nog een database container draait en we maken hiervan een export van de volume, is hoogstwaarschijnlijk de database in de export corrupt!

#!/bin/bash

# Create backup directory
BACKUP_DIR="/tmp/docker_volumes_backup"
mkdir -p "$BACKUP_DIR"

echo "Starting volume export..."

# Get list of all volume names
VOLUMES=$(docker volume ls -q)

for VOLUME in $VOLUMES; do
    echo "Exporting $VOLUME..."
    # Run a temporary container to tar the volume content
    docker run --rm \
        -v "$VOLUME":/volume_data \
        -v "$(pwd)/$BACKUP_DIR":/backup \
        alpine \
        tar -czf /backup/"$VOLUME".tar.gz -C /volume_data .
done

echo "Export complete. Files are in $BACKUP_DIR"

Import script

Dit script zal al je Docker volumes importeren vanuit /tmp/docker_volumes_backup.

Niet production ready

Dit script zal je volume overschrijven indien deze al bestaat.

Als je niet wil dat een bepaalde volume wordt overschreven, haal dan dit bestand uit de /tmp/docker_volumes_backup map!

#!/bin/bash

# Directory containing your .tar.gz files
BACKUP_DIR="/tmp/docker_volumes_backup"

# --- SAFETY WARNING ---
echo "=========================================================="
echo "This script will PERMANENTLY DELETE and RECREATE any existing"
echo "Docker volumes that match the filenames in $BACKUP_DIR."
echo "All current data in those volumes will be LOST."
echo "=========================================================="
read -p "Are you sure you want to proceed? (type 'yes' to continue): " CONFIRM

if [ "$CONFIRM" != "yes" ]; then
    echo "Import aborted. No changes were made."
    exit 1
fi
# ----------------------

if [ ! -d "$BACKUP_DIR" ]; then
    echo "❌ Error: $BACKUP_DIR does not exist."
    exit 1
fi

echo "🚀 Starting smart volume import..."

for BACKUP_FILE in "$BACKUP_DIR"/*.tar.gz; do
    # 1. Get the full volume name (e.g., project_db)
    FULL_NAME=$(basename "$BACKUP_FILE" .tar.gz)

    # 2. Extract Project and Volume names for labels
    # This splits by the first underscore
    PROJECT_NAME=$(echo "$FULL_NAME" | cut -d'_' -f1)
    COMPOSE_VOL_NAME=$(echo "$FULL_NAME" | cut -d'_' -f2-)

    echo "------------------------------------------------"

    # 3. Check if volume exists and remove it
    if docker volume inspect "$FULL_NAME" > /dev/null 2>&1; then
        echo "♻️  Existing volume found: $FULL_NAME. Removing..."
        docker volume rm "$FULL_NAME" > /dev/null 2>&1

        if [ $? -ne 0 ]; then
            echo "❌ Error: Could not remove $FULL_NAME. Ensure no containers are using it."
            echo "   Try running 'docker compose down' first."
            continue
        fi
    fi

    # 4. Create the volume WITH labels
    echo "🏗️  Creating labeled volume: $FULL_NAME"
    docker volume create "$FULL_NAME" \
        --label "com.docker.compose.project=$PROJECT_NAME" \
        --label "com.docker.compose.volume=$COMPOSE_VOL_NAME" > /dev/null

    # 5. Extract the data
    echo "📥 Restoring data from archive..."
    docker run --rm \
        -v "$FULL_NAME":/volume_data \
        -v "$(pwd)/$BACKUP_DIR":/backup \
        alpine \
        tar -xzf /backup/"$FULL_NAME".tar.gz -C /volume_data

    echo "✅ Success: $FULL_NAME"
done

echo "------------------------------------------------"
echo "Import complete."