Un segno distintivo dei container Docker è l'immutabilità. In qualsiasi momento, puoi distruggere e ricreare i container per ristabilire lo stato iniziale. Usando il docker commit
comando, puoi eseguire il commit di nuove modifiche a un'immagine contenitore, ma non è così semplice come ti aspetteresti.
Esaminiamo come eseguire il commit delle modifiche a una nuova immagine del contenitore con il docker commit
comando!
Quando eseguire il commit delle modifiche su una nuova immagine del container
I contenitori sono costruiti per essere immutabili (non modificati), quindi perché allora dovresti voler eseguire il commit delle modifiche a un contenitore? Ci sono alcuni motivi.
- Durante lo sviluppo di un nuovo servizio containerizzato per testare rapidamente le modifiche.
- Esegui una rapida correzione dei bug di un servizio di produzione senza dover prima correggere l'immagine di origine.
- Usa
commit
per eseguire lo snapshot di un'immagine ed esportare l'immagine su un nuovo server.
Anche se questi potrebbero non coprire tutti i potenziali scenari, questi sono alcuni che rendono l'utilizzo di docker commit
un caso d'uso perfetto.
Immissione delle modifiche a un'immagine semplice
Per un comando apparentemente semplice, questo comando fa molto.
Di seguito è riportato un semplice esempio commit
comando. Utilizzando un ID contenitore in esecuzione, d3fdd3517e0a
in questo esempio, viene creata una nuova immagine in un repository chiamato myrepository
e denominato changedimage
.
L'immagine originale è contrassegnata come version2
, che non è necessario, ma utile per tenere traccia delle modifiche tra immagini con nome simile.
Entrambi
myrepository
echangedimage
sono scelti arbitrariamente, ma in genere riflettono risorse adeguatamente etichettate comecustomimages/alpine-linux
.
docker commit d3fdd3517e0a myrepository/changedimage:version2
I contenitori Docker sono una serie di immagini di sola lettura con un livello di lettura-scrittura in cima. Nell'esempio precedente, Docker sospende il contenitore in esecuzione. Questa pausa serve a prevenire il danneggiamento accidentale dei dati mentre Docker crea l'immagine
Poiché questa pausa potrebbe causare interruzioni del servizio, puoi utilizzare
--pause=false
. Ciò potrebbe danneggiare i dati, poiché le scritture potrebbero non essere completate correttamente.
Inoltre, il commit
operazione omette i dati contenuti nei volumi montati all'interno del contenitore. Poiché i volumi non fanno parte del file system stesso del contenitore, Docker li ignora.
Una volta completata l'operazione di commit, Docker crea un nuovo livello con le modifiche dell'immagine originale sotto il nuovo nome dell'immagine del contenitore.
Prerequisiti
L'unico prerequisito in questo tutorial è Docker stesso. Questo può essere installato tramite il software Docker Desktop in Windows o installato tramite un pacchetto in Linux.
Correlato:distribuzione del tuo primo contenitore Docker in Windows
Commiting modifiche a una nuova immagine Docker Container
Diamo ora un'occhiata ad alcuni scenari comuni che il docker commit
il comando può essere utile per.
Innanzitutto, estrai un'immagine del contenitore Alpine Linux dal repository Docker pubblico. Alpine è nota per i suoi contenitori sottili, come si nota dalle dimensioni di circa 5 MB.
# Pull the latest Alpine Linux image
docker pull alpine
# List all Docker images
docker images
Sviluppo e test di container
Il caso d'uso principale per docker commit
è lo sviluppo di una nuova immagine contenitore. Questa immagine può infine essere utilizzata come base per altre immagini o come contenitore di produzione stesso.
Nello snippet di esempio di seguito, Docker è:
- Esecuzione del percorso
alpine
precedentemente estratto immagine - Apertura di una shell interattiva per installare un pacchetto
- Installazione del pacchetto htop
# Open an interactive shell to the Docker Alpine Linux container
docker run -it a24bb4013296 bin/sh
# Install the HTOP package
apk add htop
Di seguito puoi vedere che il pacchetto è installato correttamente nel contenitore eseguendo htop
comando.
Dopo aver installato il pacchetto sul nuovo "livello", ora dovresti eseguire il commit della modifica sull'immagine di base originale. Per farlo:
- Esegui
docker ps -a
per individuare l'ID del contenitore. - Utilizzando l'ID contenitore, salva il contenuto del livello corrente in una nuova immagine di base.
Nell'esempio seguente, la nuova immagine è denominata alpine-htop
e taggato version1
. L'immagine è contrassegnata per facilitare il monitoraggio delle versioni dell'immagine Docker con nomi simili.
# List all Docker containers regardless of status, -a or --all to show every container
docker ps -a
# Commit the layer to a new image named alpine-htop and tagged version1
docker commit b57e066d5bfa alpine-htop:version1
# List all images available
docker images
Risoluzione di bug nelle immagini di produzione
Spesso potresti avere un servizio di produzione che presenta qualche errore. Potrebbe esserci una correzione nota e potresti applicare una correzione più rapidamente rispetto alla modifica delle configurazioni esistenti e alla ridistribuzione. Usando docker commit
, puoi applicare rapidamente la correzione e quindi lavorare in background per aggiornare gli altri componenti necessari.
Questo frammento di esempio di seguito mostra l'installazione di NGINX in un'immagine Docker Linux Alpine.
# First List the available images
docker images
# Run an interactive session for the alpine-htop image
docker run -it a24bb4013296 bin/sh
# Install the NGINX package
apk add nginx
# Create the location for the NGINX PID file
mkdir /run/nginx
# Verify that NGINX is installed
nginx -v
# Run NGINX
/usr/sbin/nginx
# Verify that NGINX is properly running
ps | grep nginx
# Kill the NGINX process
kill 18
# Verify that the NGINX process is no longer active
ps | grep nginx
Conferma il nuovo contenitore NGINX creato sopra in una nuova immagine denominata alpine-nginx
e con il tag version1
. La codifica dell'immagine è una procedura consigliata per aiutare a differenziare le diverse versioni della stessa immagine.
# List all Docker containers regardless of status, -a or --all to show every container
docker ps -a
# Commit the changes to a new image named alpine-nginx
docker commit 37043139525c alpine-nginx:version1
# Verify that the new image was created
docker images
Non tutti gli eseguibili potranno essere eseguiti in background e NGINX non è diverso. Per eseguire correttamente questo contenitore, con NGINX in esecuzione in background, passa il -g 'daemon off;'
opzione su NGINX.
# Run the NGINX container in the background
docker run -d f6b46a3b76be /usr/sbin/nginx -g 'daemon off;'
# Verify that the container is running
docker ps -a
Infine, usa il --change
passare per esporre la porta 80. Utilizzando il --change
parametro, il EXPOSE 80
il comando verrà scritto nel DockerFile del contenitore. Dopo aver apportato questa modifica, avviare il nuovo contenitore. Dopo che il nuovo container è stato avviato, procedere all'arresto del container precedente che era stato eseguito in modo errato senza la porta esposta. Ciò contribuirà a eseguire la transizione graduale dal contenitore non funzionante al contenitore funzionante.
# List all running containers
docker ps -a
# Commit the changes to a new image with an exposed port 80
docker commit --change "EXPOSE 80" c649c813d985 alpine-nginx:version2
# List the running containres
docker ps -a
# List all Docker images
docker images
# Run the newly created image
docker run -d c71f0f9cef7b /usr/sbin/nginx -g 'daemon off;'
# List running containers
docker ps -a
# Stop the prior container without the exposed port 80
docker stop c649c813d985
# List running containers
docker ps -a
Istantanea di un'immagine Docker
Infine, che dire di uno scenario in cui potrebbe essere necessario eseguire uno snapshot, un'immagine di un punto nel tempo, di un container in esecuzione per spostare il container su un nuovo server? Il docker commit
il comando funziona bene per farlo, come puoi vedere di seguito.
I comandi seguenti creano un contenitore in esecuzione che arresteremo e ci impegneremo in un nuovo alpine-nginx
versione.
# List running Docker containers
docker ps -a
# Create a new running Docker NGINX container
docker run -d c71f0f9cef7b
# List running Docker containers
docker ps -a
# Stop the Docker container
docker stop 7ff99f2bcf6b
# Create a new alpine-nginx version to export
docker commit 7ff99f2bcf6b alpine-nginx:version3
# List the Docker images available
docker images
Esporta l'immagine Docker in un file. In questo esempio, il file di esportazione è denominato export.tar
, ma nomina il file in base alle tue esigenze. Infine, importa il export.tar
file di nuovo in Docker, dimostrando il processo end-to-end.
Assicurati di esportare utilizzando il formato
repo:tag
se desideri che tali etichette vengano mantenute durante la reimportazione dell'immagine.
# Save the image to a file on the local disk
docker save -o export.tar alpine-nginx:version3
# Verify that the image exists
ls
# Remove the just exported Docker image
docker rmi 39ca9e64828a
# List Docker images and verify that the image is removed
docker images
# Load the Docker image back in
docker load -i export.tar
# List Docker images and show that the image has been loaded back in
docker images
Opzioni aggiuntive per il comando di conferma Docker
Sfruttando le opzioni aggiuntive disponibili per il commit
comando, sono supportati molti scenari diversi.
Pausa del contenitore
Per non mettere in pausa il contenitore mentre è in esecuzione, puoi passare il --pause=false
comando per disabilitare la funzione di pausa. Viene spesso utilizzato quando si esegue il backup di un servizio di produzione e la sospensione di tale servizio sarebbe dannosa.
Il comando pause ha anche una scorciatoia di -p
che potrebbe essere più veloce da usare. Tieni presente, tuttavia, che bypassando la pausa del contenitore, stai rischiando il danneggiamento dei dati, se si verifica una scrittura del filesystem, che potrebbe causare la scrittura di dati incompleti o danneggiati.
Lasciare un messaggio di commit
Familiare a molti sviluppatori è quello di fornire un messaggio di commit corretto. Proprio come nell'utilizzo del controllo del codice sorgente, idealmente vuoi inviare un messaggio utile che spieghi perché è stata salvata una nuova versione del contenitore.
Questo può essere fatto usando il --message="message to commit"
comando. Come prima, esiste una versione abbreviata di questo comando, -m
. Per visualizzare l'elenco dei messaggi di commit Docker, utilizza la docker history
comando.
Definizione dell'autore
Per indicare correttamente chi sta creando la modifica, puoi fornire un valore dell'autore che fornirà un contesto aggiuntivo a chi sta apportando la modifica. Può essere utilizzato tramite --author="Jane Author ([email protected])"
. Questo comando può essere utilizzato anche tramite l'abbreviazione di -a
. Usando docker inspect
sarai in grado di recuperare un elenco JSON di informazioni sul contenitore, comprese etichette come autore.
Applicazione delle modifiche a DockerFile in parallelo
Infine, il comando più complicato che può essere utilizzato nel docker commit
il comando è il change
parametro. Questo parametro applica le modifiche nel contenitore a DockerFile contemporaneamente al commit.
Puoi usare il change
parametro passando le istruzioni al Dockerfile in questo modo, --change="ENV TEST true"
. Questo comando inserisce il testo, ENV TEST true
nel DockerFile. Ora, quando il contenitore si riavvia, le modifiche che hai designato qui sarebbero già state applicate.
Invece del
--change
nome, puoi prendere una scorciatoia e usare il-c
alias.
Con questo comando, puoi anche concatenare più --change
parametri insieme. Ciò ti consente di aggiungere facilmente più modifiche a un DockerFile in un comando di commit.
Modifica opzioni parametro
Puoi usare solo pochi comandi con change
parametro come mostrato di seguito.
CMD
– L'istruzione CMD assume la forma di CMD ["executable","parameter1","parameter2"]
. Questo è il metodo preferito, ma tieni presente che solo unCMD
può esistere in un DockerFile alla volta. L'ultimoCMD
sarà quello che avrà effetto. Lo scopo principale diCMD
consiste nel fornire comandi di esecuzione predefiniti per un contenitore al momento della creazione.ENTRYPOINT
– Simile al comando CMD, ENTRYPOINT utilizza la sintassi diENTRYPOINT ["executable","parameter1","parameter2"]
. Questa sintassi pone la domanda sul perché usare ENTRYPOINT su CMD?
Il comando ENTRYPOINT esegue un eseguibile come processo principale diPID 1
. Questa azione ti consente quindi di chiudere il processo utilizzandodocker stop
con grazia. Inoltre, puoi utilizzareCMD
con questo omettendo l'executable
porzione che passa quei parametri nelENTRYPOINT
eseguibile.ENV
– Poiché la maggior parte delle applicazioni utilizza variabili ambientali, il comando ENV consente di impostarle semplicemente nel formato chiave-valore diENV key=value
. Accedi a queste variabili chiave=valore come variabili ambientali standard di Linux.EXPOSE
– Il comando EXPOSE espone una porta e un protocollo facoltativo all'esterno del contenitore. Questo comando mappa le porte all'interno del container all'esterno del container e consente ai container di interagire con risorse esterne come un server Web che serve contenuti.LABEL
– Il comando LABEL aggiunge metadati a un contenitore. Puoi aggiungere metadati utilizzando il formatoLABEL version="2.0"
per visualizzare i metadati aggiuntivi usa il comando di ispezione dell'immagine della finestra mobile.ONBUILD
– Il comando ONBUILD aggiunge un'istruzione da eseguire in seguito quando l'immagine viene utilizzata come base per un'altra build del contenitore. Questo parametro utilizza i comandi ADD ed RUN per aggiungere contenuto con il comando ADD o RUN un eseguibile.USER
-Il comando USER imposta il nome utente (o UID) e facoltativamente il gruppo utenti (o GID) da utilizzare durante l'esecuzione dell'immagine. SembraUSER myuser:mygroup
in pratica.- VOLUME – Con la maggior parte dei container, è necessario accedere ai dati in qualche modo. Il comando VOLUME creerà un punto di montaggio con un nome specificato che lo contrassegna come contenente un volume montato esternamente. Questo è comunemente usato in questo modo,
VOLUME ["/data"]
. WORKDIR
– Infine, il comando WORKDIR imposta nella directory di lavoro i comandi CMD o ENTRYPOINT. Questo è usato in questo modo,WORKDIR /path/to/directory
. WORKDIR è utile quando devi avviare un eseguibile ma la posizione non è nella variabile ambientale PATH predefinita.
Conclusione
Il docker commit
il comando è sorprendentemente complesso. Sebbene esista una sintassi semplice, con la possibilità di aggiungere modifiche DockerFile durante l'utilizzo del comando commit, puoi apportare rapidamente modifiche che persistono alla successiva creazione del contenitore tramite DockerFile.
Questo comando potrebbe non essere necessario per tutte le situazioni, ma per una rapida risoluzione dei problemi e per creare snapshot di contenitori che possono essere facilmente spostati tra i server, il comando commit diventa rapidamente molto utile!