Il contenitore Docker si arresterà automaticamente dopo "docker run -d"


333

Secondo il tutorial che ho letto finora, utilizzare " docker run -d" avvierà un contenitore dall'immagine e il contenitore verrà eseguito in background. Ecco come appare, possiamo vedere che abbiamo già un ID contenitore.

root@docker:/home/root# docker run -d centos
605e3928cdddb844526bab691af51d0c9262e0a1fc3d41de3f59be1a58e1bd1d

Ma se ho eseguito " docker ps", non è stato restituito nulla.

Quindi ho provato " docker ps -a", posso vedere il contenitore già uscito:

root@docker:/home/root# docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                         PORTS               NAMES
605e3928cddd        centos:latest         "/bin/bash"         31 minutes ago      Exited (0) 31 minutes ago                          kickass_swartz

Qualcosa che ho fatto di sbagliato? Come posso risolvere questo problema?


1
"docker run hello-world" <== funziona perfettamente, ma se eseguo "docker run -d hello-world", non riesco ancora a ottenere un container in esecuzione.
J John,

5
Ho avuto un problema simile ma ho funzionato usando docker run -it -d <image> /bin/bashquesto avvia una shell bash in modo interattivo e non chiude il contenitore perché il processo della shell è attivo.
Rtsne42,

Risposte:


495

Il file docker centos ha un comando predefinito bash.

Ciò significa che, quando viene eseguita in background ( -d), la shell si chiude immediatamente.

Aggiornamento 2017

Le versioni più recenti della finestra mobile autorizzano l'esecuzione di un contenitore sia in modalità staccata che in modalità primo piano ( -t, -io -it)

In tal caso, non è necessario alcun comando aggiuntivo e questo è sufficiente:

docker run -t -d centos

Il bash attenderà in background.
Che è stato inizialmente presentate nel Kalyani-Chaudhari 's risposta e dettagliata in jersey di fagioli ' s risposta .

vonc@voncvb:~$ d ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
4a50fd9e9189        centos              "/bin/bash"         8 seconds ago       Up 2 seconds                            wonderful_wright

Si noti che per alpino , Marinos An riporta nei commenti :

docker run -t -d alpine/gitnon mantiene il processo in corso.
Doveva fare:docker run --entrypoint "/bin/sh" -it alpine/git


Risposta originale (2015)

Come menzionato in questo articolo :

Invece di correre con docker run -i -t image your-command, -dsi consiglia di utilizzare perché è possibile eseguire il contenitore con un solo comando e non è necessario scollegare il terminale del contenitore premendo Ctrl+ P+ Q.

Tuttavia, c'è un problema con l' -dopzione. Il contenitore si arresta immediatamente a meno che i comandi non siano in esecuzione in primo piano .
Docker richiede il comando per continuare a essere eseguito in primo piano. Altrimenti, ritiene che le applicazioni vengano arrestate e arrestate il contenitore.

Il problema è che alcune applicazioni non vengono eseguite in primo piano. Come possiamo renderlo più facile?

In questa situazione, puoi aggiungere tail -f /dev/nullal tuo comando.
In questo modo, anche se il comando principale viene eseguito in background, il contenitore non si arresta perché la coda continua a essere eseguita in primo piano.

Quindi questo funzionerebbe:

docker run -d centos tail -f /dev/null

A docker psmostrerebbe il contenitore centos ancora in esecuzione.

Da lì, puoi collegarti ad esso o staccarlo da esso (o docker execalcuni comandi).


Siamo spiacenti, un'altra domanda, ho bisogno di eseguire uno script all'avvio, sembra che /etc/rc.d/rc.local non funzioni più (la mia mentalità tratta ancora docker come sistema operativo), presumo che il file docker sia l'opzione migliore in questo Astuccio?
J John,

5
@GuruprasadGV Questo è previsto. Invece di usare la docker attach, usa docker exec -it <yourContainer> bash.
VonC

3
Questo funziona anche se aggiungi il comando tail alla fine di un file entrypoint.
yara

2
Ho usato sshd come ultimo comando (long running). Puoi anche usare ssh sul tuo contenitore come faresti su una VM (una volta impostato .ssh / authorized_keys ecc.) ... Puoi anche continuare a configurare il contenitore usando ansible.
andrew pate

1
Ho finito per farlo per eseguire il mio comando più la correzione precedente elencata sopra: finestra mobile esegui nome_immagine / bin / bash -c "mio / comando && tail -f / dev / null"
Geordie

58

In base a questa risposta , l'aggiunta del -tflag impedirà l'uscita del contenitore durante l'esecuzione in background. È quindi possibile utilizzare docker exec -i -t <image> /bin/bashper entrare in un prompt della shell.

docker run -t -d <image> <command>

Sembra che l'opzione -t non sia documentata molto bene , anche se l'aiuto dice che "alloca uno pseudo-TTY".


10
Bello. Sembra meno confuso che tail -f /dev/null
accodato

Grazie! Con la minima possibilità che ciò aiuti qualcuno, questo non si comporta bene in Emacs Eshell.
Peter Becich,

2
docker run -t -d --name mysql -p 3306:3306 mysql- non funziona per me (Ubuntu 14.04.5): STATUS = Exited (1) 4 secondi fa
Putnik

Ho scoperto che non hai bisogno di <comando> qui, a meno che tu non voglia. Stranamente, funziona anche per sostituire -t con -i (interattivo). Il documento menziona l'uso di -t e -i combinati si comporterà come una shell.
jersey bean

44

sfondo

Un contenitore Docker esegue un processo (il "comando" o "entrypoint") che lo mantiene attivo. Il contenitore continuerà a funzionare finché il comando continua a essere eseguito.

Nel tuo caso, il comando ( /bin/bash, per impostazione predefinita, on centos:latest) esce immediatamente (come fa bash quando non è collegato a un terminale e non ha nulla da eseguire).

Normalmente, quando si esegue un contenitore in modalità demone (con -d ), il contenitore esegue una sorta di processo daemon (come httpd). In questo caso, finché il daemon httpd è in esecuzione, il contenitore rimarrà in vita.

Quello che sembra stia provando a fare è mantenere vivo il contenitore senza un processo daemon in esecuzione all'interno del contenitore. Questo è alquanto strano (perché il contenitore non sta facendo nulla di utile finché non interagisci con esso, forse condocker exec ), ma ci sono alcuni casi in cui potrebbe avere senso fare qualcosa del genere.

(Intendevi arrivare a un prompt bash all'interno del contenitore? È facile! docker run -it centos:latest )

Soluzione

Un modo semplice per mantenere attivo un contenitore in modalità demone a tempo indeterminato è quello di eseguirlo sleep infinitycome comando del contenitore. Questo non fa affidamento su cose strane come l'allocazione di un TTY in modalità demone. Anche se si basa sul fare cose strane come l'uso sleepcome comando principale.

$ docker run -d centos:latest sleep infinity
$ docker ps
CONTAINER ID  IMAGE         COMMAND          CREATED       STATUS       PORTS NAMES
d651c7a9e0ad  centos:latest "sleep infinity" 2 seconds ago Up 2 seconds       nervous_visvesvaraya

Soluzione alternativa

Come indicato da cjsimon, l' -topzione alloca una "pseudo-tty". Questo inganna il tentativo di continuare a funzionare indefinitamente perché pensa che sia collegato a un TTY interattivo (anche se non hai modo di interagire con quel particolare TTY se non lo passi -i). Comunque, anche questo dovrebbe fare il trucco:

$ docker run -t -d centos:latest

Non sono sicuro al 100% se -tprodurrà altre strane interazioni; forse lasciare un commento qui sotto se lo fa.


Nota che questo non funziona su Alpine poiché il sonno di BusyBox non accetta infinity.
John Kugelman,

questo mi ha aiutato a risolvere un'immagine di amazon-linux, grazie
influente

18

Salve, questo problema è dovuto al fatto che i contenitori della finestra mobile escono se non è presente alcuna applicazione in esecuzione nel contenitore.

-d 

opzione è solo per eseguire un contenitore in modalità Deamon.

Quindi il trucco per far funzionare il tuo contenitore continuamente è puntare a un file shell nella finestra mobile che manterrà la tua applicazione in esecuzione. Puoi provare con un file start.sh

Eg: docker run -d centos sh /yourlocation/start.sh

Questo start.sh dovrebbe puntare a un'applicazione senza fine.

Nel caso in cui non si desideri eseguire alcuna applicazione, è possibile installare monit che manterrà il container docker in esecuzione. Fateci sapere se questi due casi hanno funzionato per voi per mantenere il container in funzione.

Ti auguro il meglio


12

Puoi realizzare quello che vuoi con:

docker run -t -d <image-name>

o

docker run -i -d <image-name>

o

docker run -it -d <image-name>

Il parametro di comando come suggerito da altre risposte (ad esempio tail -f / dev / null) è completamente facoltativo e NON è necessario per far funzionare il container in background.

Si noti inoltre che la documentazione Docker suggerisce che la combinazione delle opzioni -i e -t farà sì che si comporti come una shell.

Vedere:

https://docs.docker.com/engine/reference/run/#foreground


9

Ho questo frammento di codice eseguito dal ENTRYPOINTmio file docker:

while true
do
    echo "Press [CTRL+C] to stop.."
    sleep 1
done

Esegui l'immagine docker integrata come:

docker run -td <image name>

Accedi alla shell del contenitore:

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

è questa la soluzione che hai creato loop infinito per questo? : D
Muhammad SaLman,

8

eseguire il comando come segue:

docker run -t -d <image-name>

se vuoi specificare la porta, allora comanda come di seguito:

docker run -t -d -p <port-no> <image-name>

verifica il container in esecuzione usando il seguente comando:

docker ps

In realtà mi piace questa risposta al meglio, perché la risposta più popolare suggerisce che hai bisogno di un comando (cioè tail -f / dev / null). Il comando è completamente opzionale. La chiave qui è usare -t. Ho anche trovato -i lavoro al posto di -t, oppure puoi anche usare entrambi -it in combinazione (poiché la documentazione suggerisce che funzionerà come shell).
jersey bean

C'è qualche vantaggio nell'usare -t -dvs -i -d? Entrambi manterranno il container in funzione.
Wisbucky,

5

Docker richiede il comando per continuare a essere eseguito in primo piano. Altrimenti, ritiene che le applicazioni vengano arrestate e arrestate il contenitore.

Quindi se lo script della voce della finestra mobile è un processo in background come il seguente:

/usr/local/bin/confd -interval=30 -backend etcd -node $CONFIG_CENTER &

Il '&' fa arrestare ed uscire il contenitore se non ci sono altri processi in primo piano attivati ​​in seguito. Quindi la soluzione è semplicemente rimuovere '&' o avere un altro CMD in primo piano in esecuzione dopo di esso , come ad esempio

tail -f server.log

Potrebbe volere touchprima quel file, nel caso in cui non fosse possibile trovare un file di registro.
Samuel Elh

Di solito il file di registro I tail è il registro del server corrente o l'output di reindirizzamento, che dovrebbe essere già presente dopo l'avvio del processo.
Peiming Hu,

4

Il contenitore Docker viene chiuso se l'attività interna viene eseguita, quindi se si desidera mantenerlo attivo anche se non ha alcun lavoro o se è già stato completato, è possibile farlo docker run -di image. Dopo averlo fatto docker container ls, lo vedrai in esecuzione.


3

Forse sono solo io ma su CentOS 7.3.1611 e Docker 1.12.6 ma ho finito per usare una combinazione delle risposte pubblicate da @VonC e @Christopher Simon per farlo funzionare in modo affidabile. Nulla di ciò che ho fatto prima avrebbe impedito l'uscita del contenitore dopo l'esecuzione corretta di CMD. Sto iniziando oracle-xe-11Gr2 e sshd.

Dockerfile

...
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && systemctl enable sshd
...
CMD /etc/init.d/oracle-xe start && /sbin/sshd && tail -f /dev/null

Quindi aggiungendo -d -t e -i per l'esecuzione

docker run --shm-size=2g --name oracle-db -d -t -i -p 5022:22 -p 5080:8080 -p 1521:1521 centos-oracle:7.3.1611 

Finalmente dopo ore di colpi alla testa contro il muro

ssh -v root@127.0.0.1 -p 5022
...
root@127.0.0.1's password: 
debug1: Authentication succeeded (password).

Per qualsiasi motivo, quanto sopra uscirà dopo aver eseguito CMD se la coda -f viene rimossa, o una delle opzioni -t -d -i viene omessa.



1

Ho avuto lo stesso problema, solo l'apertura di un altro terminale con una bash ha funzionato per me:

creare un contenitore:

docker run -d mcr.microsoft.com/mssql/server:2019-CTP3.0-ubuntu
containerid=52bbc9b30557

avviare il contenitore:

docker start 52bbc9b30557

avvia bash per mantenere il container in esecuzione:

docker exec -it 52bbc9b30557 bash

avviare il processo è necessario:

docker exec -it 52bbc9b30557 /path_to_cool_your_app

1

Se stai usando CMD alla fine del tuo Dockerfile, quello che puoi fare è aggiungere il codice alla fine. Funzionerà solo se la tua finestra mobile è costruita su Ubuntu o su qualsiasi sistema operativo che può usare bash.

&& /bin/bash

In breve la fine del Dockerfile sarà simile a questa.

...

CMD ls && ... && /bin/bash

Quindi, se hai qualcosa in esecuzione automaticamente dopo aver eseguito l'immagine della finestra mobile e quando l'attività è completa, il terminale bash sarà attivo all'interno della finestra mobile. Quindi, è possibile inserire i comandi della shell.


1

L'esecuzione di docker con modalità interattiva potrebbe risolvere il problema.

Ecco l'esempio per eseguire l'immagine con e senza modalità interattiva

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker run -d -t -i test_again1.0 b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker ps

NOME DEI PORTI DI STATO CREATI SUL COMANDO IMMAGINE ID CONTENITORE

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker run -d -t -i test_again1.0 bash c3d6a9529fd70c5b2dc2d7e90fe662d19c6dad8549e9c812fb2b7ce2105d7ff5

chaitra @ RSK-IND-BLR-L06: ~ / dockers $ sudo docker ps

ID CONTENITORE COMANDO IMMAGINE STATO CREATO PORTI NOMI c3d6a9529fd7 test_again1.0 "bash" 2 secondi fa Su 1 secondo awesome_haibt


0

se si desidera operare sul contenitore, è necessario eseguirlo in primo piano per mantenerlo in vita.


-1

L'ordine degli argomenti è importante

La risposta Jersey Beans (tutti e 3 gli esempi) ha funzionato per me. Dopo un bel po 'di tentativi ed errori mi sono reso conto che l'ordine degli argomenti conta.

Mantiene il contenitore in esecuzione in background: docker run -t -d <image-name>

Mantiene in esecuzione il contenitore in primo piano: docker run <image-name> -t -d

Non era ovvio per me provenire da un background Powershell.

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.