In questo articolo, Docker Hub – creazione di container e immagini personalizzate, vediamo come utilizzare Docker Hub per fare il pull e il push di immagini, vedremo come creare e cancellare container

In questo articolo, Docker Hub – Pull di immagini ufficiali e creazione di container, vediamo come utilizzare Docker Hub per fare il pull e il push di immagini, vedremo come creare e cancellare container

Cos’è Docker Hub

Docker Hub è il servizio di registry ufficiale offerto da Docker per la condivisione e l’archiviazione di immagini. Funziona come un repository online dove è possibile trovare immagini già pronte, create dalla community o da sviluppatori ufficiali, ma anche pubblicare immagini personalizzate realizzate in locale. Grazie a Docker Hub, gli sviluppatori possono collaborare in modo semplice e sicuro, distribuendo le proprie applicazioni in forma di container. Per utilizzare Docker Hub è necessario registrarsi gratuitamente sul sito ufficiale (https://hub.docker.com). Dopo aver creato un account, è possibile creare repository pubblici o privati, caricare immagini tramite il comando docker push e accedervi in qualunque momento tramite il comando docker pull, rendendo così più efficiente la gestione del ciclo di vita delle applicazioni containerizzate.

La home page di Doker Hub presenta una richiesta di registrazione:

E’ possibile eseguire una registrazione classica o utilizzare gli account Google o GitHub. Dopo aver eseguito la registrazione, un banner ci chiede di confermare l’e-mail ricevuta e di scegliere un piano tariffario. Per i nostri scopi va bene il piano gratuito:

Dopo aver eseguito l’accesso vedremo una pagina simile a questa in basso:

Nella sezione repositories vedremo tutte le nostre immagini. Come vedremo sarà possibile creare immagini direttamente dalla piattaforma oppure fare il push di un’immagine. Tutte le nostre immagini saranno visibili all’interno di Repositories.

La sezione Explore invece, quella più importante, contiene tutte le repository pubbliche ufficiali e non ufficiali (realizzate da utenti della community) per le quale è possibile fare il pull (il download), renderle personalizzate, creare delle istanze di esse (container)

Per ciascuna immagina avremo, nella sezione overview, una descrizione dettagliata, i comandi per lanciarla ecc. mentre, nella sezione tags, potremo vedere le alternative, dal punto di vista del versioning, a quella immagine. Nelle immagini seguenti ho scritto “Python” come input di ricerca ottenendo:

Che è l’immagine ufficiale di Python con diverse tags disponibili.

Prima immagine: Hello-World

Ci proponiamo ora di fare il pull (download) della nostra prima immagine: Hello-World.

Pull dell’immagine

Questo step può essere eseguito in due modi:

  1. Direttamente da Docker Desktop
  2. Da Docker Hub

Primo metodo: da Docker Desktop

dal menù laterale si clicca su Docker Hub, si cerca l’immagine

Si clicca sull’immagine e poi, in alto a destra si clicca su pull. In basso a destra la piattaforma ci informa che l’immagine è stata scaricata:

In effetti se clicchiamo su images vediamo l’immagine appena scaricata:

Le info relative all’immagine scaricata sono:

  • nome dell’immagine
  • tag: abbiamo già detto che rappresenta la versione. Nel nostro caso “latest” è l’ultima versione. Fare il pull della versione “latest” di un’immagine non è sempre una buona pratica poichè le ultime versioni potrebbero non essere prive di vulnerabilità per cui si dovrebbe scegliere sempre una versione stabile e sicura
  • Image ID: è un identificatore univoco che rappresenta in modo specifico un’immagine costruita in un determinato momento. Si tratta di un hash generato in base al contenuto dell’immagine stessa, quindi ogni volta che si crea un’immagine con contenuti differenti, anche di poco, il suo ID cambierà. Docker assegna a ogni immagine un ID calcolato come un digest SHA-256 del contenuto dell’immagine. Questo hash garantisce integrità e unicità: due immagini con contenuti identici avranno lo stesso ID, anche se hanno nomi/tag diversi. L’ID dell’immagine è una stringa esadecimale di 64 caratteri, che rappresenta l’hash SHA-256 completo ma nei comandi Docker, spesso viene mostrata solo una troncatura dei primi 12 caratteri dell’hash completo, per semplificare la lettura. Tuttavia, è importante sapere che questa è solo una forma abbreviata, utile per l’interfaccia CLI, mentre internamente Docker utilizza sempre l’hash completo SHA-256 a 64 caratteri per identificare in modo univoco l’immagine. Di fatto l’ID serve a riferirsi all’immagine in operazioni CLI come docker rmi, docker inspect, docker history, ecc
  • Created: data di creazione
  • Sixe: dimensione
  • Actions: da qui è possibile creare un container basato sull’immagine, eliminare l’immagine, fare il push (upload nel repository di docker hub) ecc

Secondo Metodo: Da CLI

Il secondo metodo è quello che prevede l’utilizzo della CLI ( power shell) e fare il pull da Docker Hub.

Dopo aver ricercato l’immagine e cliccato su di essa, di solito in alto a destra viene proposto il comando di pull:

basta cliccare su copy, aprire PowerShell e cliccare con il tasto detro del mouse al prompt dei comandi e premere invio. Ci da le info sul pull e scarica l’immagine:

Primo Container

Come facciamo a mandare in run la nostra prima immagine? Dobbiamo creare un container cioè un’istanza della nostra immagine.

Anche in questo caso possiamo utilizzare due metodi:

  • da Docker Desktp
  • da CLI

Primo metodo: da Docker Desktop

Occorre cliccare sul simbolo Run in corrispondenza dell’immagine e visualizzeremo la seguente maschera:

Cliccando sulla freccia del drop-down menu

potremo scegliere:

  • nome del container: scriviamo ad esempio primo_container_HelloWorld
  • Le porte: In questo caso non ne abbiamo bisogno ma, in generale, la mappatura delle porte è un concetto fondamentale nella gestione dei container Docker, specialmente quando si eseguono applicazioni che devono essere accessibili dall’esterno (ad esempio: server web, API REST, database, ecc.). Ogni container Docker è isolato dal sistema host e dagli altri container. Quando un’applicazione all’interno del container espone un servizio (ad esempio, un server HTTP sulla porta 80), quella porta è accessibile solo dall’interno del container a meno che non venga esplicitamente “mappata” verso l’esterno. La mappatura delle porte consiste nell’individuare una porta host sulla quale mappare la porta relativa al servizio specifico che viene esposta dal container.
    • la sintassi è: docker run -p <porta_host>: <porta_container> nome_immagine
    • esempio: Supponiamo di avere un’applicazione web all’interno del container che ascolta sulla porta 80. Per renderla accessibile dalla porta 8080 del sistema host, si utilizza: docker run -p 8080:80 nome_immagine
  • I volumi: ne abbiamo già parlato nell’articolo Docker. In questo caso non occorre la persistenza dei dati quindi lasciamo il campo vuoto ma , in generale, se un’applicazione nel container scrive dati ad esempio su /app/data, si può montare una cartella dal proprio host: docker run -v $(pwd)/dati:/app/data nome_immagine. In questo modo:
    • I file scritti da /app/data saranno salvati in ./dati del tuo sistema host.
    • Se il container viene eliminato, i dati non andranno persi.
    • Puoi anche modificare i file sull’host e vederli aggiornati nel container (utile per sviluppo).
  • Le variabili d’ambiente: Le variabili d’ambiente permettono di passare configurazioni al container al momento dell’esecuzione, senza dover modificare il codice o l’immagine. Sono fondamentali per rendere il container più riutilizzabile in diversi contesti (sviluppo, test, produzione). Nel nostro caso non serve

Adesso, cliccando su “RUN” va in esecuzione il nostro primo container:

Cliccando su Containers nella barra laterale possiamo vedere che è stato creato il nostro primo container:

Secondo metodo: da CLI

Da PowerShell possiamo creare e contestualmente mandare in run un altro container basato sulla stessa immagine.

La sintassi completa è:

docker run \
--name nome_container \
-p porta_host:porta_container \
-v /percorso/host:/percorso/container \
-e NOME_VARIABILE=valore \
--env-file percorso_file.env \
-d \
--restart always \
nome_immagine:tag

dove:

OpzioneDescrizione
--name nome_containerAssegna un nome leggibile al container
-p x:yMappa la porta y del container sulla porta x dell’host
-v /host:/containerMonta un volume tra host e container
-e VAR=valoreImposta una variabile d’ambiente
--env-file file.envCarica variabili da un file .env
-dEsegue il container in background (detached mode)
--restart alwaysRiavvia automaticamente il container in caso di errore o reboot
nome_immagine:tagSpecifica l’immagine Docker da usare e il suo tag (es. nginx:latest)

Nel nostro caso posso semplicemente scrivere ed eseguire il comando in cui specifico l’azione (run), il nome del container (–name secondo_container_HelloWorld), l’immagine e la versione dalla quale creare il container (hello-world:latest):

docker run --name secondo_container_HelloWorld hello-world:latest

Ottengo ovviamente lo stesso output:

Ovviamente nel mio Docker Desktop visualizzerò il mio secondo container:

Questo ci dice che posso creare diverse istanze della stessa immagine completamente isolate e autosufficienti

Help di Docker

Docker mette a disposizione diversi comandi (Comandi comuni, Comandi per la gestione di immagini e container ecc) e le relative opzioni globali

Per visualizzare la lista dei comandi occorre digitare ed eseguire:

docker --help

mentre se volessi informazioni specifiche su un comando la sintassi è: docker COMMAND --help

esempio: informazioni sul comando ps:

docker ps --help

Questo comando fa una lista dei container. Se lo proviamo otteniamo:

Non visualizziamo i nostri container. Per visualizzali occorre specificare l’opzione -a (oppure –all):

Rimozione di un container

Anche in questo caso possiamo fare riferimento ai due metodi (da Docker Desktop o da CLI).

Primo metodo: Da Docker Desktop

Molto semplice: occorre solo cliccare sull’icona “cestino” di quel container

Secondo metodo: da CLI

Dobbiamo cercare un comando per la cancellazione dei container quindi, aiutiamoci con l’help e vediamo che esiste il comando rm:

facendo l’help del comando rm:

scopriamo che ci sono diversi aliases e che possiamo specificare o il nome o l’ID del container quindi possiamo lanciare il comando:

docker rm <ID_o_nome_container> //sostituire con l'ID del container

Dopo aver eseguito il comando e rila nciato docker ps -a vedremo che anche il secondo container è stato rimosso

Cancellazione di un’immagine

Dopo aver cancellato i nostri container vediamo che l’immagine dalla quale le due istanze sono partite rimane ancora, come è giusto che sia.

Ci proponiamo di cancellare l’immagine hello-world. Per fare ciò facciamo riferimento sempre all’help e vediamo che il comando necessario è rmi. Facciamo l’help di rmi:

e vediamo che il comando è simile a quello per rimuovere i container:

Sempre attraverso l’help di docker conosciamo anche il comando per visualizzare la lista di tutte le immagini:

docker images

Per cui dopo aver eseguiro questo comando:

Conosco l’IMAGE ID di hello-world e posso lanciare il comando di cancellazione:

docker rmi <ID_o_nome_immagine>// nel mio caso il comando è: docker rmi c41088499908

L’immagine è stata rimossa. Potrete verificarlo o rilanciando il comando docker images oppure da Docker Desktop

Creazione di un Web Server Apache – PHP

A questo punto abbiamo a disposizione la teoria per poter sfruttare Docker per realizzare le nostre applicazioni. In questo paragrafo ci proponiamo il seguente obiettivo: Avere a disposizione un Web Server Apache che esegua i nostri script PHP

Con Docker il tutto si traduce nei seguenti step:

  1. Ricerca dell’immagine
  2. Pull dell’immagine
  3. Creazione di una Working directory
  4. Creazione di uno script PHP di prova
  5. Creazione di un container
  6. Test dell’applicazione

1. Ricerca dell’immagine

Da Docker Hub ricerco l’immagine ufficiale php digitando semplicemente php.

A me serve una versione che integri il Web Server Apache per cui cliccando su Tags e scriviamo nel campo della ricerca 8.4.6-apache (l’ho ottenuto scrivendo 8.2, 8.3, fino ad arrivare all’ultima versione poi -apache) otteniamo la versione 8.4.6-apache-bullseye

2. Pull dell’immagine

Decidiamo di utilizzare questa immagine. Facciamo il pull dell’immagine: in PowerShell scriviamo il comando per il pull:

Verifichiamo che l’immagine sia presente (o da riga di comando o da Docker Desktop)

3. Creazione di una Working Directory

Sul desktop (o in una qualsiasi altra directory) creare una cartella (ad es: Applicazioni con Docker). Al suo interno creiamo una nuova directory (la nomino ad esempio con il nome dell’immagine: 8.4.6-apache-bullseye).

4. Creazione di uno script PHP di prova

Apro VSC in questa directory. E’utile collegare VSC a Docker installando l’estensione Docker. Dopo averlo fatto, creare il file di esempio index.php:

5. Creazione di un container

Facciamo riferimento al paragrafo descritto in precedenza per la creazione dei container.

Poichè sfruttiamo l’immagine originale e non abbiamo necessità di estensioni o di funzionalità aggiuntive non è necessario un Dockerfile ma possiamo semplicemente creare e mandare in run il container facendo alcune considerazioni preliminari:

  • scegliamo un nome: (ad. es: mio_php_apache)
  • decidiamo di eseguire il container in modalità detached (background) in modo da avviarlo senza mantenerlo collegato al terminale: il processo del container continua a essere eseguito “in sottofondo”, mentre l’utente può continuare a usare il terminale per altre operazioni. dobbiamo usare allora l’opzione -d
  • Dobbiamo mappare la porta 80 del Server Web che funziona all’interno del container con una porta a scelta dell’host in modo che sia raggiungibile dall’esterno. Scegliamo ad esempio la porta 8080 quindi nel nostro comando scriveremo: -p 8080:80
  • Dovremo montare la nostra cartella attuale come root del server Apache. Questo significa che Il Web Server eseguirà gli script che noi inseriremo nella nostra directory di progetto. Per fare questo la sintassi è: -v /percorso/host:/percorso/container. Quindi se faremo partire il comando dalla directory di progetto, senza specificare il percorso completo potremo scrivere semplicemente punto (.). Il singolo punto (.) restituisce la directory corrente. Non sappiamo qual è la root di apache. Per conoscerla abbiamo come al solito due metodi, da Docker Hub o da CLI

Metodo 1: da Docker Hub

Cliccando sull’immagine avremo diverse informazioni sulla stessa tra le quali i layer di cui è costituita. scendendo in basso vedremo che la WORKING DIRECTORY (WORKDIR) è: /var/www/html

Metodo 2: da CLI

Utilizzando il comando:

docker inspect <ID_o_nome_immagine> //nel mio caso docker inspect 90ec40a62b44

A questo punto sappiamo che nel comando di creazione del container dobbiamo scrivere -v . : /var/www/html

  • decidiamo di non farlo partire in automatico (quindi non utilizziamo –restart always)
  • non abbiamo bisogno di variabili d’ambiente
  • dovremo completare il comando con immagine:tag

Scriviamo allora il comando di creazione del nostro container. Lo possiamo fare o da PowerShell o direttamente dal terminale di VSC visto che siamo nella directory corretta:

docker run -d --name php_apache -p 8080:80 -v .:/var/www/html php:8.4.6-apache-bullseye

Verifichiamo che il container sia stato creato:

6. Test dell’applicazione

Non ci resta altro che testare la nostra applicazione. Possiamo farlo da Docker Desktop cliccando direttamente sul link offerto nella sezione delle porte:

oppure aprendo il browser e digitando nella barra degli indirizzi: localhost:8080

In entrambe i casi visualizzeremo la nostra pagina PHP di prova:

Conclusioni

In questo articolo abbiamo visto come usare Docker-Hub e sfruttare un’immagine ufficiale per realizzare un’applicazione. Nelle prossime guide vedremo come personalizzare le immagini per creare applicazioni più complesse e come renderle pubbliche su Docker Hub

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Una risposta a “Docker Hub – Pull di immagini ufficiali e creazione di container”

  1. […] la nostra struttura. Fare riferimento alla guida precedente all’interno della quale avevamo già creato una directory per i nostri progetti […]