← Torna al blog

Docker per lo sviluppo web: una guida pratica ai container che serve davvero

Perche Docker conta per lo sviluppo web

Se avete mai passato mezza giornata a configurare un ambiente di sviluppo, a fare debug sul perche un progetto funziona sul portatile di un collega ma non sul vostro, o avete sentito le parole "ma sul mio computer funziona," Docker e la risposta a un problema che conoscete gia bene.

Docker impacchetta un'applicazione e tutte le sue dipendenze (runtime, librerie, strumenti di sistema, file di configurazione) in un'unita standardizzata chiamata container. Quel container gira in modo identico su qualsiasi macchina che ha Docker installato, che sia il MacBook di uno sviluppatore, un server Linux in un data center, o un runner di pipeline CI/CD. L'ambiente e definito nel codice, versionato insieme alla vostra applicazione e riproducibile da zero in pochi secondi.

Non si tratta solo di comodita. L'inconsistenza degli ambienti e una fonte genuina di bug, fallimenti di deployment e tempo sprecato. Quando il vostro ambiente di sviluppo non corrisponde alla produzione, i bug passano attraverso i test e appaiono solo dopo il deployment. Docker elimina questa intera categoria di problemi.

Container vs Macchine Virtuali

Se avete usato macchine virtuali (VirtualBox, VMware, Parallels), i container potrebbero sembrare simili. Entrambi forniscono ambienti isolati. Ma l'architettura e fondamentalmente diversa.

Macchine Virtuali

Una VM esegue un sistema operativo completo con il proprio kernel, sopra un hypervisor. Ogni VM include un'installazione OS completa (spesso diversi gigabyte), si avvia in minuti e consuma CPU e RAM significative solo per mantenere l'overhead del sistema operativo.

Container

Un container condivide il kernel del sistema operativo della macchina host. Impacchetta solo l'applicazione e le sue dipendenze specifiche, non un intero OS. Un'immagine container tipica per un'applicazione Node.js e di 100-300 MB (rispetto ai 2-4 GB di una VM). I container si avviano in secondi. Potete eseguire decine di container sullo stesso portatile che fatica con tre VM.

AspettoMacchina VirtualeContainer
Livello di isolamentoIsolamento OS completoIsolamento a livello di processo
Tempo di avvioMinutiSecondi
Dimensione immagineGigabyteMegabyte
Overhead risorseAlto (OS completo per VM)Basso (kernel condiviso)
DensitaPoche per hostDecine a centinaia per host
Caso d'usoEseguire tipi di OS diversiPackaging e isolamento applicazioni

Concetti base di Docker

Immagini

Un'immagine Docker e un template di sola lettura che definisce cosa conterra il container. Pensatela come uno snapshot di un ambiente configurato. Le immagini vengono costruite a livelli: partite da un'immagine base (come node:18-alpine o python:3.11-slim), aggiungete il codice dell'applicazione, installate le dipendenze e configurate le impostazioni.

Container

Un container e un'istanza in esecuzione di un'immagine. Quando un container viene fermato e rimosso, il suo livello scrivibile viene perso (a meno che non usiate i volumi per persistere i dati). Questa natura effimera e una caratteristica, non un difetto.

Volumi

I volumi sono il meccanismo di Docker per lo storage persistente. Nello sviluppo, usate i volumi per montare il vostro codice sorgente locale nel container, cosi le modifiche che fate nel vostro editor appaiono immediatamente nel container in esecuzione senza ricostruire.

Reti

I container Docker possono comunicare tra loro attraverso reti virtuali. Quando usate docker-compose, tutti i servizi definiti nello stesso file compose vengono automaticamente posizionati su una rete condivisa e possono raggiungersi per nome di servizio.

Il Dockerfile: definire il vostro ambiente

Un Dockerfile e un file di testo che contiene istruzioni per costruire un'immagine Docker. Ecco un esempio pratico per un'applicazione Node.js:

FROM node:18-alpine AS base WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 3000 CMD ["node", "server.js"]

Analizziamo riga per riga:

  • FROM node:18-alpine: Partire dall'immagine Node.js 18 ufficiale basata su Alpine Linux (una distribuzione Linux minimale, che mantiene l'immagine piccola).
  • WORKDIR /app: Impostare la directory di lavoro dentro il container.
  • COPY package*.json ./: Copiare solo i file dei pacchetti prima. Questa e un'ottimizzazione deliberata: Docker fa cache dei livelli.
  • RUN npm ci --only=production: Installare le dipendenze.
  • COPY . .: Copiare il resto del codice dell'applicazione.
  • CMD ["node", "server.js"]: Definire il comando da eseguire all'avvio del container.

Build multi-stage

Per le immagini di produzione, i build multi-stage vi permettono di usare un'immagine per la compilazione (con dipendenze dev, compilatori, ecc.) e un'immagine separata e minimale per l'esecuzione. L'immagine finale contiene solo l'output compilato e le dipendenze di produzione. Questo mantiene le immagini di produzione piccole e riduce la superficie di attacco.

Docker Compose: ambienti di sviluppo multi-servizio

La maggior parte delle applicazioni web ha bisogno di piu del solo runtime. Servono un database, magari una cache, magari una coda di messaggi. Docker Compose vi permette di definire e eseguire ambienti multi-container con un singolo file YAML.

Node.js + PostgreSQL + Redis

version: '3.8' services: app: build: . ports: - "3000:3000" volumes: - .:/app - /app/node_modules environment: DATABASE_URL: postgres://user:password@db:5432/myapp REDIS_URL: redis://cache:6379 depends_on: - db - cache db: image: postgres:15-alpine environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: myapp volumes: - pgdata:/var/lib/postgresql/data cache: image: redis:7-alpine volumes: pgdata:

Con questo file salvato come docker-compose.yml, eseguire docker compose up avvia la vostra applicazione, un database PostgreSQL e una cache Redis. Tutti e tre possono comunicare tra loro per nome di servizio.

PHP + MySQL + Nginx

Un setup comune per WordPress, Laravel o applicazioni PHP personalizzate. Nginx funge da reverse proxy davanti a PHP-FPM, con MySQL come database.

Python (Django/Flask) + PostgreSQL

Identica struttura con il servizio web che esegue il server di sviluppo Django o Flask, connesso a PostgreSQL tramite la rete Docker interna.

Il problema "funziona sul mio computer" risolto

Prima di Docker, l'onboarding di un nuovo sviluppatore su un progetto andava piu o meno cosi:

  1. Clonare il repository
  2. Installare la versione corretta di Node.js (o PHP, o Python). Ma il sistema ha una versione diversa. Usare nvm o pyenv per gestire piu versioni.
  3. Installare il database. Configurarlo. Creare il database e l'utente. Eseguire le migrazioni.
  4. Installare Redis. O Elasticsearch. O qualsiasi altra cosa serva al progetto.
  5. Configurare le variabili d'ambiente. Meta sono documentate, l'altra meta e conoscenza tribale.
  6. Eseguire l'applicazione e sperare che funzioni. Se no, fare debug per diverse ore.

Con Docker, il processo diventa:

  1. Clonare il repository
  2. Eseguire docker compose up
  3. L'applicazione e in esecuzione con tutte le dipendenze configurate

Non e un'esagerazione. Quando l'ambiente di sviluppo e completamente definito in un Dockerfile e docker-compose.yml, ogni sviluppatore lavora con lo stesso stack, stesse versioni, stessa configurazione. Niente piu "io ho PostgreSQL 14 e tu hai 15, e il comportamento e diverso."

Per i team a Lugano e in tutta la Svizzera, dove i team di sviluppo sono spesso piccoli e il tempo di ogni sviluppatore e prezioso, le ore risparmiate nella configurazione degli ambienti e nel debug di problemi specifici dell'ambiente si accumulano velocemente.

Docker per pipeline CI/CD

Test consistenti

Il vostro server CI (GitHub Actions, GitLab CI, Jenkins) esegue i test dentro gli stessi container Docker usati nello sviluppo. Se i test passano localmente, passano nel CI, perche l'ambiente e identico.

Build riproducibili

Costruire un'immagine Docker da un Dockerfile produce lo stesso risultato indipendentemente da dove viene costruita. La vostra pipeline CI costruisce l'immagine di produzione, esegue i test contro di essa, e se tutto passa, la pubblica in un container registry.

Deployment semplificato

Fare il deployment di un container Docker in produzione e semplice: scaricare l'immagine dal registry e avviare il container. Piattaforme come Railway, Render, Fly.io e AWS ECS rendono il deployment dei container ancora piu semplice.

Basi di sicurezza Docker

I container forniscono isolamento a livello di processo, ma non sono una soluzione magica per la sicurezza:

Non eseguire come root

Di default, i processi dentro i container Docker girano come root. Aggiungete un utente non-root al vostro Dockerfile:

RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser

Usare immagini base minimali

Usate immagini basate su Alpine (node:18-alpine, python:3.11-alpine) invece di immagini Debian/Ubuntu complete. Meno pacchetti significano meno vulnerabilita potenziali.

Non memorizzare segreti nelle immagini

Non mettete mai password, chiavi API o certificati in un Dockerfile. Usate variabili d'ambiente, Docker secrets o strumenti esterni di gestione segreti.

Scansionare le immagini per vulnerabilita

Strumenti come Trivy, Docker Scout e Snyk possono scansionare le vostre immagini Docker per vulnerabilita note. Integrate queste scansioni nella vostra pipeline CI.

Per approfondimenti sulla sicurezza delle applicazioni web, vedete la nostra guida OWASP Top 10 e la nostra checklist sicurezza per PMI.

Quando Docker e esagerato

  • Siti statici semplici: Se state costruendo un sito HTML/CSS/JS statico senza dipendenze backend, Docker aggiunge complessita senza beneficio proporzionale.
  • Progetti singoli con stack semplici: Se siete l'unico sviluppatore, con un solo runtime e senza database, i benefici di consistenza dell'ambiente sono minimi.
  • Team senza familiarita con i container: Se il team non ha mai usato Docker, introdurlo durante una scadenza stretta vi rallenterà. Imparatelo su un progetto secondario.
  • Macchine con risorse limitate: Docker Desktop su macOS e Windows esegue una VM Linux sotto il cofano, che consuma RAM e CPU.

Considerazioni sulle performance

Performance del file system su macOS

Docker su macOS usa una VM Linux, e le operazioni del file system tra l'host macOS e il container Linux sono piu lente dell'accesso nativo ai file. Questo e evidente con directory node_modules grandi. Docker Desktop ha migliorato significativamente con VirtioFS, ma resta misurabilmente piu lento dello sviluppo nativo.

Tempi di build

I build Docker possono essere lenti se non ottimizzati. Ottimizzazioni chiave:

  • Ordinare le istruzioni del Dockerfile dalla meno alla piu frequentemente modificata
  • Usare .dockerignore per escludere file non necessari
  • Usare build multi-stage
  • Sfruttare BuildKit per l'esecuzione parallela degli stage

Comandi Docker essenziali

ComandoCosa fa
docker compose upAvvia tutti i servizi definiti in docker-compose.yml
docker compose up -dAvvia in modalita detached (background)
docker compose downFerma e rimuove tutti i container
docker compose logs -fSegui l'output dei log di tutti i servizi
docker compose exec app shApri una shell dentro il container app in esecuzione
docker build -t myapp .Costruisci un'immagine dalla directory corrente
docker psElenca i container in esecuzione
docker system pruneRimuovi immagini, container e reti non utilizzati

Iniziare oggi

  1. Installate Docker Desktop (macOS, Windows) o Docker Engine (Linux).
  2. Scegliete un progetto su cui state lavorando attivamente.
  3. Scrivete un Dockerfile per la vostra applicazione.
  4. Create un docker-compose.yml se il progetto usa un database o altri servizi.
  5. Eseguite docker compose up e verificate che l'applicazione funzioni.
  6. Committate Dockerfile e docker-compose.yml nel vostro repository cosi tutto il team ne beneficia.

La configurazione iniziale richiede un'ora o due. Il risparmio di tempo inizia dal secondo sviluppatore che si unisce al progetto e non si ferma. Se avete bisogno di aiuto per configurare Docker per il vostro workflow di sviluppo web, il nostro team a Lugano puo aiutarvi.

Vuoi sapere se il tuo sito è sicuro?

Richiedi un audit di sicurezza gratuito. In 48 ore ricevi un report completo.

Richiedi Audit Gratuito

Contatto Rapido