Dockerfile vs buildpack: quale usare per la tua app?

Una scheda Dockerfile e una scheda buildpack che confluiscono in un'unica immagine container

In breve

  • Con un Dockerfile scrivi tu ogni passaggio della build; i Cloud Native Buildpacks riconoscono il tuo linguaggio e costruiscono l'immagine dal codice sorgente senza Dockerfile.
  • I buildpack sono adatti alle app standard in linguaggi supportati e lasciano al builder la manutenzione dell'immagine di base; un Dockerfile è adatto a pacchetti di sistema personalizzati, stack insoliti e pieno controllo sull'immagine.
  • Entrambi producono un'immagine container, quindi puoi partire con uno e cambiare in seguito.
  • Su Nodion scegli Buildpack o Dockerfile per ogni app: le app con buildpack sono in ascolto sulla PORT impostata da Nodion, quelle con Dockerfile sulla porta di EXPOSE o della scheda Processes.

Sia un Dockerfile sia i buildpack trasformano il tuo codice sorgente in un'immagine container. La differenza è chi definisce i passaggi della build: con un Dockerfile lo fai tu, con i buildpack vengono ricavati dal tuo codice. Usa i buildpack per una normale web app in un linguaggio supportato e un Dockerfile quando ti serve il pieno controllo sull'immagine o usi uno stack che nessun buildpack riconosce.

Cos'è un Dockerfile

Con le parole di Docker, un Dockerfile è “a text document that contains all the commands a user could call on the command line to assemble an image”, cioè un documento di testo con tutti i comandi che un utente potrebbe eseguire dalla riga di comando per assemblare un'immagine. Scegli un'immagine di base, installi i pacchetti di sistema, copi il tuo codice, installi le dipendenze e imposti il comando di avvio. Ogni riga è tua: pieno controllo, ma anche tutta la manutenzione.

FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Nella pratica, due funzionalità determinano come si scrivono i Dockerfile:

  • Cache dei layer: l'immagine viene costruita a layer, e Docker li mette in cache. Quando un layer cambia, vengono ricostruiti anche tutti i layer successivi. Per questo l'esempio copia package.json e installa le dipendenze prima di copiare il resto del codice.
  • Build multi-stage: più istruzioni FROM in un solo file, ognuna delle quali avvia un nuovo stage. Compili in uno stage e copi solo il risultato in un'immagine finale piccola, lasciandoti alle spalle compilatori e strumenti di build.

Cosa sono i buildpack

Un buildpack è un software che analizza il tuo codice sorgente e capisce come farne la build. I Cloud Native Buildpacks sono lo standard aperto per farlo. Una build attraversa fasi fisse: detect trova i buildpack adatti al tuo codice, build trasforma il sorgente in artefatti eseguibili (per esempio installando un runtime e le dipendenze e compilando), ed export scrive l'immagine OCI finale. Non ti serve un Dockerfile; file opzionali come un Procfile o project.toml possono configurare la build e i processi.

Tre proprietà distinguono i buildpack:

  • Immagini di build e di runtime separate: compilatori e header stanno nell'immagine di build, e l'app viene distribuita sull'immagine di runtime senza di essi.
  • Rebase: quando l'immagine di runtime riceve un aggiornamento, pack rebase fa puntare l'immagine dell'app alla nuova base senza rifare la build dell'app.
  • Riproducibilità: il lifecycle imposta i timestamp dei layer a una data fissa, quindi lo stesso sorgente, lo stesso builder e gli stessi buildpack producono la stessa immagine, a patto che i buildpack stessi producano un output riproducibile.

Trovi altri dettagli in Cloud Native Buildpacks: cosa sono e come funzionano.

Dockerfile vs buildpack in sintesi

DockerfileBuildpack
ControlloTotale: immagine di base, pacchetti, utenti, struttura dei fileEntro le opzioni del buildpack: pin di versione, Procfile, pacchetti aggiuntivi
ManutenzioneAggiorni tu l'immagine di base e ogni passaggioChi mantiene il builder aggiorna lo stack e i pacchetti dei linguaggi
Aggiornamenti di sicurezzaRifai la build con un'immagine di base aggiornata; devi accorgertene tuGli aggiornamenti del builder portano immagini di base aggiornate alla build successiva; un'immagine esistente richiede una nuova build o un rebase esplicito
RiproducibilitàDipende da quanto rigorosamente fissi immagini e pacchettiIntegrata a parità di input, con timestamp dei layer fissi
Velocità di buildVeloce con una cache dei layer ben ordinata; una modifica all'inizio ricostruisce tutto ciò che segueI layer in cache, come le dipendenze, vengono ripristinati tra una build e l'altra
Multi-stageSì, più stage FROMNon serve: gli strumenti di build restano nell'immagine di build
Stack insolitiTutto ciò che puoi installare in un'immagineSolo ciò che il builder riconosce

Quando scegliere i buildpack

  • La tua app è scritta in un linguaggio supportato dal builder, come Node.js, Python, Ruby, PHP, Go, Rust, Java, .NET o Elixir, oppure è un sito statico.
  • Non vuoi gestire da solo immagini di base e pacchetti del sistema operativo.
  • Hai molti servizi e vuoi che vengano tutti costruiti allo stesso modo.
  • Il tuo team conosce il linguaggio, non Docker.

Quando scegliere un Dockerfile

  • Ti serve un'immagine di base specifica, pacchetti di sistema oltre a quelli che installa un buildpack, o un utente personalizzato.
  • Il tuo linguaggio o framework non viene riconosciuto dal builder.
  • Il progetto include già un Dockerfile funzionante, come molte app open source.
  • Vuoi un'immagine piccola da una build multi-stage, oppure esattamente la stessa immagine in locale, in CI e in produzione.

Come Nodion supporta entrambi

In Applications → New colleghi un repository Git e scegli Buildpacks o Dockerfile. La scansione preferisce Dockerfile quando ne trova uno. Puoi cambiare la strategia in seguito in Settings; si applica dal deploy successivo. Se fai la build altrove, fai invece il deploy di un'immagine già pronta.

Buildpack su Nodion

  • I Cloud Native Buildpacks di Nodion sullo stack nodion-26 (Ubuntu 26.04 LTS). Riconoscono Node.js, Python, Ruby, PHP, Go, Rust, Elixir, Java, .NET e siti statici.
  • Il processo gira come utente non root. I pacchetti Debian aggiuntivi vanno in project.toml o in un Aptfile; i loro script di manutenzione non vengono eseguiti.
  • Un Procfile definisce i tipi di processo; altrimenti, l'impostazione predefinita del linguaggio imposta il processo web.
  • Porta: Nodion imposta PORT. Mettiti in ascolto su quella porta; se non è impostata, la maggior parte dei comandi predefiniti ripiega su 8080.
web: gunicorn myapp.wsgi --bind 0.0.0.0:$PORT
worker: python worker.py

Dockerfile su Nodion

  • La base directory è il build context, e un .dockerignore al suo interno viene rispettato.
  • I file multi-stage funzionano. Non c'è un selettore di stage, quindi viene eseguito l'ultimo stage.
  • Le variabili d'ambiente contrassegnate come Build vengono passate come build arg (ARG). I secret di BuildKit non sono collegati.
  • Porta: Nodion non imposta PORT su un'app con Dockerfile. Mettiti in ascolto sulla porta del processo web, precompilata da EXPOSE e modificabile nella scheda Processes; se quella lista è vuota, Nodion usa la porta indicata da EXPOSE nell'immagine, poi 8080. Ascolta su tutte le interfacce, non solo su localhost.
  • Health check: la readiness è una richiesta HTTP GET al percorso dell'health check indicato in Settings (per impostazione predefinita /). Una risposta 2xx o 3xx indica che l'app è pronta. Un HEALTHCHECK nell'immagine viene ignorato.
  • L'istruzione USER dell'immagine viene rispettata.

Tutti i dettagli sono in Buildpack e nella documentazione del Dockerfile. Non sei ancora sicuro? Parti con i buildpack e aggiungi un Dockerfile quando ti serve qualcosa che non possono fare.

Domande frequenti

Mi serve un Dockerfile per fare il deploy di un container?

No. I buildpack costruiscono un'immagine container direttamente dal tuo codice sorgente, senza un Dockerfile nel repository. Puoi anche fare il deploy di un'immagine già pronta da un registry.

I buildpack sono meglio di un Dockerfile?

Nessuno dei due è migliore in assoluto. I buildpack richiedono meno manutenzione per le app standard in linguaggi supportati, mentre un Dockerfile ti dà il pieno controllo sull'immagine e funziona con qualsiasi stack.

Posso usare un Dockerfile multi-stage su Nodion?

Sì. I Dockerfile multi-stage funzionano. Non c'è un selettore di stage, quindi l'immagine che gira è quella dell'ultimo stage.

Su quale porta deve stare in ascolto la mia app?

Con i buildpack, sulla variabile d'ambiente PORT che Nodion imposta. Con un Dockerfile, Nodion non imposta PORT: mettiti in ascolto sulla porta del processo web, presa da EXPOSE o impostata nella scheda Processes, e su tutte le interfacce.

Dai al tuo agente un cloud tutto suo.

Fino a 15 € di credito quando ti registri.

Continua con GitHub

oppure con l'email

Resta aggiornato.

Novità sul prodotto, niente spam. Puoi annullare l'iscrizione quando vuoi.