Kontener dokowania zatrzyma się automatycznie po „uruchomieniu dokera -d”

333

Zgodnie z samouczkiem, który do tej pory przeczytałem, użycie „ docker run -d” uruchomi kontener z obrazu, a kontener będzie działał w tle. Tak to wygląda, widzimy, że mamy już identyfikator kontenera.

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

Ale jeśli uruchomię „ docker ps”, nic nie zostanie zwrócone.

Próbowałem więc „ docker ps -a”, widzę, że kontener już się zakończył:

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

Coś źle zrobiłem? Jak mogę rozwiązać ten problem?

J John
źródło
1
„docker run hello-world” <== działa idealnie, ale jeśli uruchomię „docker run -d hello-world”, nadal nie mogę uzyskać działającego kontenera.
J John
5
Miałem podobny problem, ale działałem przy użyciu docker run -it -d <image> /bin/bashtej funkcji, która uruchamia powłokę bash interaktywnie i nie zamyka pojemnika, ponieważ proces powłoki jest aktywny.
Rtsne42,

Odpowiedzi:

495

Plik dokera centos ma domyślne polecenie bash.

Oznacza to, że po uruchomieniu w tle ( -d) powłoka natychmiast się kończy.

Aktualizacja 2017

Nowsze wersje dokowanym uprawniających do prowadzenia kontenera, zarówno w trybie wolnostojącym , a w trybie planie ( -t, -ii -it)

W takim przypadku nie potrzebujesz żadnych dodatkowych poleceń, a to wystarczy:

docker run -t -d centos

Bash będzie czekał w tle.
Że początkowo zgłoszone w Kalyani-Chaudhari „s odpowiedź i wyszczególnione w jersey fasoli ” s odpowiedzi .

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

Należy pamiętać, że dla Alpine , Marinos donosi w komentarzach :

docker run -t -d alpine/gitnie utrzymuje procesu.
Musiał zrobić:docker run --entrypoint "/bin/sh" -it alpine/git


Oryginalna odpowiedź (2015)

Jak wspomniano w tym artykule :

Zamiast uruchamiać z docker run -i -t image your-command, -dzalecane jest używanie, ponieważ możesz uruchomić swój kontener za pomocą tylko jednego polecenia i nie musisz odłączać terminala kontenera, naciskając Ctrl+ P+ Q.

Istnieje jednak problem z -dopcją. Twój kontener natychmiast się zatrzymuje, chyba że polecenia nie są uruchomione na pierwszym planie .
Docker wymaga polecenia, aby nadal działał na pierwszym planie. W przeciwnym razie uważa, że ​​aplikacje zatrzymują się i zamykają kontener.

Problem polega na tym, że niektóre aplikacje nie działają na pierwszym planie. Jak możemy to ułatwić?

W tej sytuacji możesz dodać tail -f /dev/nulldo swojego polecenia.
W ten sposób, nawet jeśli główne polecenie działa w tle, kontener nie zatrzymuje się, ponieważ ogon nadal działa na pierwszym planie.

To by działało:

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

A docker pspokazuje, że kontener centos wciąż działa.

Stamtąd możesz dołączyć do niego lub odłączyć się od niego (lub docker execniektórych poleceń).

VonC
źródło
Przepraszam, jeszcze jedno pytanie, muszę uruchomić skrypt podczas uruchamiania, wygląda na to, że /etc/rc.d/rc.local już nie działa (mój sposób myślenia nadal traktuje dokera jak system operacyjny), zakładam, że plik dokera jest lepszą opcją w tym walizka?
J John
5
@GuruprasadGV To jest oczekiwane. Zamiast używać docker attach, użyj docker exec -it <yourContainer> bash.
VC
3
Działa to również, jeśli dodasz polecenie tail na końcu pliku punktu wejścia.
yara
2
Użyłem sshd jako mojej ostatniej (długiej) komendy. Następnie możesz ssh na swoim kontenerze, tak jak na maszynie wirtualnej (po ustawieniu .ssh / autoryzowanych_kluczy itp.) ... Możesz także skonfigurować kontener za pomocą ansible.
andrew pate
1
Skończyło się na tym, aby wykonać polecenie i starszą poprawkę wymienioną powyżej: docker uruchom image_name / bin / bash -c "my / command && tail -f / dev / null"
Geordie
58

Zgodnie z tą odpowiedzią dodanie -tflagi zapobiegnie wyjściu kontenera podczas działania w tle. Następnie możesz użyć, docker exec -i -t <image> /bin/bashaby wyświetlić monit powłoki.

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

Wygląda na to, że opcja -t nie jest dobrze udokumentowana , chociaż pomoc mówi, że „alokuje pseudo-TTY”.

cjsimon
źródło
10
Miły. Wydaje się mniej tail -f /dev/null
hackerski
Dzięki! Przy małej szansie, że to komuś pomaga, nie zachowuje się to dobrze w Emacs Eshell.
Peter Becich
2
docker run -t -d --name mysql -p 3306:3306 mysql- nie działa dla mnie (ubuntu 14.04.5): STATUS = Wyjście (1) 4 sekundy temu
Putnik
Odkryłem, że nie potrzebujesz tutaj <polecenia>, chyba że chcesz. O dziwo, działa również, aby zamienić -t na -i (interaktywny). Dokument wspomina, że ​​użycie kombinacji -t i -i będzie zachowywać się jak powłoka.
jersey bean
43

tło

Kontener Docker uruchamia proces („polecenie” lub „punkt wejścia”), który utrzymuje go przy życiu. Kontener będzie działał tak długo, jak długo będzie działać polecenie.

W twoim przypadku polecenie ( /bin/bashdomyślnie włączone centos:latest) kończy się natychmiast (tak jak bash, gdy nie jest podłączone do terminala i nie ma nic do uruchomienia).

Zwykle po uruchomieniu kontenera w trybie demona (z -d) kontener uruchamia jakiś proces demona (jak httpd). W takim przypadku, dopóki uruchomiony jest demon httpd, kontener pozostanie aktywny.

Wygląda na to, że próbujesz utrzymać kontener przy życiu bez uruchamiania procesu demona wewnątrz kontenera. Jest to nieco dziwne (ponieważ kontener nie robi nic użytecznego, dopóki nie wejdziesz z nim w interakcję, być może z docker exec), ale są pewne przypadki, w których sensowne może być zrobienie czegoś takiego.

(Czy chciałeś dostać się do bashu wewnątrz kontenera? To proste! docker run -it centos:latest)

Rozwiązanie

Prostym sposobem na utrzymanie kontenera w trybie demona na czas nieokreślony jest uruchomienie go sleep infinityjako komendy kontenera. Nie polega to na robieniu dziwnych rzeczy, takich jak przydzielanie TTY w trybie demona. Chociaż polega na robieniu dziwnych rzeczy, takich jak używanie sleepjako głównego polecenia.

$ 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

Alternatywne rozwiązanie

Jak wskazuje cjsimon, -topcja przydziela „pseudo-tty”. Te sztuczki zmuszają do kontynuowania działania w nieskończoność, ponieważ wydaje się, że jest on podłączony do interaktywnego TTY (nawet jeśli nie masz możliwości interakcji z tym konkretnym TTY, jeśli go nie przejdziesz -i). W każdym razie powinno to załatwić sprawę:

$ docker run -t -d centos:latest

Nie jestem w 100% pewien, czy -tspowoduje inne dziwne interakcje; może zostaw komentarz poniżej, jeśli tak jest.

mkasberg
źródło
Pamiętaj, że to nie działa na alpejskim, ponieważ sen BusyBox nie akceptuje infinity.
John Kugelman,
pomogło mi to rozwiązać problemy z obrazem amazon-linux, dziękuję
wpływowy
18

Cześć, ten problem jest spowodowany zamknięciem kontenerów dokowanych, jeśli w kontenerze nie ma uruchomionej aplikacji.

-d 

opcją jest po prostu uruchomienie kontenera w trybie demona.

Zatem sztuczką, aby kontener działał nieprzerwanie, jest wskazanie pliku powłoki w oknie dokowanym, który utrzyma działanie aplikacji. Możesz spróbować z plikiem start.sh

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

Ten plik start.sh powinien wskazywać na niekończącą się aplikację.

W przypadku, gdy nie chcesz, aby jakakolwiek aplikacja była uruchomiona, możesz zainstalować, monitco zapewni utrzymanie kontenera dokującego. Daj nam znać, czy te dwa przypadki zadziałały, aby utrzymać działanie kontenera.

Wszystkiego najlepszego

Pratik
źródło
12

Możesz osiągnąć to, co chcesz:

docker run -t -d <image-name>

lub

docker run -i -d <image-name>

lub

docker run -it -d <image-name>

Parametr polecenia sugerowany przez inne odpowiedzi (np. Tail -f / dev / null) jest całkowicie opcjonalny i NIE jest wymagany, aby kontener działał w tle.

Należy również pamiętać, że dokumentacja Dockera sugeruje, że połączenie opcji -i i -t spowoduje, że będzie on zachowywał się jak powłoka.

Widzieć:

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

jersey bean
źródło
9

Mam ten fragment kodu uruchamiany z ENTRYPOINTmojego pliku dokera:

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

Uruchom zbudowany obraz dokera jako:

docker run -td <image name>

Zaloguj się do powłoki kontenera:

docker exec -it <container id> /bin/bash
Binita Bharati
źródło
czy jest to rozwiązanie, które stworzyliście w tym celu nieskończoną pętlę? : D
Muhammad SaLman
8

wykonaj polecenie w następujący sposób:

docker run -t -d <image-name>

jeśli chcesz podać port, wykonaj następujące polecenia:

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

sprawdź działający kontener za pomocą następującego polecenia:

docker ps
kalyani chaudhari
źródło
Właściwie najbardziej podoba mi się ta odpowiedź, ponieważ najpopularniejsza odpowiedź sugeruje, że potrzebujesz polecenia (tj. Tail -f / dev / null). Polecenie jest całkowicie opcjonalne. Kluczem jest tutaj użycie -t. Znalazłem także -i działające zamiast -t, lub możesz także używać obu -it łącznie (jak sugeruje dokumentacja, że ​​będzie działać jako powłoka).
jersey bean
Czy jest jakaś zaleta używania -t -dvs -i -d? Oba utrzymają działanie kontenera.
wisbucky
5

Docker wymaga polecenia, aby nadal działał na pierwszym planie. W przeciwnym razie uważa, że ​​aplikacje zatrzymują się i zamykają kontener.

Jeśli więc skrypt wprowadzania dokera jest procesem w tle, taki jak:

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

„&” Powoduje zatrzymanie kontenera i wyjście z niego, jeśli później nie uruchomi się żaden inny proces pierwszego planu. Tak więc rozwiązaniem jest po prostu usunięcie „&” lub uruchomienie innego CMD pierwszego planu , takiego jak

tail -f server.log
Peiming Hu
źródło
Może touchnajpierw chcę ten plik, na wypadek gdyby nie można znaleźć pliku dziennika.
Samuel Elh
Zwykle plik dziennika I tail jest bieżącym plikiem dziennika lub przekierowaniem serwera, który powinien już tam być po uruchomieniu procesu.
Peiming Hu
4

Kontener Docker zostanie zamknięty, jeśli zadanie w środku zostanie wykonane, więc jeśli chcesz utrzymać go przy życiu, nawet jeśli nie ma on żadnej pracy lub jest już ukończony, możesz to zrobić docker run -di image. Gdy to zrobisz docker container ls, zobaczysz, że działa.

Vrangz
źródło
3

Może to tylko ja, ale w CentOS 7.3.1611 i Docker 1.12.6, ale ostatecznie musiałem użyć kombinacji odpowiedzi opublikowanych przez @VonC i @Christopher Simon, aby niezawodnie działać. Nic, co zrobiłem wcześniej, nie powstrzymałoby wyjścia kontenera po pomyślnym uruchomieniu CMD. Zaczynam oracle-xe-11Gr2 i sshd.

Plik Docker

...
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

Następnie dodaj -d -t i -i, aby uruchomić

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 

W końcu po godzinach walenia głową w ścianę

ssh -v [email protected] -p 5022
...
[email protected]'s password: 
debug1: Authentication succeeded (password).

Z jakiegokolwiek powodu powyższe wyjdzie po wykonaniu CMD, jeśli tail -f zostanie usunięty lub jedna z opcji -t -d -i zostanie pominięta.

steven87vt
źródło
1

Miałem ten sam problem, po prostu otworzyłem inny terminal z bash na nim zadziałało:

utwórz kontener:

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

uruchom kontener:

docker start 52bbc9b30557

uruchom bash, aby utrzymać działanie kontenera:

docker exec -it 52bbc9b30557 bash

rozpocznij proces potrzebujesz:

docker exec -it 52bbc9b30557 /path_to_cool_your_app
Steef
źródło
1

Jeśli używasz CMD na końcu pliku Docker, możesz dodać kod na końcu. Działa to tylko wtedy, gdy twój doker jest zbudowany na Ubuntu lub dowolnym systemie operacyjnym, który może korzystać z bash.

&& /bin/bash

Krótko koniec twojego Dockerfile będzie wyglądał jak coś takiego.

...

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

Więc jeśli masz coś uruchomionego automatycznie po uruchomieniu obrazu dokera, a po zakończeniu zadania terminal bash będzie aktywny wewnątrz dokera. W ten sposób możesz wprowadzić polecenia powłoki.

Ekin
źródło
1

Uruchomienie dokera w trybie interaktywnym może rozwiązać problem.

Oto przykład uruchamiania obrazu w trybie interaktywnym i bez niego

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

ID KONTENERA OBRAZ KOMUNIKAT STWORZONY STAN NAZWY PORTÓW

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 KONTENERA OBRAZ TWORZENIE STANU NAZWY PORTÓW c3d6a9529fd7 test_again1.0 „bash” 2 sekundy temu Do 1 sekundy awesome_haibt

Chaitra
źródło
0

jeśli chcesz operować na kontenerze, musisz uruchomić go na pierwszym planie, aby utrzymać go przy życiu.

lwpro2
źródło
-1

Kolejność argumentów ma znaczenie

Odpowiedź z fasoli Jersey (wszystkie 3 przykłady) działała dla mnie. Po kilku próbach i błędach zdałem sobie sprawę, że kolejność argumentów ma znaczenie.

Utrzymuje działanie kontenera w tle: docker run -t -d <image-name>

Utrzymuje kontener działający na pierwszym planie: docker run <image-name> -t -d

Nie było dla mnie oczywiste, że pochodzi z Powershell.

HVL71
źródło