Introduzione
Docker è una piattaforma che consente di sviluppare, testare e distribuire applicazioni come contenitori portatili e autosufficienti che funzionano praticamente ovunque.
Il comando docker run
crea un contenitore da una determinata immagine e avvia il contenitore utilizzando un determinato comando. È uno dei primi comandi con cui dovresti familiarizzare quando inizi a lavorare con Docker.
In questo articolo, useremo l'immagine ufficiale di Nginx per mostrare vari modi per eseguire un contenitore Docker.
Comando Docker Run
Il comando docker run
assume la sintassi seguente:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Il nome dell'immagine da cui deve essere creato il contenitore è l'unico argomento richiesto per il comando docker run
. Se l'immagine non è presente sul sistema locale, viene estratta dal registro.
Se non viene specificato alcun comando, il comando specificato nelle Dockerfile CMD
o nelle istruzioni ENTRYPOINT
viene eseguito durante l'esecuzione del contenitore.
A partire dalla versione 1.13, l'interfaccia della riga di comando di Docker è stata ristrutturata e tutti i comandi sono stati raggruppati sotto l'oggetto con cui interagiscono.
Poiché il comando run
interagisce con i contenitori, ora è un sottocomando di docker container
. La sintassi del nuovo comando è la seguente:
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
La vecchia sintassi precedente alla 1.13 è ancora supportata. Il comando docker run
è un alias di docker container run
. Gli utenti sono incoraggiati a utilizzare la nuova sintassi dei comandi.
Un elenco di tutte le opzioni docker container run
è disponibile nella pagina della documentazione Docker .
Eseguire il contenitore in foreground
Per impostazione predefinita, quando non viene fornita alcuna opzione al comando docker run
, il processo di root viene avviato in primo piano (foreground). Ciò significa che l'input, l'output e l'errore standard dal processo di root sono collegati alla sessione del terminale.
docker container run nginx
L'output del processo nginx verrà visualizzato sul tuo terminale. Dal momento che non ci sono connessioni al server web, il terminale è vuoto.
Per arrestare il contenitore, terminare il processo Nginx in esecuzione premendo CTRL+C
.
Eseguire il contenitore in Detached Mode
Per mantenere il contenitore in esecuzione quando si esce dalla sessione del terminale, avviarlo in modalità staccata (detached mode). Questo è simile all'esecuzione di un processo Linux in background.
Utilizzare l'opzione -d
per avviare un contenitore rimosso:
docker container run -d nginx
Il messaggio di output dovrebbe essere simile al seguente:
121f93h9139d4b091nds4908nd47190284n71093d7n419dn7903124n7d19023a
Il contenitore disconnesso si arresterà al termine del processo di root.
È possibile elencare i contenitori in esecuzione utilizzando il comando docker container ls
.
Per collegare il terminale al processo principale del contenitore staccato, utilizzare il comando docker container attach
.
Rimuovere il contenitore After Exit
Per impostazione predefinita, quando il contenitore viene chiuso, il suo file system persiste sul sistema host.
Le opzioni --rm
indicano al comando docker run
di rimuovere il contenitore quando esce automaticamente:
docker container run --rm nginx
L'immagine Nginx potrebbe non essere l'esempio migliore per ripulire il file system del contenitore dopo l'uscita del contenitore. Questa opzione viene solitamente utilizzata su contenitori in foreground che eseguono attività a breve termine come test o backup di database.
Impostare il nome del contenitore
In Docker, ogni contenitore è identificato dal suo UUID
e dal nome. Per impostazione predefinita, se non impostato esplicitamente, il nome del contenitore viene generato automaticamente dal demone Docker.
Utilizzare l'opzione --name
per assegnare un nome personalizzato al contenitore:
docker container run -d --name my_nginx nginx
Il nome del contenitore deve essere univoco. Se si tenta di avviare un altro contenitore con lo stesso nome, verrà visualizzato un errore simile al seguente:
docker: Error response from daemon: Conflict. The container name "/my_nginx" is already in use by container "9...c". You have to remove (or rename) that container to be able to reuse that name.
Esegui docker container ls -a
per elencare tutti i contenitori e vedere i loro nomi:
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
546d4fe312fe nginx "nginx -g 'daemon of…" 23 seconds ago Up 23 seconds 80/tcp my_nginx
I nomi significativi sono utili per fare riferimento al contenitore all'interno di una rete Docker o quando si eseguono comandi CLI docker.
Pubblicare le porte del contenitore
Per impostazione predefinita, se non vengono pubblicate porte, il processo in esecuzione nel contenitore è accessibile solo dall'interno del contenitore.
Pubblicare le porte significa associare le porte del contenitore alle porte del computer host in modo che le porte siano disponibili per i servizi al di fuori di Docker.
Per pubblicare una porta utilizzare l'opzione -p
come segue:
-p host_ip:host_port:container_port/protocol
- Se
host_ip
non viene specificato, per impostazione predefinita è0.0.0.0
. - Se
protocol
non viene specificato, il valore predefinito è TCP. - Per pubblicare più porte, utilizzare più opzioni
-p
.
Per mappare la porta TCP 80 (nginx) nel contenitore alla porta 8080 sull'interfaccia host locale dell'host, eseguire:
docker container run --name web_server -d -p 8080:80 nginx
È possibile verificare che la porta sia pubblicata aprendo http://localhost:8080
nel browser o eseguendo il comando curl
sull'host Docker:
curl -I http://localhost:8080
L'output sarà simile al seguente:
HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Tue, 23 Nov 2019 20:13:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 11 Nov 2019 11:56:01 GMT
Connection: keep-alive
ETag: "4dd1r677-264"
Accept-Ranges: bytes
Condivisione dei dati (Mounting Volumes)
Quando un contenitore viene arrestato, tutti i dati generati dal contenitore vengono rimossi. I volumi Docker sono il modo preferito per rendere persistenti i dati e condividerli su più contenitori.
Per creare e gestire i volumi, utilizzare l'opzione -p
come segue:
-v host_src:container_dest:options
- Il parametro
host_src
può essere un percorso assoluto per un file o una directory sul host o un volume di nome. - Il parametro
container_dest
è un percorso assoluto per un file o una directory sul contenitore. - Le opzioni possono essere
rw
(lettura-scrittura) ero
(sola lettura). Se non viene specificata alcuna opzione, per impostazione predefinita èrw
.
Per spiegare come funziona, creiamo una directory sull'host e inseriamo un file index.html
al suo interno:
mkdir public_html
echo "Testing Docker Volumes" > public_html/index.html
Quindi, montare la directory public_html
nel contenitore /usr/share/nginx/html
:
docker run --name web_server -d -p 8080:80 -v $(pwd)/public_html:/usr/share/nginx/html nginx
Invece di specificare il percorso assoluto della directory public_html
, stiamo usando il comando $(pwd)
, che stampa la directory di lavoro corrente.
Ora, se digiti http://localhost:8080
nel tuo browser, dovresti vedere il contenuto del file index.html
. Puoi anche usare curl
:
curl http://localhost:8080
Testing Docker Volumes
Eseguire il contenitore in modo interattivo
Quando si ha a che fare con processi interattivi come bash
, utilizzare l'opzione -i
e -t
per avviare il contenitore.
Le opzioni -it
indicano a Docker di mantenere l'input standard collegato al terminale e allocare una pseudo-tty:
docker container run -it nginx /bin/bash
La shell Bash del contenitore verrà collegata al terminale e il prompt dei comandi cambierà:
root@1d192392e:/#
Ora puoi interagire con la shell del contenitore ed eseguire qualsiasi comando al suo interno.
In questo esempio, abbiamo utilizzato /bin/bash
come argomento al comando docker run
che è stato eseguito invece di quello specificato nel Dockerfile.
Conclusione
Docker è lo standard per il packaging e la distribuzione (deploy) di applicazioni e un componente essenziale di CI/CD, automazione e DevOps.
Il comando docker container run
viene utilizzato per creare ed eseguire contenitori Docker.