Come containerizzare un’applicazione usando Docker

how to containerize an application using docker blog banner

La maggior parte dei progetti di sviluppo coinvolge un ampio ventaglio di ambienti. Ci sono gli ambienti di produzione, di sviluppo, QA, staging e poi gli ambienti locali di ogni sviluppatore. Mantenere questi ambienti sincronizzati in modo che il progetto venga eseguito allo stesso modo (o che venga semplicemente eseguito) in ogni ambiente può essere una bella sfida.

I motivi di una possibile incompatibilità sono molti, ma l’uso di Docker ti aiuterà a eliminarne la maggior parte e in questo articolo spiegheremo come containerizzare un’applicazione e analizzeremo Docker, i container di applicazioni e come l’uso di questi strumenti possa aiutarti a eseguire la tua applicazione ovunque sia possibile installare Docker, evitando così problemi di compatibilità.

Che cos’è un container di applicazioni?

Un container di applicazioni è un pacchetto leggero e indipendente che include un’applicazione e tutte le sue dipendenze, comprese le librerie, gli ambienti di esecuzione e i file di configurazione. Un container contiene, in un ambiente isolato, tutto ciò che serve all’applicazione per funzionare in modo efficiente. Sono progettati per funzionare su qualsiasi sistema operativo e hardware compatibile, indipendentemente dalle differenze delle distribuzioni dei sistemi operativi (OS), e condividendo il kernel del sistema operativo dell’host. Ciò consente di eseguire più applicazioni o servizi isolati su un singolo host senza la necessità di un sistema operativo completo per ciascuna applicazione.

I container di applicazioni differiscono dalla virtualizzazione tradizionale in termini di l’allocazione delle risorse, sistema operativo, isolamento e scalabilità. I container condividono risorse come CPU, memoria e storage a livello di sistema operativo, consumando meno risorse rispetto alle virtual machine (VM) che richiedono un sistema operativo completo per ogni istanza. Per questo motivo, i container si avviano in pochi secondi, a differenza delle virtual machine che possono richiedere minuti. Questa caratteristica rende i container più scalabili delle virtual machine. Un aspetto in cui le macchine virtuali brillano, tuttavia, è che forniscono un isolamento molto più forte tra le istanze rispetto ai container, perché ogni macchina virtuale esegue il proprio sistema operativo.

Perché containerizzare le applicazioni?

La containerizzazione delle applicazioni offre una grande quantità di vantaggi che rendono più facili da gestire alcune delle sfide dello sviluppo, della distribuzione e delle operazioni del software. Tra i principali motivi per cui è necessario containerizzare un’applicazione vi sono:

  • Portabilità: La containerizzazione fornisce un ambiente di runtime coerente mettendo un’applicazione in un pacchetto insieme alle sue dipendenze e alla sua configurazione. Questo garantisce un comportamento coerente sia che il container sia in esecuzione sul computer di uno sviluppatore sia su una piattaforma in cloud.
  • Scalabilità: I container consentono di distribuire, applicare patch e scalare rapidamente le applicazioni. Gli orchestratori di container possono eseguire uno scaling intelligente, eseguendo la giusta quantità di istanze applicative necessarie per i carichi applicativi utilizzati, tenendo conto delle risorse disponibili.
  • Produttività: I container offrono un ambiente prevedibile e coerente, indipendentemente dal luogo in cui vengono eseguiti. Invece di impostare manualmente ogni ambiente, gli sviluppatori possono di solito eseguire un singolo comando per avviare un container, che costruirà e avvierà l’ambiente per loro.
  • Flessibilità: L’efficienza dei container consente di suddividere facilmente un’applicazione in microservizi più piccoli e distribuibili, senza il sovraccarico di risorse dovuto all’esecuzione di più server fisici o di virtual machine.

Introduzione a Docker

Docker è stato lanciato nel 2013 come piattaforma open-source che semplifica il processo di creazione, esecuzione, gestione e distribuzione delle applicazioni grazie alla containerizzazione. Per molti team di sviluppo, si tratta di uno strumento fondamentale nei loro flussi di lavoro legati allo sviluppo e alla distribuzione del software, che consente agli sviluppatori di mettere le applicazioni in pacchetti con le loro dipendenze, utilizzando container leggeri e trasferibili facilmente.

Diamo una rapida occhiata ad alcuni componenti chiave di Docker per avere un’idea del suo funzionamento.

Dockerfile

Un Dockerfile è un file di testo che contiene le istruzioni per costruire un’immagine Docker. Specifica quale immagine Docker utilizzare come base, la posizione del codice sorgente dell’applicazione che verrà fornito con l’immagine, le librerie, i pacchetti e le altre dipendenze necessarie per l’esecuzione dell’applicazione. Docker legge questo file ed esegue le istruzioni in esso contenute per costruire l’immagine Docker.

Immagini Docker

Un’immagine Docker è un modello read-only che contiene il codice sorgente e le dipendenze dell’applicazione e che serve come base per i container Docker. Le immagini Docker vengono create con un Dockerfile e possono essere sottoposte al controllo delle versioni (versioning), archiviate in registri e condivise con altri. Le immagini Docker utilizzano un’architettura a strati, dove ogni strato rappresenta una modifica all’immagine. Poiché la stratificazione è legata direttamente a ogni comando in un file Docker, ogni istruzione può produrre un nuovo strato

Container Docker

Un container Docker è un’istanza in esecuzione di un’immagine Docker. Come altri container, vengono eseguiti in ambienti isolati su un sistema host e sono leggeri, si avviano rapidamente e garantiscono un comportamento coerente indipendentemente dal sistema host su cui vengono eseguiti.

Come containerizzare un’applicazione utilizzando Docker

È possibile containerizzare molti tipi di applicazioni, comprese le applicazioni frontend e backend. Più avanti vedremo come è possibile containerizzare una semplice applicazione web sviluppata con Python Flask. Sebbene esistano altri linguaggi e applicazioni che possono essere organizzati in pacchetti con Docker, per i nostri esempi utilizzeremo Python Flask.

Prerequisiti per la containerizzazione tramite Docker

Poiché la containerizzazione di un’applicazione inserisce tutto il suo codice e le sue dipendenze in un container, non ci sono molti requisiti, a parte i seguenti:

  • Devi avere installato Docker. Puoi trovare i pacchetti di installazione per Linux, Mac o Windows qui.
  • Crea una cartella di progetto per contenere tutti i file dell’applicazione. Nell’esempio che segue, utilizzeremo solo tre file.
  • Potresti voler installare i linguaggi di programmazione e le librerie utilizzate in locale per testare l’applicazione prima di containerizzarla. Tuttavia, ciò non è del tutto necessario, poiché l’installazione avverrà nel container dell’applicazione e Docker si occuperà di questa parte.

Comprendere il codice dell’applicazione e le sue dipendenze

Per il nostro esempio, creeremo una semplice applicazione in Python Flask. Ecco come apparirà la cartella del progetto:

my_flask_app/
    - app.py
    - requirements.txt

La nostra applicazione è composta da due file: app.py, che contiene il codice dell’applicazione web, e requirements.txt, un file che Python usa per installare le dipendenze. Ecco il contenuto di app.py con alcuni commenti che spiegano il ruolo di ogni sua parte:

# Importazione del modulo Python Flask
from flask import Flask


# Il costruttore di Flask utilizza il nome del modulo corrente
app = Flask(__name__)


# La funzione route() è un decorator,
# Lega un URL a una funzione associata
@app.route('/')
def hello_world():
return 'Hello World'


# Se il file viene eseguito direttamente
# Eseguire l'applicazione Flask
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

Non c’è molto nel filerequirements.txt. Semplicemente elenca Flask come dipendenza:

Flask==2.3.2

Guida passo per passo alla containerizzazione di un’applicazione

Ora che abbiamo un’applicazione da containerizzare, il passo successivo è la creazione di un Dockerfile che contenga le istruzioni per la creazione dell’immagine Docker. 

Creare il Dockerfile

Per prima cosa, crea un Dockerfile vuoto nel progetto. Questo file non ha estensione. La cartella del progetto dovrebbe avere questo aspetto:

my_flask_app/
    - app.py
    - Dockerfile
    - requirements.txt

Ecco il contenuto del file Dockerfile:

FROM python:3.10


COPY . /app
WORKDIR /app


RUN pip install -r requirements.txt
EXPOSE 5000


CMD ["python3", "app.py"]

Ecco cosa significa tutto questo:

  • FROM: Definisce il container che useremo come container di base. Puoi trovare un’ampia selezione di container di base con cui iniziare su Docker Hub.
  • COPY: Quando il container viene realizzato, i file del nostro progetto, rappresentati dal punto, saranno copiati in una cartella /app all’interno del container.
  • WORKDIR: Questo indica a Docker dove eseguire il comando in fondo al nostro file, che è la cartella in cui abbiamo copiato il nostro progetto.
  • RUN: L’istruzione RUN indica a Docker un comando da eseguire durante la creazione del container. Questo comando viene eseguito durante la creazione dell’immagine, non all’avvio del container. Qui è dove chiediamo di installare le dipendenze presenti nel file requirements.txt.
  • EXPOSE: Questo indica a Docker la porta su cui il container dovrà essere in ascolto, che è la porta su cui verrà eseguita la nostra applicazione Flask.
  • CMD: Questo indica a Docker i comandi che verranno eseguiti all’avvio del container e che eseguiranno l’applicazione Flask. L’istruzione CMD fornisce le impostazioni predefinite per l’esecuzione di un container e può essere sovrascritta durante l’esecuzione di Docker.

Creare l’immagine Docker

Ora che abbiamo creato il Dockerfile possiamo creare l’immagine Docker eseguendo questo comando nella nostra cartella del progetto:

docker build -t flask-app .

Nel comando, -t sta per tag e contrassegna l’immagine con un nome, flask-app è il nome che daremo all’immagine e l’opzione . definisce il contesto di compilazione, che sarà la cartella corrente. Una volta eseguito il comando, Docker costruirà la vostra immagine e vedrete un output come questo:


Docker Image Output

Esecuzione del container Docker

Ora che l’immagine Docker è stata creata, è possibile eseguire il container con il seguente comando nella cartella del progetto:

docker run -it -p 5000:5000 flask-app

In questo comando, -it indica a Docker di eseguire il container in modalità interattiva, il che significa che sarà possibile interagire con la shell del container e assegnare una tty al container, che ti fornirà una console basata su testo. Tuttavia, l’uso di -it quando si esegue l’applicazione Flask non è sempre necessario, poiché non si tratta di uno strumento a riga di comando che richiede un terminale interattivo. Il flag -p specifica la mappatura delle porte del container. Il primo 5000 è la porta del computer host che si vuole mappare sulla porta del container. Il secondo 5000 è la porta del container. E flask-app è il nome dell’immagine che abbiamo appena creato e che vogliamo eseguire.

L’output nel terminale dopo aver eseguito il comando sarà simile a questo:


Immagine di esempio del container E quando andrai su http://localhost:5000/ potrai vedere l’applicazione Flask di base. 

Best practice per la containerizzazione con Docker

Sebbene la containerizzazione di un’applicazione con Docker offra innumerevoli vantaggi per lo sviluppo e la distribuzione delle applicazioni, è importante seguire le best practice per trarne vantaggio. Ecco alcune regole importanti da seguire:

  • Utilizza un’immagine di base minima: Scegli l’immagine di base più leggera possibile, come Alpine Linux, per ridurre le dimensioni dell’immagine finale, diminuire il consumo di risorse e velocizzare la creazione.
  • Utilizza costruzioni a più fasi: Costruisci e compila in un’unica fase, quindi copia solo gli artefatti necessari nella fase finale per ridurre le dimensioni dell’immagine finale.
  • Riduci al minimo i livelli: Riduci il numero di livelli dell’immagine combinando i comandi in un’unica operazione RUN perché ogni livello aggiunge overhead.
  • Rimuovi i file non necessari: Rimuovi i file temporanei, le cache e gli artefatti di compilazione dopo l’installazione delle dipendenze o la creazione dell’applicazione, per ridurre le dimensioni dell’immagine.
  • Esegui container stateless: Memorizza i dati persistenti al di fuori del container in database, object storage o in un altro sistema di archiviazione esterno, in modo da poter interrompere il container senza perdere i dati.
  • Tagga le tue immagini: I tag aiutano a gestire le versioni delle tue immagini. L’uso di tag unici per le distribuzioni consente di scalare rapidamente un cluster di produzione a molti nodi.
  • Applica le patch ai tuoi container: Il patching e l’aggiornamento dei container è un modo proattivo per migliorare la sicurezza e ridurre le minacce.

Docker: Uno strumento essenziale per lo sviluppo moderno

La containerizzazione con Docker ha rivoluzionato lo sviluppo delle applicazioni. Le applicazioni containerizzate offrono notevoli vantaggi, tra cui portabilità, scalabilità, produttività, efficienza e flessibilità. Docker ha reso semplice questo processo fornendo un approccio alla containerizzazione standardizzato e facile da usare.

L’adozione di Docker, se accompagnata dall’uso delle best practice per la containerizzazione, può migliorare lo sviluppo, la distribuzione e la gestione delle applicazioni moderne. Fornendo un ambiente di runtime coerente, i container consentono agli sviluppatori di sviluppare applicazioni una sola volta e di eseguirle ovunque, semplificando il processo in vari ambienti. La scalabilità dei container consente una rapida distribuzione e la possibilità di riduzione delle applicazioni in microservizi più piccoli e distribuibili.

Docker, piattaforma leader per la containerizzazione, semplifica il processo di creazione, esecuzione, gestione e distribuzione di applicazioni containerizzate, imponendosi così come uno strumento essenziale per lo sviluppo di software moderno.

Passi successivi

La creazione di un team IT efficiente ed efficace richiede una soluzione centralizzata che funga da principale strumento di erogazione dei servizi. NinjaOne consente ai team IT di monitorare, gestire, proteggere e supportare tutti i dispositivi, ovunque essi si trovino, senza la necessità di una complessa infrastruttura locale.

Scopri di più su  NinjaOne Endpoint Management, fai un  tour dal vivo o  inizia la tua prova gratuita della piattaforma NinjaOne.

Ti potrebbe interessare anche

Vuoi diventare un Ninja dell’IT?

Scopri come NinjaOne può aiutarti a semplificare le operazioni IT.
Guarda una demo×
×

Guarda NinjaOne in azione!

Inviando questo modulo, accetto La politica sulla privacy di NinjaOne.

Inizia una prova gratuita della piattaforma RMM numero 1 su G2

Non è richiesta alcuna carta di credito e si ha accesso completo a tutte le funzionalità.

Termini e condizioni NinjaOne

Cliccando sul pulsante “Accetto” qui sotto, dichiari di accettare i seguenti termini legali e le nostre condizioni d’uso:

  • Diritti di proprietà: NinjaOne possiede e continuerà a possedere tutti i diritti, i titoli e gli interessi relativi allo script (compreso il copyright). NinjaOne ti concede una licenza limitata per l’utilizzo dello script in conformità con i presenti termini legali.
  • Limitazione d’uso: Puoi utilizzare lo script solo per legittimi scopi personali o aziendali interni e non puoi condividere lo script con altri soggetti.
  • Divieto di ripubblicazione: In nessun caso ti è consentito ripubblicare lo script in una libreria di script appartenente o sotto il controllo di un altro fornitore di software.
  • Esclusione di garanzia: Lo script viene fornito “così com’è” e “come disponibile”, senza garanzie di alcun tipo. NinjaOne non promette né garantisce che lo script sia privo di difetti o che soddisfi le tue esigenze o aspettative specifiche.
  • Assunzione del rischio: L’uso che farai dello script è da intendersi a tuo rischio. Riconosci che l’utilizzo dello script comporta alcuni rischi intrinseci, che comprendi e sei pronto ad assumerti.
  • Rinuncia e liberatoria: Non riterrai NinjaOne responsabile di eventuali conseguenze negative o indesiderate derivanti dall’uso dello script e rinuncerai a qualsiasi diritto legale o di equità e a qualsiasi rivalsa nei confronti di NinjaOne in relazione all’uso dello script.
  • EULA: Se sei un cliente NinjaOne, l’uso dello script è soggetto al Contratto di licenza con l’utente finale (EULA) applicabile.