version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: nextjs_postgres
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
container_name: nextjs_redis
ports:
- "6379:6379"
volumes:
- redisdata:/data
web:
build:
context: .
dockerfile: Dockerfile.dev
container_name: nextjs_app
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://dev_user:dev_password@postgres:5432/dev_db
- REDIS_URL=redis://redis:6379
volumes:
- .:/app
- /app/node_modules
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
volumes:
pgdata:
redisdata:Am văzut prea des setup-uri de dev unde noul coleg pierde două zile doar ca să își pornească baza de date și Redis-ul local. Ba nu are versiunea bună de Node pe sistem, ba Postgres-ul instalat direct pe macOS se bate pe portul 5432 cu o altă instanță uitată în fundal. Docker Compose rezolvă asta elegant. Totuși, dacă nu e configurat cu cap, te trezești că Next.js pornește înaintea bazei de date și crapă instant la prima interogare.
La un proiect recent cu peste 14.000 de utilizatori activi, am reușit să reduc timpul de onboarding pentru developeri de la o zi întreagă la fix 5 minute. Secretul a fost un singur fișier docker-compose.yml bine structurat. Acesta se asigură că serviciile de backend sunt complet pregătite înainte ca aplicația Next.js să încerce să se conecteze la ele.
Compromisul de care trebuie să fii conștient
Hai să fim sinceri de la început. Rularea Next.js în interiorul unui container Docker în timpul dezvoltării are un mare minus pe macOS și Windows: performanța volumelor partajate (bind mounts). Din cauza modului în care Docker virtualization gestionează sistemul de fișiere, hot-reload-ul poate avea un delay deranjant de 1-2 secunde față de rularea nativă pe host.
Pentru proiecte uriașe, cu sute de pagini, eu prefer să țin doar Postgres și Redis în Docker, iar Next.js să îl rulez direct pe mașina mea cu npm run dev. Totuși, pentru proiecte mici și medii, comoditatea de a avea totul izolat într-o singură comandă bate acest mic lag de performanță.
Configurația de care ai nevoie
Marea problemă cu depends_on în Docker Compose este că, implicit, doar așteaptă ca containerul bazei de date să fie pornit, nu și gata să accepte conexiuni. Postgres are nevoie de câteva secunde bune ca să își inițializeze procesele interne.
Soluția curată este să folosim un bloc de healthcheck pentru Postgres și să instruim serviciul de Next.js să aștepte starea de service_healthy. În plus, mapăm corect volumele pentru Node, inclusiv un volum anonim pentru node_modules. Astfel, evităm suprascrierea pachetelor din container cu cele de pe host.
Cum rulezi totul în siguranță?
După ce ai salvat fișierul, tot ce trebuie să faci este să rulezi docker compose up. Docker se va ocupa de descărcarea imaginilor, crearea volumelor persistente pentru Postgres (ca să nu pierzi datele când oprești containerele) și pornirea serviciilor în ordinea corectă.
Un mic pont: folosește întotdeauna versiuni Alpine pentru imagini în mediul de dev. Sunt mult mai ușoare, se descarcă rapid și consumă considerabil mai puține resurse pe mașina ta.
Tu cum procedezi în mod curent? Rulezi și Next.js în container la dev, sau preferi să ții doar bazele de date în Docker și Node pe host?