# 1. Backup named volume folosind un container efemer
docker run --rm \
-v db_data:/source:ro \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/db_data_$(date +%Y%m%d_%H%M%S).tar.gz -C /source .
# 2. Restore într-un volum complet NOU (pentru siguranță)
docker volume create db_data_restored
docker run --rm \
-v db_data_restored:/target \
-v $(pwd)/backups:/backup \
alpine sh -c "cd /target && tar xzf /backup/db_data_20240101_120000.tar.gz"Am văzut de prea multe ori setup-uri de Docker în care o bază de date de producție stătea pe un amărât de bind mount (./data:/var/lib/postgresql/data). Pare comod când dezvolți local pe Mac sau Windows, dar când ajungi pe un server Linux începe distracția cu permisiunile și performanța I/O.
După ce am pierdut câteva ore bune recuperând un Postgres corupt la un client cu vreo 60GB de date, am zis că merită clarificată diferența dintre named volumes și bind mounts, plus fluxul corect de backup/restore.
De ce bind mounts sunt o capcană pentru date persistente
Bind mount-ul leagă un director specific de pe host direct în container. Pe Linux, dacă Docker rulează containerul cu userul postgres (de regulă UID 999), iar folderul tău de pe host e deținut de root (UID 0), containerul crapă instant cu permission denied.
Pe macOS și Windows treaba e și mai rea: Docker Desktop folosește un layer de virtualizare (gRPC-FUSE sau VirtioFS) care adaugă un overhead masiv pe operațiile de I/O ale bazei. La un test simplu cu sysbench, am obținut un throughput cu 40% mai mic pe bind mount față de un named volume.
Named volumes (docker volume create db_data) sunt gestionate exclusiv de daemon-ul Docker (stocate în /var/lib/docker/volumes/ pe Linux). Docker setează automat permisiunile corecte când populează volumul la prima pornire și folosește direct filesystem-ul nativ, fără intermediari.
Trade-off-ul? E mai greu să „arunci o privire” direct în fișiere din terminalul tău de zi cu zi, dar tocmai de-aia sunt mai sigure.
Cum faci backup curat dintr-un named volume
Cea mai simplă și portabilă metodă de a face backup la un named volume nu e să copiezi direct din /var/lib/docker (unde ai nevoie de root și riști date parțiale dacă DB-ul scrie activ). Folosim un container temporar care montează volumul.
Atenție la un detaliu critic: dacă baza este masivă și are trafic constant, un simplu tar pe fișierele de date poate prinde o stare inconsistentă (un snapshot „corupt”). Pentru fiabilitate 100%, ai două opțiuni:
- Oprești containerul bazei 30 de secunde dacă îți permiți acel scurt downtime.
- Faci dump logic (
pg_dumpsaumysqldump) rulat direct printr-un container efemer conectat la aceeași rețea Docker.
Pentru baze sub 10-15GB, un pg_dump scos direct printr-o comandă docker exec sau un container one-off de backup e sfânt.
Restore testat (partea pe care 90% din dev o sar)
Un backup pe care nu l-ai testat vreodată cu un restore nu există. E doar o iluzie liniștitoare.
Când restaurezi dintr-o arhivă tar într-un named volume nou, regula de aur este să nu restaurezi niciodată peste un volum existent care are baza pornită. Creezi un volum proaspăt, populezi fișierele cu un container temporar, apoi pornești serviciul legat la noul volum. Dacă ceva nu merge, volumul vechi e încă intact și nu ai creat downtime suplimentar.
Voi cum gestionați backup-urile automate pentru containerele de DB pe instanțe mici unde nu aveți RDS/managed databases? Vă bazați pe cronjob-uri cu dump logic sau snapshot-uri la nivel de volum?