I comandi base di Docker

Nel precedente articolo dedicato a Docker abbiamo completato l’installazione, se te lo sei perso lo trovi qui. Ora che abbiamo tutto pronto, è tempo di sporcarci le mani. In questa sezione, eseguiremo un contenitore sul nostro sistema e avremo un assaggio dei primi comandi.

Per iniziare, eseguiamo quanto segue nel nostro terminale:

$ sudo docker pull ubuntu

Il comando pull recupera l’ immagine di ubuntu dal repository in cloud Docker Hub e la salva sul nostro sistema. Puoi usare il comando docker images per vedere un elenco di tutte le immagini presenti sul tuo sistema.

$ sudo docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                 latest              c51f86c28340        4 weeks ago         1.109 MB

Non avendo specificato un tag, viene automaticamente scaricata l’ultima versione disponibile

Ora proviamo ad eseguire un contenitore Docker basato sull’ immagine appena scaricata. Per farlo useremo il comando docker run che abbiamo già utilizzato nell’articolo introduttivo.

$ sudo docker run ubuntu

Quando chiamiamo il comando docker run, il client Docker trova l’immagine, carica il contenitore e quindi esegue un comando in quel contenitore.

Se l’immagine non si trova già in locale, Docker eseguirà automaticamente anche il pull dal repository.

Digitando il comando docker ps ci vengono mostrati tutti i contenitori attualmente in esecuzione, se invece utilizziamo docker ps -aavremo una lista di tutti i container presenti, indipendentemente dal loro stato.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
305297d7a235        ubuntu             "bash"            1 minutes ago      Exited (0) 0 minutes ago                       distracted_goldstine
14e5bd11d164        hello-world         "/hello"            50 minutes ago       Exited (0) 50 minutes ago                        thirsty_euclid

Come vediamo, ogni Container creato ha un proprio ID e un proprio nome che lo contraddistinguono
Possiamo notare che il nostro contenitore Ubuntu appena eseguito è in stato “exited”. Questo perché il comando predefinito per la macchina ubuntu è bash e noi abbiamo avviato il container in modalità non interattiva obbligando quindi il container ad uscire perché non ha più nulla da fare.

L’esecuzione del comando docker run con il flag -it ci collega invece a un tty interattivo nel contenitore (-i abilita standard input -t avvia una tty).

$ sudo docker -it run ubuntu

Ora possiamo eseguire tutti i comandi che vogliamo nel contenitore come se fossimo collegati direttamente su una macchina linux. Non ci credi? Prenditi del tempo per eseguire i tuoi comandi preferiti e nel frattempo esegui anche il comando ps, noterai che il processo bash ha come PID 1 perchè è il comando entry point eseguito dopo aver startato il container.

Per uscire dal contenitore è possibile utilizzare il comando exit; digitando questo comando il contenitore killerà il nostro PID1 e quindi risulterà in stato exited; per uscire mantenendo il container in stato Up possiamo usare invece la combinazione di tasti Ctrl PQ. Proviamo questa seconda opzione e poi controlliamo i contenitori attivi.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
ff0a5c3750b9 ubuntu             "bash"            3 minutes ago      Up  3 minutes ago                       crazy_hugle

Come vediamo il nostro container è rimasto Up dopo aver eseguito la combinazione Ctrl PQ

Proviamo ora a rientrare nel container eseguendo il seguente comando:

$ sudo docker -it exec ff0a5c3750b9 bash

Con il comandodocker exec saremo in grado di agganciarci al nostro container avviato in precedenza e aggiungere un nuovo comando. Nel nostro caso abbiamo aggiunto bash per rientrare nella bash ma se ad esempio avessimo digitato ls, avrebbe stampato i risultati del comando e sarebbe uscito. Ora che siamo nuovamente nella bash digitiamo ps, noteremo che il PID non è più uno perché abbiamo eseguito un nuovo comando mentre il container era già avviato. Se infatti ora provassimo a digitare exit noteremo che il container resterà comunque Up perchè il processo con Id =1 è ancora in esecuzione. Per agganciarci direttamente al comando definito in fase di creazione del container possiamo usare docker attach:

$ sudo docker attach ff0a5c3750b9

E poi possiamo controllare con ps il numero del processo bash

root@ff0a5c3750b9:/# ps
PID TTY TIME CMD
1 pts/0 00:00:00 bash
22 pts/0 00:00:00 ps

Abbiamo visto che è proprio 1, quindi ci siamo agganciati al comando eseguito in fase di avvio del container

Altri comandi base

docker create <nomeimmagine> crea il container senza avviarlo

docker start <idcontainer> avvia un container stoppato in precedenza

docker stop <idcontainer> stoppa un container in esecuzione mantenendo il file system

docker pause <idcontainer> mette in pausa il container mantenendo file system e stato dei processi

docker unpause <idcontainer> rimette in esecuzione un container in pausa

docker restart <idcontainer> riavvia un container in esecuzione

Questo conclude un giro rapido dei comandi base, che molto probabilmente utilizzerai più spesso. Man mano che procediamo ulteriormente, ne vedremo di nuovi.

Prima di andare avanti, però, facciamo un po’ di pulizia. Se eseguiamo docker ps -a notiamo che abbiamo diversi container doppi perchè abbiamo eseguito più volte il comando docker run . Quindi, prima di procedere, eliminiamo i contenitori che non ci servono più. Per farlo, possiamo eseguire il comando docker rm seguito dall’id dei contenitori che vogliamo eliminare.

$ docker rm 305297d7a235 ff0a5c3750b9

305297d7a235
ff0a5c3750b9

docker rm rimuove solo i container stoppati, per eliminare i container in esecuzione è possibile utilizzare docker rm -d .
Al momento dell’eliminazione, dovresti vedere restituiti gli ID dei container eliminati. Se hai un elevato numero di contenitori da eliminare in una volta sola è possibile eseguire qualche comando composto:

$ docker rm $(docker ps -a -q -f status=exited)

Questo comando ad esempio elimina tutti i contenitori con stato exited, il flag -q restituisce solo gli ID numerici e l’opzione -f invece permette di impostare il filtro desiderato, in questo caso abbiamo impostato l’eliminazione per soli i container in stato exited. 

Per eliminare tutti i container non utilizzati è possibile anche utilizzare il comando docker container prune

$ docker container prune

WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
4a7f7eebae0f63178aff7eb0aa39f0627a203ab2df258c1a00b456cf20063
f98f9c2aa1eaf727e4ec9c0283bcaa4762fbdba7f26191f26c97f64090360

Total reclaimed space: 212 B

Infine, puoi anche eliminare le immagini che non ti servono più eseguendo docker rmi:

docker rmi <nomeimmagine> rimuove l’immagine in base al nome

docker rmi $docker images -a -q) rimuove tutte le immagini locali

Anticipiamo anche il comando docker system prune -a . Questo comando elimina:

  • tutti i container stoppati
  • tutte le immagini senza almeno un container associato
  • le network non utilizzate (vedremo nei prossimi articoli come creare network aggiuntive e perché farlo)
  • svuota tutta la cache di build

Conclusioni

Oggi abbiamo mosso i primi passi nel mondo Docker, avviando i primi container e imparando i comandi principali. Se l’hai notato, tutto è accaduto abbastanza rapidamente; immagina invece di aver dovuto creare una macchina virtuale, avviarla, eseguire un comando e quindi spegnerla. Nei prossimi articoli vedremo la gestione dei dati e il networking, provando a far dialogare tra loro più container.