Personalizzare un'immagine Docker per eseguire la propria app Web

Completato

L'hub Docker è un'eccellente fonte di immagini per iniziare subito a sviluppare le proprie app in contenitori. È possibile scaricare un'immagine che offre le funzionalità di base necessarie quindi costruire la propria applicazione su di essa per creare una nuova immagine personalizzata. È possibile automatizzare i passaggi di questo processo scrivendo un Dockerfile.

Nello scenario del negozio di abbigliamento online l'azienda ha deciso che Docker è la soluzione ottimale. Il passaggio successivo è determinare il modo migliore per aggiungere ai contenitori le applicazioni Web. L'azienda prevede di creare molte delle app usando ASP.NET Core. Si è notato che Docker Hub contiene un'immagine di base che include questo framework. A titolo di verifica, si vuole usare questa immagine di base e aggiungere il codice per una delle app Web per creare una nuova immagine personalizzata. Si vuole anche che questo processo sia facilmente ripetibile affinché venga automatizzato ogni volta che viene rilasciata una nuova versione dell'app Web.

In questa unità: come creare un'immagine Docker personalizzata e automatizzare il processo scrivendo un Dockerfile.

Creare un'immagine personalizzata con un Dockerfile

Per creare un'immagine Docker contenente l'applicazione, in genere si parte dall'identificazione di un'immagine di base a cui si aggiungono file e informazioni di configurazione. Il processo di identificazione di un'immagine di base adatta inizia in genere con una ricerca di immagini in Docker Hub. Si desidera un'immagine che contenga già un framework applicazione e tutti gli strumenti e le utilità di una distribuzione Linux, come Ubuntu o Alpine. Ad esempio, se si ha un'applicazione ASP.NET Core che si vuole inserire in pacchetto in un contenitore, Microsoft pubblica un'immagine denominata mcr.microsoft.com/dotnet/core/aspnet che contiene già il runtime di ASP.NET Core.

Un'immagine può essere personalizzata avviando un contenitore con l'immagine di base e apportando modifiche a quell'immagine. Le modifiche in genere implicano alcune attività, ad esempio la copia dei file nel contenitore dal file system locale e l'esecuzione di vari strumenti e utilità per la compilazione del codice. Al termine, si usa il comando docker commit per salvare le modifiche in una nuova immagine.

Completare manualmente il processo descritto sopra richiede molto tempo ed è a rischio di errore. Si può creare uno script usando un linguaggio di script come Bash, ma Docker offre un modo più efficace di automatizzare la creazione delle immagini usando un Dockerfile.

Un Dockerfile è un file di testo normale che contiene tutti i comandi necessari per creare un'immagine. I Dockerfile vengono scritti in un linguaggio di script minimo progettato per la creazione e la configurazione delle immagini. Inoltre si documentano le operazioni necessarie per creare un'immagine partendo da un'immagine di base.

L'esempio seguente illustra un Dockerfile che crea un'applicazione .NET 6.0 e la aggiunge a un pacchetto in una nuova immagine.

FROM mcr.microsoft.com/dotnet/sdk:6.0
WORKDIR /app
COPY myapp_code .
RUN dotnet build -c Release -o /rel
EXPOSE 80
WORKDIR /rel
ENTRYPOINT ["dotnet", "myapp.dll"]

In questo file vengono eseguite le operazioni seguenti:

Comando Azione
FROM Scarica l'immagine specificata e crea un nuovo contenitore basato su questa immagine.
WORKDIR Imposta la directory di lavoro corrente nel contenitore, usata dai comandi successivi.
COPY Copia i file dal computer host nel contenitore. Il primo argomento (myapp_code) è un file o cartella nel computer host. Il secondo argomento (.) specifica il nome del file o della cartella da usare come destinazione nel contenitore. In questo caso, la destinazione è la directory di lavoro corrente (/app).
RUN Esegue un comando nel contenitore. Gli argomenti per il comando RUN sono i comandi della riga di comando.
EXPOSE Crea una configurazione nella nuova immagine che specifica le porte che devono essere aperte quando è in esecuzione il contenitore. Se il contenitore esegue un'app Web, è normale esporre la porta 80.
ENTRYPOINT Specifica l'operazione che il contenitore deve eseguire all'avvio. In questo esempio esegue l'app appena creata. Specificare il comando da eseguire e i relativi argomenti come matrice di stringhe.

Per convenzione, le applicazioni destinate a essere incluse in pacchetti come immagini Docker normalmente hanno un Dockerfile situato nella radice del proprio codice sorgente, quasi sempre denominato Dockerfile.

Il comando docker build crea una nuova immagine eseguendo un Dockerfile. La sintassi di questo comando ha diversi parametri:

  • Il flag -f indica il nome del Dockerfile da usare.
  • Il flag -t specifica il nome dell'immagine che deve essere creata, in questo esempio myapp:v1.
  • L'ultimo parametro, ., specifica il contesto di compilazione per i file di origine per il comando COPY: il set di file nel computer host necessario durante il processo di compilazione.
docker build -t myapp:v1 .

Dietro le quinte, il comando docker build crea un contenitore, esegue comandi al suo interno e quindi esegue il commit delle modifiche in una nuova immagine.