Stanco di perdere ore a configurare l’ambiente di sviluppo? In questa guida pratica scoprirai come avviare un ambiente completo con Node.js e PostgreSQL usando Docker Compose in meno di 5 minuti. Niente teoria astratta sui container: solo codice funzionante da copiare e incollare.
Prima di continuare: ripassa queste 3 basi
Perché Docker Compose per lo Sviluppo Node + Postgres
Docker per sviluppatori significa principalmente una cosa: eliminare il “funziona sulla mia macchina”. Con Docker Compose puoi definire l’intero stack applicativo in un singolo file YAML e condividerlo con tutto il team.
I vantaggi di usare Docker Compose per Node.js e PostgreSQL:
- Setup istantaneo – Un comando e hai database, backend e volumi persistenti pronti
- Isolamento completo – Ogni progetto ha le sue dipendenze senza conflitti
- Pulizia totale – Elimini tutto con
docker-compose down -v - Consistenza tra ambienti – Dev, staging e produzione identici
Prerequisiti: Cosa Ti Serve Prima di Iniziare
Prima di procedere con il setup dell’ambiente di sviluppo Docker, assicurati di avere:
- Docker Desktop installato (include Docker Compose) – Scarica qui
- Editor di codice (VS Code consigliato)
- Connessione internet per scaricare le immagini Docker
Verifica l’installazione aprendo il terminale e digitando:
docker --version
docker-compose --versionIl File docker-compose.yml Completo (Copia e Incolla)
Ecco il docker-compose.yml production-ready che puoi usare immediatamente. Crea questo file nella root del tuo progetto:
version: '3.8'
services:
# Database PostgreSQL
postgres:
image: postgres:16-alpine
container_name: dev_postgres
restart: unless-stopped
environment:
POSTGRES_USER: devuser
POSTGRES_PASSWORD: devpassword
POSTGRES_DB: myapp_dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U devuser"]
interval: 10s
timeout: 5s
retries: 5
# Applicazione Node.js
app:
image: node:20-alpine
container_name: dev_node_app
restart: unless-stopped
working_dir: /app
volumes:
- ./:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
NODE_ENV: development
DATABASE_URL: postgresql://devuser:devpassword@postgres:5432/myapp_dev
PORT: 3000
command: sh -c "npm install && npm run dev"
depends_on:
postgres:
condition: service_healthy
# pgAdmin (opzionale - interfaccia grafica per Postgres)
pgadmin:
image: dpage/pgadmin4:latest
container_name: dev_pgadmin
restart: unless-stopped
environment:
PGADMIN_DEFAULT_EMAIL: admin@local.dev
PGADMIN_DEFAULT_PASSWORD: admin
ports:
- "5050:80"
depends_on:
- postgres
volumes:
postgres_data:
driver: local
Struttura del Progetto Consigliata
Per sfruttare al meglio questo setup Docker Compose, organizza il progetto così:
my-project/
├── docker-compose.yml
├── package.json
├── .env
├── init-scripts/
│ └── 01-init.sql
├── src/
│ ├── index.js
│ └── db/
│ └── connection.js
└── .dockerignoreFile .dockerignore Essenziale
Crea un file .dockerignore per escludere file inutili:
node_modules
npm-debug.log
.git
.gitignore
.env
*.md
.vscodeAvvio dell’Ambiente: I Comandi Essenziali
Ora che hai il file docker-compose.yml pronto, ecco come gestire il tuo ambiente di sviluppo Docker:
Prima volta: Build e Avvio
# Avvia tutti i servizi in background
docker-compose up -d
# Verifica che i container siano attivi
docker-compose ps
# Visualizza i log in tempo reale
docker-compose logs -f app
Accesso ai Servizi
Dopo l’avvio, puoi accedere a:
- Applicazione Node.js:
http://localhost:3000 - PostgreSQL:
localhost:5432 - pgAdmin:
http://localhost:5050(user: admin@local.dev, password: admin)
Gestione Quotidiana
# Ferma i container (dati persistono)
docker-compose stop
# Riavvia i container
docker-compose start
# Ferma e rimuovi container (dati persistono nei volumi)
docker-compose down
# Rimuovi tutto inclusi i volumi (ATTENZIONE: cancella il database)
docker-compose down -vConnessione al Database da Node.js
Ecco un esempio pratico di connessione a PostgreSQL usando pg (il client più popolare per Node.js):
Installa il Client PostgreSQL
npm install pg dotenvFile: src/db/connection.js
const { Pool } = require('pg');
// La connection string viene da docker-compose.yml
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
pool.on('connect', () => {
console.log('✅ Connesso a PostgreSQL');
});
pool.on('error', (err) => {
console.error('❌ Errore PostgreSQL:', err);
});
module.exports = pool;Esempio di Query
const pool = require('./db/connection');
async function getUsers() {
try {
const result = await pool.query('SELECT * FROM users');
return result.rows;
} catch (error) {
console.error('Errore query:', error);
throw error;
}
}
// Test della connessione
pool.query('SELECT NOW()', (err, res) => {
if (err) {
console.error('❌ Errore connessione DB:', err);
} else {
console.log('✅ Database connesso:', res.rows[0].now);
}
});Script di Inizializzazione Database
Grazie al volume ./init-scripts:/docker-entrypoint-initdb.d, puoi eseguire automaticamente script SQL all’avvio.
Crea init-scripts/01-init.sql:
-- Creazione tabella users
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Inserimento dati di test
INSERT INTO users (username, email) VALUES
('john_doe', 'john@example.com'),
('jane_smith', 'jane@example.com')
ON CONFLICT DO NOTHING;
-- Creazione indici
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);Nota importante: Gli script in docker-entrypoint-initdb.d vengono eseguiti solo alla prima creazione del database. Per riapplicarli, usa docker-compose down -v.
Hot Reload: Sviluppo con Nodemon
Per il massimo della produttività, configura il hot reload per vedere le modifiche istantaneamente.
Installa Nodemon
npm install --save-dev nodemonModifica package.json
{
"scripts": {
"dev": "nodemon src/index.js",
"start": "node src/index.js"
}
}Il comando npm run dev nel docker-compose.yml attiverà automaticamente nodemon, riavviando l’app a ogni modifica dei file.
Debugging con Docker Compose
Quando qualcosa non funziona, questi comandi Docker per sviluppatori sono essenziali:
Verifica Stato e Logs
# Stato di tutti i container
docker-compose ps
# Log di tutti i servizi
docker-compose logs
# Log di un servizio specifico
docker-compose logs app
# Segui i log in tempo reale
docker-compose logs -f --tail=100 appAccesso alla Shell del Container
# Shell nel container Node.js
docker-compose exec app sh
# Shell nel container Postgres
docker-compose exec postgres psql -U devuser -d myapp_dev
# Esegui comando senza entrare nella shell
docker-compose exec app npm listProblemi Comuni e Soluzioni
Porta già in uso:
# Trova chi usa la porta 5432
lsof -i :5432
# Oppure cambia la porta in docker-compose.yml
ports:
- "5433:5432" # Usa 5433 sul tuo hostContainer non si avvia:
# Rebuild forzato
docker-compose up -d --build --force-recreateDatabase corrotto:
# Reset completo (ATTENZIONE: cancella tutti i dati)
docker-compose down -v
docker-compose up -dOttimizzazioni per la Produzione
Questo setup è perfetto per sviluppo, ma per produzione considera queste modifiche:
Usa Variabili d’Ambiente Esterne
Crea un file .env:
POSTGRES_USER=produser
POSTGRES_PASSWORD=strong_password_here
POSTGRES_DB=myapp_prod
NODE_ENV=production
PORT=3000Poi modifica docker-compose.yml:
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}Usa Multi-Stage Build per Node.js
Invece di image: node:20-alpine, crea un Dockerfile ottimizzato:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]E modifica docker-compose.yml:
app:
build:
context: .
dockerfile: Dockerfile
# ... resto della configurazioneAlternative e Strumenti Aggiuntivi
Questo setup Docker Compose è solo l’inizio. Ecco altre possibilità:
Aggiungi Redis per il Caching
redis:
image: redis:7-alpine
container_name: dev_redis
ports:
- "6379:6379"
volumes:
- redis_data:/dataNginx come Reverse Proxy
nginx:
image: nginx:alpine
container_name: dev_nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- appMonitoring con Docker Stats
# Visualizza risorse in tempo reale
docker stats
# Solo i container del progetto
docker stats $(docker-compose ps -q)Conclusioni: Il Tuo Ambiente Perfetto in 5 Minuti
Hai appena creato un ambiente di sviluppo professionale con Docker Compose, Node.js e PostgreSQL. Ricapitolando cosa hai ottenuto:
- ✅ Setup automatizzato – Un comando per avviare tutto
- ✅ Database persistente – I dati sopravvivono ai restart
- ✅ Hot reload – Vedi le modifiche istantaneamente
- ✅ Interfaccia grafica – pgAdmin per gestire il database visualmente
- ✅ Pronto per il team – Condividi il setup in secondi
Questo approccio a Docker per sviluppatori elimina ore di configurazione e garantisce che tutto il team lavori con lo stesso stack. Non serve più installare PostgreSQL localmente, gestire versioni di Node.js diverse o debuggare conflitti di porta.
Prossimi passi: Prova ad aggiungere altri servizi come Redis, MongoDB o Elasticsearch. Docker Compose rende banale orchestrare anche stack complessi.
💡 Vuoi approfondire Docker? Scopri come deployare questo stack in produzione con Docker Swarm o Kubernetes nella nostra guida avanzata.
Potrebbe interessarti anche:
- Docker Compose ti permette di definire applicazioni multi-container in un singolo file YAML. Per approfondire le funzionalità avanzate, consulta la documentazione ufficiale di Docker Compose.
- Nel nostro setup utilizziamo
node:20-alpine, la versione più recente e leggera disponibile sulla immagine ufficiale Node.js su Docker Hub. - Per il database utilizziamo
postgres:16-alpine, l’immagine ufficiale PostgreSQL ottimizzata per ambienti di sviluppo. - Per connetterti a PostgreSQL da Node.js, la libreria node-postgres (pg) è lo standard de facto, con oltre 10 milioni di download settimanali.
- pgAdmin è lo strumento di amministrazione più popolare per PostgreSQL. Per scoprire tutte le funzionalità avanzate, consulta la documentazione ufficiale di pgAdmin.
Domande Frequenti su Docker Compose con Node.js e PostgreSQL
Quanto tempo ci vuole per configurare Docker Compose con Node.js e PostgreSQL?
Con il file docker-compose.yml fornito in questa guida, il setup completo richiede meno di 5 minuti. Devi solo copiare il file nella root del tuo progetto ed eseguire docker-compose up -d. Docker scaricherà automaticamente le immagini necessarie e avvierà tutti i servizi.
Cosa devo installare prima di usare Docker Compose?
Hai bisogno solo di Docker Desktop installato sul tuo computer (disponibile per Windows, Mac e Linux). Docker Desktop include già Docker Compose integrato. Non serve installare Node.js o PostgreSQL localmente, perché tutto viene gestito dai container Docker.
I dati del database PostgreSQL vengono persi quando fermo i container?
No, i dati sono persistenti grazie ai volumi Docker. Il nostro docker-compose.yml usa un volume chiamato postgres_data che conserva tutti i dati del database anche quando fermi o riavvii i container. Solo il comando docker-compose down -v elimina i volumi e quindi i dati.
Quali versioni di Node.js e PostgreSQL supporta questo setup?
Il setup utilizza Node.js 20 Alpine e PostgreSQL 16 Alpine, le versioni più recenti e ottimizzate. Puoi facilmente cambiare versione modificando i tag delle immagini nel docker-compose.yml, ad esempio node:18-alpine o postgres:15-alpine per usare versioni precedenti.
Come funziona il hot reload con Docker Compose?
Il setup include nodemon che rileva automaticamente le modifiche ai file nel tuo progetto. Grazie al volume che mappa la cartella locale nel container (./:/app), ogni volta che salvi un file JavaScript, nodemon riavvia automaticamente l’applicazione Node.js senza dover riavviare il container.
Cosa faccio se le porte 5432 o 3000 sono già in uso?
Puoi modificare le porte esposte nel docker-compose.yml senza problemi. Ad esempio, cambia "5432:5432" in "5433:5432" per esporre PostgreSQL sulla porta 5433 del tuo host, mentre internamente i container continuano a usare la porta standard 5432 per comunicare tra loro.
Come mi connetto a PostgreSQL da un client esterno come DBeaver o pgAdmin?
Usa questi parametri di connessione: Host localhost, Porta 5432, Database myapp_dev, Username devuser, Password devpassword. Oppure usa l’interfaccia pgAdmin inclusa nel setup, accessibile all’indirizzo http://localhost:5050 (username: admin@local.dev, password: admin).
Come rimuovo completamente l’ambiente Docker e libero spazio su disco?
Esegui docker-compose down -v per fermare i container e rimuovere i volumi. Per pulire completamente immagini e cache, usa docker system prune -a --volumes. Questo comando rimuove tutti i container fermati, le immagini non utilizzate e i volumi orfani, liberando spazio prezioso.





