# 1. Backup direct din containerul de producție (streamed & compressed)
docker exec -t postgres-db pg_dump -U postgres -d my_app_db | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
# 2. Ridicăm un container temporar izolat pentru testul de restore
docker run --name pg-test -e POSTGRES_PASSWORD=secret -d postgres:15-alpine
# Așteptăm câteva secunde să se inițializeze baza
sleep 5
# 3. Restaurăm datele din arhivă în containerul nou
gunzip -c backup_20231024_100000.sql.gz | docker exec -i pg-test psql -U postgres -d my_app_db
# 4. Verificăm integritatea datelor
docker exec -it pg-test psql -U postgres -d my_app_db -c "SELECT COUNT(*) FROM users;"Salutare. Am văzut săptămâna trecută un caz la un client unde un dev mai puțin experimentat a pus baza de date Postgres din producție pe un bind mount direct pe serverul de Linux. Toate bune, până când s-a schimbat UID-ul userului din container la un update de imagine și s-au tăiat permisiunile de write. Baza a picat în cap în mijlocul zilei.
Am strâns destulă frustrare pe subiectul ăsta în ultimii ani, așa că zic să clarificăm cum gestionăm datele perisabile în Docker și cum facem un backup de pe care chiar putem restabili ceva.
Named Volumes vs Bind Mounts: Când și de ce?
Regula mea simplă, testată pe zeci de proiecte: bind mount-ul e strict pentru dezvoltare locală, iar named volume-ul e pentru date de producție.
La bind mount (-v /var/mydata:/app/data), tu mapezi un folder direct din OS-ul gazdă. În dev e superb pentru că modifici codul în VS Code și se vede instant în container. În schimb, pe producție apar rapid trei probleme mari: permisiunile de fișiere (mai ales la trecerea între Linux și macOS), performanța scăzută de I/O și dependența de structura de directoare a host-ului.
Named volumes (-v pgdata:/var/lib/postgresql/data) sunt izolate și gestionate direct de Docker Engine. Performanța e maximă, n-ai treabă cu userii din host, iar Docker știe exact unde și cum să le stocheze. Singurul minus e că nu le vezi direct în File Explorer, dar sincer, nici nu ar trebui să umbli manual acolo.
Cum faci backup la o bază de date în Docker?
Cea mai mare greșeală pe care o văd este încercarea de a face backup prin copierea fișierelor brute din named volume în timp ce baza de date rulează. Dacă faci cp sau rsync pe /var/lib/docker/volumes/... când Engine-ul scrie în WAL (Write-Ahead Logging), te alegi cu o bază coruptă. În 90% din cazuri, restore-ul va eșua.
Backup-ul corect se face la nivel de aplicație (logical dump), rulând utilitarul nativ al bazei direct prin container sau folosind un container temporar legat la rețea.
Pentru Postgres, la un proiect cu vreo 12k utilizatori activi, noi folosim o abordare extrem de simplă prin pg_dump extras direct prin streaming. Durează câteva secunde pentru baze mici și câteva minute la cele de zeci de gigabiți, garantând consistența datelor.
Testează restore-ul! Dacă nu ai testat restore, nu ai backup
Am o regulă de aur: un backup netestat este un simplu fișier de prisos pe disc. Cel puțin o dată pe lună, un script automatizează la noi un restore pe un mediu de staging izolat.
Vezi mai jos pașii minimali pentru un backup comprimat și restabilirea lui într-un container curat de test.
Procesul e simplu: faci dump-ul gzipat direct din containerul de prod, creezi un container de test curat cu un volume nou și injectezi dump-ul. Dacă noul container pornește și trece un query de verificare (SELECT COUNT(*)), știi sigur că backup-ul tău e valid.
Voi cum gestionați backup-urile de baze de date în Docker pe proiectele voastre? Mergeți pe dump-uri clasice trimise în S3 sau folosiți soluții de snapshot la nivel de volum în cloud?