version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: dev_user
POSTGRES_PASSWORD: dev_password
POSTGRES_DB: dev_db
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dev_user -d dev_db"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redisdata:/data
volumes:
pgdata:
redisdata:Să fim sinceri, scuza cu „la mine pe mașină funcționează” ar fi trebuit să dispară odată cu anii 2010. Totuși, încă văd proiecte unde setup-ul local e un coșmar de scripturi bash, versiuni de Node incompatibile și baze de date instalate direct pe sistemul de operare. Am pățit-o acum vreo 6 ani, când un update minor de macOS mi-a bușit Postgres-ul local fix înainte de un demo important cu un client.
De atunci, regula mea e simplă: orice proiect nou primește din prima zi un fișier docker-compose.yml bine pus la punct. Fie că e un monolit masiv sau un simplu app Next.js cu Redis pentru caching și Postgres pentru date, Docker Compose îți salvează sănătatea mintală.
De ce merită efortul (și cifrele din spate)
La un proiect trecut, unde aveam o echipă de 8 developeri, onboarding-ul unui om nou dura cam o zi întreagă. Ba nu avea versiunea corectă de Node, ba Redis-ul configurat local nu accepta conexiuni fără parolă, ba versiunea de Postgres instalată prin Homebrew avea alte setări de collation. După ce am curățat configurația și am trecut totul pe Docker Compose, am redus timpul de onboarding de la o zi la fix 10 minute. Dai docker compose up și totul funcționează exact la fel ca pe serverul de staging.
Un alt avantaj uriaș este izolarea. Când lucrezi pe 3 proiecte simultan, fiecare cu versiuni diferite de Postgres (să zicem 12, 14 și 16), e sinucidere curată să le rulezi nativ pe aceeași mașină. Docker rezolvă asta elegant prin maparea de porturi diferite în funcție de proiect.
Trade-off-ul sincer: Docker pe macOS și Windows
Nimic nu e gratis pe lumea asta, iar Docker Compose pe mașinile non-Linux vine cu un cost de performanță. Docker rulează pe macOS și Windows printr-o mașină virtuală ușoară, ceea ce înseamnă că operațiunile de I/O (scriere și citire pe disc) sunt considerabil mai lente decât pe Linux nativ.
Dacă rulezi Next.js în modul dev direct în container, s-ar putea să observi că hot-reloading-ul durează 2-3 secunde în loc de 200ms. Din cauza asta, eu folosesc adesea un model hibrid: țin Postgres și Redis în Docker, iar Next.js îl rulez local pe mașina gazdă cu npm run dev, legat la porturile expuse de containere. E cel mai bun compromis între viteza de dezvoltare și izolarea serviciilor grele.
Cum arată o configurație curată
Am văzut mulți developeri care scriu configurații incomplete. De exemplu, pun doar depends_on: - postgres pentru serviciul de backend. Asta doar îi spune lui Docker să pornească containerul de Postgres, dar nu așteaptă ca baza de date să fie gata să primească conexiuni (procesul intern de startup poate dura câteva secunde). De aici apar erorile clasice de genul „Connection refused” la primul start.
În exemplul de mai jos am rezolvat asta folosind un healthcheck pe Postgres. Aplicația va aștepta ca baza de date să fie cu adevărat activă înainte de a porni. De asemenea, folosim volume definite separat pentru ca datele din baza de date să nu dispară atunci când oprești containerele, iar pentru Redis folosim o imagine alpine ca să economisim memorie.
Voi cum preferați să lucrați? Puneți absolut totul în Docker (inclusiv serverul de dev de frontend) sau mergeți pe varianta hibridă ca să nu vă omorâți bateria la laptop?