Ghid Complet de Stocare și Backup în Docker: Volume Gestionate, Backup Automatizat de Baze de Date și Migrare între Servere în Docker

Volume și rețele Standard Producție

Ghid de bune practici pentru persistența datelor în Docker: gestionarea volumelor de producție, scripturi de backup automat prin containere efemere, restaurarea consecventă a bazelor de date și migrarea volumelor între servere.

Sintaxă comandă
docker run --rm -v volum_db:/source:ro -v $(pwd):/backup alpine tar czf /backup/db.tar.gz -C /source .

Unul dintre principiile de bază ale arhitecturii cloud native este că containerele sunt efemere: pot fi oprite, distruse și recreate oricând fără nicio pierdere de informație. Pentru aplicațiile cu stare (Stateful), precum bazele de date PostgreSQL, MySQL, Redis sau depozitele de fișiere media, datele trebuie stocate exclusiv în Named Volumes. Gestionarea corectă, backup-ul periodic consecvent și procedurile clare de restaurare (Disaster Recovery) sunt coloana vertebrală a oricărui sistem de producție.

1. De ce Named Volumes și NU Bind Mounts în Producție?

  • Performanță I/O nativă: Volumele gestionate de Docker sunt plasate în /var/lib/docker/volumes/, beneficiind de viteza maximă a sistemului de fișiere al gazdei fără overhead de sincronizare.
  • Izolarea permisiunilor: Bind mount-urile expun structura internă a directorilor de pe gazdă și provoacă conflicte frecvente de UID/GID între sistemul de operare și utilizatorul din container.
  • Portabilitate: Un volum gestionat poate fi mutat cu ușurință pe drivere de stocare în rețea (NFS, AWS EBS, Ceph) fără a schimba definiția serviciului în compose.yaml.

2. Tehnica Containerului Efemer pentru Backup de Volum

Cel mai elegant și sigur mod de a arhiva un volum Docker fără a instala utilitare suplimentare pe serverul gazdă este pornirea unui mic container Alpine Linux efemer (cu parametrul --rm), care montează volumul ca Read-Only și creează o arhivă comprimată:

Comandă unică de arhivare a unui volum de producție
# Creăm o arhivă tar.gz a volumului 'postgres_db_data' în folderul curent /backups:
docker run --rm \
  -v postgres_db_data:/volume-sursa:ro \
  -v /backups:/backup-destinatie \
  alpine \
  tar -czf /backup-destinatie/backup_postgres_$(date +%Y%m%d_%H%M%S).tar.gz -C /volume-sursa .

3. Restaurarea Datelor pe un Server Nou (Disaster Recovery)

Dacă serverul de producție s-a defectat sau migrați pe un hardware mai puternic, iată pașii exacți pentru reconstrucția volumului din arhiva de backup:

Procedura de restaurare completă a volumului
# 1. Creăm un volum Docker nou pe noul server:
docker volume create postgres_db_data

# 2. Dezarhivăm conținutul salvat direct în noul volum folosind același container efemer:
docker run --rm \
  -v postgres_db_data:/volume-destinatie \
  -v /backups:/backup-sursa:ro \
  alpine \
  sh -c "cd /volume-destinatie && tar -xzf /backup-sursa/backup_postgres_20261024.tar.gz"

# 3. Pornim baza de date pe noul server:
docker compose up -d postgres-db

4. Backup Logic Consecvent pentru Baze de Date Active

Pentru baze de date tranzacționale de mare intensitate (PostgreSQL / MySQL), copierea fișierelor brute în timp ce baza de date rulează poate genera coruperi de date (scriere parțială a paginilor de memorie). Metoda recomandată în producție este un dump logic executat direct prin container:

Script automat de backup logic pentru PostgreSQL (de adăugat în crontab)
#!/bin/bash
BACKUP_DIR="/var/backups/postgres"
mkdir -p "$BACKUP_DIR"
DATE=$(date +%Y%m%d_%H%M%S)

# Executăm pg_dumpall din interiorul containerului activ și comprimăm cu zstd / gzip:
docker exec -t postgres-db pg_dumpall -U dbuser | gzip > "$BACKUP_DIR/pg_dump_$DATE.sql.gz"

# Păstrăm doar backup-urile din ultimele 14 zile (ștergere automată a celor vechi):
find "$BACKUP_DIR" -type f -name "*.sql.gz" -mtime +14 -delete

echo "Backup PostgreSQL finalizat cu succes la $DATE"

5. Verificarea Integrității și Spațiului pe Disc

# Verificăm spațiul total ocupat de toate volumele Docker pe disc:
docker system df -v

# Identificăm volumele orfane (rămase nefolosite după ștergerea containerelor):
docker volume ls -f dangling=true

# Curățăm volumele orfane fără a afecta datele active:
docker volume prune -f