Illustrazione di un ambiente Docker per sviluppatori con container Node.js e PostgreSQL impilati, in stile tech editoriale con accenti #097e70

Docker per Sviluppatori: Ambiente Node + Postgres

Stanco di configurare manualmente l'ambiente di sviluppo? Questa guida ti mostra come avviare Node.js e PostgreSQL con Docker Compose in meno di 5 minuti. Include file docker-compose.yml completo, script di inizializzazione database, hot reload con nodemon e interfaccia pgAdmin. Zero teoria, solo codice pronto all'uso.

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.

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 --version

Il 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
└── .dockerignore

File .dockerignore Essenziale

Crea un file .dockerignore per escludere file inutili:

node_modules
npm-debug.log
.git
.gitignore
.env
*.md
.vscode

Avvio 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 -v

Connessione 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 dotenv

File: 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 nodemon

Modifica 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 app

Accesso 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 list

Problemi 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 host

Container non si avvia:

# Rebuild forzato
docker-compose up -d --build --force-recreate

Database corrotto:

# Reset completo (ATTENZIONE: cancella tutti i dati)
docker-compose down -v
docker-compose up -d

Ottimizzazioni 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=3000

Poi 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 configurazione

Alternative 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:/data

Nginx come Reverse Proxy

nginx:
  image: nginx:alpine
  container_name: dev_nginx
  ports:
    - "80:80"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
  depends_on:
    - app

Monitoring 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:

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.