version: '3.8'
services:
db:
image: postgres:15-alpine
container_name: local_postgres
restart: always
environment:
POSTGRES_USER: dev_user
POSTGRES_PASSWORD: dev_password
POSTGRES_DB: dev_db
ports:
- "5432:5432"
volumes:
- postgres_data:/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: local_redis
ports:
- "6379:6379"
web:
build:
context: .
dockerfile: Dockerfile
container_name: local_nextjs
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://dev_user:dev_password@db:5432/dev_db
- REDIS_URL=redis://redis:6379
volumes:
- .:/app
- /app/node_modules
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
postgres_data:Când vine un coleg nou în echipă, ultimul lucru pe care vrei să-l faci e să pierzi jumătate de zi explicându-i cum se configurează baza de date locală sau ce versiune de Redis îi trebuie. Am pățit asta la un proiect cu vreo 12 microservicii și baze de date diferite. Am redus timpul de onboarding de la o zi întreagă la fix 10 minute folosind o configurație curată de Docker Compose.
Astăzi îți arăt un template simplu și robust pentru un stack clasic: o aplicație Next.js, o bază de date PostgreSQL și un server de cache Redis.
Compromisul de care trebuie să fii conștient
Înainte să aruncăm o privire pe fișierul de configurare, hai să fim sinceri cu un lucru. Docker pe macOS și Windows mănâncă resurse cu lopata. Dacă ai un laptop mai vechi, rularea Next.js în interiorul Docker cu bind-mount pentru hot-reload o să-ți facă ventilatoarele să sune ca un avion la decolare.
Personal, prefer un compromis: rulez PostgreSQL și Redis în containere Docker, iar aplicația Next.js o rulez nativ pe mașina mea cu npm run dev. Totuși, dacă vrei izolare completă și zero dependențe instalate local, poți rula totul în Docker Compose. Configurația de mai jos le acoperă pe amândouă.
Trucul cu "depends_on" care îți salvează nervii
Cea mai mare greșeală pe care o văd în ghidurile de pe net este folosirea simplă a directivei depends_on: - db. Asta doar îi spune Docker-ului să pornească containerul de Postgres înaintea aplicației web. Nu înseamnă că Postgres este și gata să accepte conexiuni când Next.js încearcă să facă migrarea bazei de date.
Rezultatul? Aplicația Next.js dă crash la pornire pentru că baza de date încă se inițializează.
Rezolvarea constă în definirea unui healthcheck pentru baza de date și folosirea unei condiții în depends_on. Ne asigurăm astfel că Next.js pornește doar când Postgres raportează că e complet funcțional.
Volumul de date persistent
O altă problemă clasică: oprești containerele și pierzi toate datele de test pe care le-ai introdus cu trudă. Pentru a evita asta, mapăm un volum extern pentru Postgres. Atenție să nu adaugi folderul de date în controlul de versiune (Git). Adaugă-l direct în .gitignore.
Cum ți se pare abordarea asta? Preferi să rulezi totul în Docker, inclusiv Next.js, sau folosești containerele doar pentru baze de date și servicii externe?