Perdo i miei dati all'uscita del container


394

Nonostante il tutorial interattivo e le domande frequenti di Docker, perdo i miei dati quando il container esce.

Ho installato Docker come descritto qui: http://docs.docker.io/en/latest/installation/ubuntulinux senza alcun problema su Ubuntu 13.04.

Ma perde tutti i dati quando esce.

iman@test:~$ sudo docker version
Client version: 0.6.4 
Go version (client): go1.1.2 
Git commit (client): 2f74b1c 
Server version: 0.6.4 
Git commit (server): 2f74b1c 
Go version (server): go1.1.2 
Last stable version: 0.6.4 


iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists... 
Building dependency tree... 
The following NEW packages will be installed: 
  iputils-ping 
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 
Need to get 56.1 kB of archives. 
After this operation, 143 kB of additional disk space will be used. 
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB] 
debconf: delaying package configuration, since apt-utils is not installed 
Fetched 56.1 kB in 0s (195 kB/s) 
Selecting previously unselected package iputils-ping. 
(Reading database ... 7545 files and directories currently installed.) 
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ... 
Setting up iputils-ping (3:20101006-1ubuntu1) ... 
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory 

L'ho anche provato con sessioni interattive con lo stesso risultato. Ho dimenticato qualcosa?

MODIFICA: IMPORTANTE PER I NUOVI UTENTI DOCKER

Come hanno detto @ mohammed-noureldin e altri, in realtà questo NON è un contenitore in uscita . Ogni volta che crea un nuovo contenitore.


10
Questo non può essere chiamato " uscita dal contenitore ", stai solo creando un nuovo contenitore, l'uso della parola uscita può confondere molto (anche io ero confuso a causa di quello).
Mohammed Noureldin,

1
@MohammedNoureldin, hai ragione, uscire non è corretto, ma questo è esattamente quello che tu, io e altri abbiamo pensato. Quindi è una parola migliore in questione, la tua modifica rende la domanda una risposta! I nuovi utenti non troveranno qui!
iman,

All'inizio con Docker, ho pensato che in realtà, a causa della TUA domanda, trovo che l'indirizzo sia semplicemente SBAGLIATO. il nuovo titolo è stato rivisto e accettato, non capisco perché qualcuno dovrebbe insistere su un titolo sbagliato, è la tua domanda e la tua decisione.
Mohammed Noureldin,

3
Sono d'accordo con @MohammedNoureldin. La combinazione del titolo specifico, dell'esempio e della risposta accettata non aiuta i futuri lettori e soprattutto i principianti a capire Docker. Proporrei di mantenere il titolo e la domanda originale, poiché i principianti cercheranno sicuramente qualcosa del genere. Ma perché non aggiungi qualcosa che descriva le tue idee sbagliate nel momento in cui hai scritto il post. Aiuterà a chiarire le cose. Questa è la nostra cultura qui a SO ... non è vero? :-)
tgogos,

2
Ho avuto questo problema ... ogni volta che esci devi avviare il tuo container non eseguirlo ... esegui un'immagine agane crea un nuovo container questo aiuterà la docker ad avviare <id container> docker attach <id contenitore>
fatemeh

Risposte:


399

È necessario eseguire il commit delle modifiche apportate al contenitore e quindi eseguirlo. Prova questo:

sudo docker pull ubuntu

sudo docker run ubuntu apt-get install -y ping

Quindi ottenere l'id contenitore usando questo comando:

sudo docker ps -l

Apporta modifiche al contenitore:

sudo docker commit <container_id> iman/ping 

Quindi eseguire il contenitore:

sudo docker run iman/ping ping www.google.com

Questo dovrebbe funzionare.


9
Quindi dovrei usare il commit dopo ogni corsa per conservare i dati.
iman

5
Commit deve essere utilizzato solo quando si apportano CAMBIAMENTI nel contenitore (come l'installazione di nuovi strumenti o dati) in modo che tali modifiche vengano salvate e la prossima volta che si esegue un nuovo contenitore da quell'immagine, inizierà dal punto dell'ultimo salvataggio o impegnarsi, preservando i tuoi dati.
Unferth,

7
@Unferth cosa succede se voglio continuare a eseguire modifiche? Finora crea più immagini con <none>. Come continuo ad aggiungere il commit sopra un'immagine esistente?
Marconi

62
Le modifiche incrementali non sono "il modo docker". Usa un DOCKERFILE.
user2105103

23
Come ti impegneresti dall'interno del contenitore? Si consideri il seguente scenario: 1) Sto eseguendo il container in questo modo: docker run -i -t myimage / bin / bash 2) Apporto alcune modifiche 3) Non riesco a eseguire il commit all'interno del container, quindi quando esco dal container, ho perderò tutti i miei dati, senza avere la possibilità di eseguire il commit delle mie modifiche precedenti
qgicup,

375

Quando si utilizza docker runper avviare un contenitore, in realtà crea un nuovo contenitore in base all'immagine specificata.

Oltre alle altre utili risposte qui, tieni presente che puoi riavviare un contenitore esistente dopo essere uscito e le tue modifiche sono ancora lì.

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin

89
docker psmostra solo l'esecuzione di contenitori docker. docker ps -ati mostra anche quelli che sono usciti e che puoi continuare a correre. Un commit è necessario solo dopo ogni esecuzione se si desidera creare un'istantanea lì per un uso futuro, altrimenti il ​​contenitore stesso resterà in attesa per continuare a utilizzarlo.
user1278519

2
Domanda per favore, quindi se scarico una jenkinsfinestra mobile del server e la eseguo sul mio host ci ed esegue alcuni lavori che ho e di conseguenza il server jenkins scrive sul disco alcuni registri. ora se il mio server (che ha ospitato la mia finestra mobile) viene riavviato e riavvio la finestra mobile di jenkins significherebbe che ho perso tutti i file di registro? se è così, come posso eventualmente usare la jenkinsfinestra mobile per facilitare l'installazione di jenkins su CI?
Jas,

2
@Jas Se ti attieni allo stesso contenitore e non ne crei di nuovi, non ci sono problemi. Docker al giorno d'oggi ha criteri di riavvio, quindi è possibile configurarlo per riavviare lo stesso contenitore al riavvio del computer. Ti consiglierei anche di mettere a casa i tuoi jenkins in un volume per poter accedervi dall'esterno (backup, ecc.).
ZeissS,

7
Ecco un modo pratico per copiare i file dal contenitore una volta usciti:docker cp $(docker ps -alq):/path/to/file .
Josh Habdas,

3
puoi anche avviare e collegare un contenitore in base al nome. (ad es. docker run -it --name my_debian debiane dopo docker start my_debian && docker attach my_debian)
Johnny Willer

128

Esistono i seguenti modi per conservare i dati del contenitore:

  1. Volumi Docker

  2. Docker commit

    a) creare un contenitore dall'immagine di Ubuntu ed eseguire un terminale bash.

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b) All'interno del terminale installare il ricciolo

       # apt-get update
       # apt-get install curl
    

    c) Uscire dal terminale del contenitore

       # exit
    

    d) Prendi nota del tuo ID contenitore eseguendo il comando seguente:

       $ docker ps -a
    

    e) salva contenitore come nuova immagine

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f) verifica di poter vedere la tua nuova immagine con il ricciolo installato.

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    

È necessario exitprima docker commit? Grazie.
Abhishek Anand,

2
@AbhishekSe sì, perché con il docker runcomando esegui bash nel contenitore e rimani lì a causa delle opzioni -ie -t(interattivo con TTY). Tuttavia, Docker funziona sul tuo computer, all'esterno del contenitore, quindi dopo aver apportato le modifiche necessarie al contenitore dall'interno, per tornare alla shell del tuo sistema devi exit(o Ctrl + D) la shell del contenitore. Nota anche #e $nella risposta, che indicano le diverse shell su cui sono scritti i comandi.
Erik,

Domanda veloce: se non commetto, ho perso i dati. È chiaro. Ma quando cambio la configurazione di nginx, perché rimane aggiornata? (non è necessario impegnarsi) @Erik
grep

@grep se si dispone di un MWE chiaro e riproducibile, fare una nuova domanda al riguardo, se non ce n'è già uno su questo caso d'uso specifico.
Erik

3. docker stopseguito da docker start.
Carillonator,

59

Oltre alla risposta di Unferth , si consiglia di creare un file Docker .

In una directory vuota, creare un file chiamato "Dockerfile" con i seguenti contenuti.

FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]

Crea un'immagine usando il Dockerfile . Usiamo un tag in modo da non dover ricordare il numero esadecimale dell'immagine.

$ docker build -t iman/ping .

E quindi esegui l'immagine in un contenitore.

$ docker run iman/ping stackoverflow.com

1
Non dover mai farlo manualmente più di una volta è esattamente il punto della finestra mobile. Crea un file docker, esegui il commit e carica l'immagine risultante. Tirare l'immagine in avanti.
Brandon Bertelsen,

11

Ho una risposta molto più semplice alla tua domanda, esegui i seguenti due comandi

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

il comando ps -a sopra restituisce un elenco di tutti i contenitori. Prendi il nome del contenitore che fa riferimento al nome dell'immagine - 'ubuntu'. la finestra mobile auto genera nomi per i contenitori, ad esempio -'lightlyxuyzx' se non si utilizza l'opzione --name.

Le opzioni -t e -d sono importanti, il contenitore creato è staccato e può essere ricollegato come indicato di seguito con l'opzione -t.

Con l'opzione --name, puoi nominare il tuo contenitore nel mio caso "mycontainername".

sudo docker exec -ti mycontainername bash

e questo comando sopra ti aiuta ad accedere al contenitore con shell bash. Da questo punto in poi qualsiasi modifica apportata al contenitore viene automaticamente salvata dalla finestra mobile. Per esempio -apt-get install curl all'interno del contenitore È possibile uscire dal contenitore senza problemi, la finestra mobile salva automaticamente le modifiche.

Al prossimo utilizzo, tutto quello che devi fare è eseguire questi due comandi ogni volta che vuoi lavorare con questo contenitore.

Questo comando di seguito avvia il contenitore arrestato:

sudo docker start mycontainername

sudo docker exec -ti mycontainername bash

Un altro esempio con porte e uno spazio condiviso di seguito:

docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash

Nel mio caso: 7efe2989e877 - è il imageid di un precedente contenitore in esecuzione che ho ottenuto usando

finestra mobile ps -a


4
Con Docker 18.09.2 su Ubuntu 18.04 non funziona così com'è. Funziona se metto l' --nameopzione e prima del nome dell'immagine, in questo modo:docker run --name mycontainername -t -d ubuntu /bin/bash
Stéphane Gourichon


3

Il mio suggerimento è di gestire la finestra mobile, con la finestra mobile componi. È un modo semplice per gestire tutti i container della finestra mobile per il tuo progetto, puoi mappare le versioni e collegare diversi contenitori per lavorare insieme.

I documenti sono molto semplici da capire, meglio dei documenti di Docker.

Docker-Compose Docs

Migliore


3

Ci sono davvero ottime risposte sopra alla domanda posta. Potrebbe non essere necessaria un'altra risposta, ma voglio ancora esprimere la mia opinione personale sull'argomento con le parole più semplici possibili.

Ecco alcuni punti su contenitori e immagini che ci aiuteranno per una conclusione:

  • Un'immagine docker può essere :
    1. creato-da-un-data-contenitore
    2. soppresso
    3. used-to-contenitori creare-qualsiasi-numero-di-
  • Un contenitore docker può essere :
    1. creato-da-un-image
    2. iniziato
    3. fermato
    4. rinnovate
    5. soppresso
    6. utilizzato da immagini create-qualsiasi-numero-di-
  • Un comando di esecuzione docker esegue questa operazione :
    1. Scarica un'immagine o utilizza un'immagine memorizzata nella cache
    2. Crea un nuovo contenitore da esso
    3. Avvia il contenitore
  • Quando viene utilizzato un file Docker per creare un'immagine :
    1. È già noto che l'immagine verrà eventualmente utilizzata per eseguire un contenitore finestra mobile.
    2. Dopo aver emesso il comando di compilazione della finestra mobile, la finestra mobile dietro le quinte crea un contenitore in esecuzione con un file system di base e segue i passaggi all'interno del file Docker per configurare quel contenitore secondo le esigenze degli sviluppatori.
    3. Una volta configurato il contenitore con le specifiche del file Docker, verrà eseguito il commit come immagine.
    4. L'immagine si prepara al rock & roll!

Conclusione :

Come possiamo vedere, un contenitore finestra mobile è indipendente dall'immagine finestra mobile.

Un contenitore può essere riavviato a condizione che l'ID univoco di quel contenitore [utilizzare docker ps --allper ottenere l'id] .

Qualsiasi operazione come la creazione di una nuova directory, la creazione di file, l'installazione di strumenti, ecc. Può essere eseguita all'interno del contenitore quando è in esecuzione. Una volta che il contenitore viene arrestato, persiste tutte le modifiche. L'arresto e il riavvio del contenitore è come il riavvio di un sistema informatico.

Un contenitore già creato è sempre disponibile per un riavvio ma quando si immette un docker runcomando, un nuovo contenitore viene creato da un'immagine e quindi è come un nuovo sistema informatico. Le modifiche apportate all'interno del vecchio contenitore - come possiamo capire ora - non sono disponibili in questo nuovo contenitore.

Un'ultima nota :

Immagino sia ormai ovvio il motivo per cui i dati sembrano essere persi, ma sono sempre lì .. ma in un [vecchio] contenitore diverso. Quindi, prendi nota della differenza in docker start& docker runcommand e non confonderti mai.


1

il problema simile (e nessun modo Dockerfile da solo potrebbe risolverlo) mi ha portato a questa pagina.

fase 0: per tutti, sperando che Dockerfile possa risolverlo: fino a quando --dns e --dns-search appariranno nel supporto Dockerfile - non c'è modo di integrare risorse basate su intranet.

fase 1: dopo aver creato l'immagine usando Dockerfile (tra l'altro è un problema tecnico Dockerfile deve trovarsi nella cartella corrente ), avendo un'immagine per distribuire ciò che è basato su intranet, eseguendo lo script di esecuzione docker. esempio: docker run -d \ --dns=${DNSLOCAL} \ --dns=${DNSGLOBAL} \ --dns-search=intranet \ -t pack/bsp \ --name packbsp-cont \ bash -c " \ wget -r --no-parent http://intranet/intranet-content.tar.gz \ tar -xvf intranet-content.tar.gz \ sudo -u ${USERNAME} bash --norc"

fase 2: applicazione dello script di esecuzione docker in modalità demone che fornisce record DNS locali per avere la possibilità di scaricare e distribuire elementi locali.

punto importante: eseguire lo script dovrebbe terminare con qualcosa di simile /usr/bin/sudo -u ${USERNAME} bash --norcper mantenere il container in esecuzione anche dopo il completamento degli script di installazione.

no , non è possibile eseguire il contenitore in modalità interattiva per l'intera questione dell'automazione poiché rimarrà all'interno del prompt dei comandi interno finché non viene premuto CTRL-p CTRL-q .

no , se bash interagente non verrà eseguito alla fine dello script di installazione, il contenitore verrà terminato immediatamente dopo aver terminato l'esecuzione dello script, perdendo tutti i risultati dell'installazione.

fase 3: il contenitore è ancora in esecuzione in background ma non è chiaro se il contenitore abbia terminato la procedura di installazione o meno. utilizzando il seguente blocco per determinare la fine della procedura di esecuzione: while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done lo script procederà ulteriormente solo dopo l'installazione completata. e questo è il momento giusto per chiamare: commit , fornendo l'attuale ID contenitore e il nome dell'immagine di destinazione (potrebbe essere lo stesso della procedura di compilazione / esecuzione ma aggiunto con il tag di scopi di installazione locale. esempio:. docker commit containerID pack/bsp:toolchainedvedi questo link su come ottenere containerID corretto

fase 4: il contenitore è stato aggiornato con le installazioni locali e è stato inserito nell'immagine appena assegnata (quella con l'aggiunta del tag degli scopi). ora è sicuro fermare il container. esempio:docker stop packbsp-cont

stage5: in qualsiasi momento il container con installazioni locali richiede l'esecuzione, avviarlo con l'immagine precedentemente salvata. esempio:docker run -d -t pack/bsp:toolchained


1

una risposta brillante qui Come continuare una finestra mobile che è uscita dai kg dell'utente

docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)

docker exec -it <container-id> /bin/bash

Questa seconda linea è cruciale. Quindi exec viene usato al posto della corsa e non su un'immagine ma su un containerid. E lo fai dopo che il contenitore è stato avviato.


0

Nessuna delle risposte affronta il punto di questa scelta progettuale. Penso che la finestra mobile funzioni in questo modo per prevenire questi 2 errori:

  • Riavvio ripetuto
  • Errore parziale
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.