in Devops, Informatica

Migrare un container Docker e i suoi volumi

Quando si lavora con Docker, si presenta prima o poi la necessità di spostare un ambiente di lavoro da una macchina all’altra. Che si tratti del passaggio a un nuovo PC sviluppatore, della migrazione verso un server di staging o semplicemente di un backup completo, trasferire un container insieme ai suoi dati persistenti può sollevare qualche dubbio.

Un errore comune è pensare che basti “spostare il container”. In realtà, la filosofia di Docker separa nettamene il processo/ambiente (l’immagine e il container) dai dati persistenti (i volumi).

In questo articolo vedremo la procedura passo-passo per esportare correttamente sia l’immagine/container che i volumi associati dal PC di origine e ripristinarli sul PC di destinazione.

Concetti chiave prima di iniziare

Prima di eseguire qualsiasi comando, chiariamo due distinzioni fondamentali:

  1. docker save vs docker export:
    • docker save: Salva un’immagine Docker completa con tutta la sua cronologia dei layer e i metadati. È la scelta raccomandata per mantenere intatta la configurazione dell’ambiente.
    • docker export: Esporta il filesystem di un container specifico ad un istante $t$, appiattendo i layer. È utile se hai fatto modifiche “al volo” dentro il container senza aggiornare il Dockerfile, ma perde la cronologia dei layer.
  2. I Volumi Docker (named volumes):I volumi risiedono in una directory gestita direttamente dal daemon Docker (es. /var/lib/docker/volumes/ su Linux). Non basta copiare il file dell’immagine per portarsi dietro i dati del database o i file caricati: i volumi vanno esportati separatamente.

Fase 1: Esportazione dall’origine

Supponiamo di avere un container chiamato mio_app_container che utilizza un volume chiamato mio_app_data.

Passo 1: Stoppare il container

Per garantire la consistenza dei dati ed evitare che vengano scritti file mentre creiamo l’archivio, arrestiamo il container:

docker stop mio_app_container

Passo 2: Creare una nuova immagine dalle modifiche (Opzionale)

Se il container è stato modificato rispetto all’immagine originale di partenza, crea un commit per salvare lo stato corrente come nuova immagine:

docker commit mio_app_container mia_immagine_custom:latest

Passo 3: Esportare l’immagine Docker

Ora salviamo l’immagine in un file archivio .tar:

docker save -o mia_immagine.tar mia_immagine_custom:latest

(Nota: Se hai usato l’immagine ufficiale senza modifiche interne al file system, puoi anche usare il nome dell’immagine di partenza, es. docker save -o mia_immagine.tar nginx:latest).

Passo 4: Esportare il Volume dati

Il modo più pulito ed elegante per esportare un volume gestito da Docker (senza dover cercare i percorsi interni del sistema operativo) è usare un container temporaneo leggero (come ubuntu o alpine) per comprimere il volume in un archivio .tar.gz:

docker run --rm \
  -v mio_app_data:/volume_data \
  -v $(pwd):/backup \
  ubuntu tar cvzf /backup/mio_volume_backup.tar.gz -C /volume_data .

Cosa fa questo comando?

  • --rm: Elimina il container temporaneo al termine dell’operazione.
  • -v mio_app_data:/volume_data: Monta il tuo volume Docker all’interno del container temporaneo nella cartella /volume_data.
  • -v $(pwd):/backup: Monta la tua directory corrente del PC host nella cartella /backup del container.
  • tar cvzf ...: Comprime tutto il contenuto di /volume_data nel file mio_volume_backup.tar.gz salvandolo nella tua cartella corrente.

A questo punto avrai due file nella tua cartella:

  • mia_immagine.tar
  • mio_volume_backup.tar.gz

Fase 2: Trasferimento dei file

Trasferisci i due file creati (mia_immagine.tar e mio_volume_backup.tar.gz) sul nuovo PC.

Puoi farlo tramite pendrive USB, scp, rsync o qualsiasi servizio di cloud/network storage:

Bash

# Esempio via SCP verso il nuovo PC/Server
scp mia_immagine.tar mio_volume_backup.tar.gz utente@nuovo-pc:/home/utente/

Fase 3: Importazione

Spostati sul nuovo PC nella cartella in cui hai posizionato i due file .tar.

Passo 1: Caricare l’immagine Docker

Ripristiniamo l’immagine Docker nel daemon locale:

docker load -i mia_immagine.tar

Verifica che l’immagine sia presente con il comando docker images.

Passo 2: Ricreare il Volume ed estrarre i dati

Creiamo il nuovo volume vuoto su Docker:

docker volume create mio_app_data

Ora popoliamo il volume appena creato estraendo il contenuto dall’archivio .tar.gz usando nuovamente un container temporaneo:

docker run --rm \
  -v mio_app_data:/volume_data \
  -v $(pwd):/backup \
  ubuntu tar xvzf /backup/mio_volume_backup.tar.gz -C /volume_data

Passo 3: Avviare il nuovo container

Ora che sia l’immagine che i dati del volume sono presenti sulla nuova macchina, possiamo lanciare il container collegando il volume ripristinato:

docker run -d \
  --name mio_app_container \
  -p 8080:80 \
  -v mio_app_data:/path/nel/container \
  mia_immagine_custom:latest

(Sostituisci /path/nel/container con il percorso effettivo in cui l’applicazione si aspetta di trovare i dati, ad esempio /var/lib/mysql per MySQL o /usr/share/nginx/html per un webserver).

Alternativa rapida: E se usi Docker Compose?

Se utilizzi Docker Compose, il processo è ancora più snello:

  1. Non serve esportare le immagini standard: sul nuovo PC ti basterà ricopiare il file docker-compose.yml.
  2. Esporta soltanto il volume seguendo il Passo 4 della Fase 1.
  3. Sul nuovo PC crea il volume ed estrai i dati (Fase 3 – Passo 2).
  4. Avvia tutto con il classico comando:Bashdocker compose up -d

Checklist riassuntiva

Da ricordare:

  1. Stop al container → docker stop
  2. Salvataggio immagine → docker save
  3. Backup del volume → docker run ... tar cvzf
  4. Trasferimento file sui due PC
  5. Ripristino immagine → docker load
  6. Creazione volume + Estrazione dati → docker volume create + docker run ... tar xvzf
  7. Avvio container → docker run / docker compose up