Docker konteyneri “docker run -d” sonrasında otomatik olarak durur


333

Şimdiye kadar okuduğum eğiticiye göre, " docker run -d" kullanın, bir kapsayıcıyı görüntüden başlatacak ve kapsayıcı arka planda çalışacak. Bu şekilde görünüyor, zaten konteyner kimliğimiz olduğunu görebiliyoruz.

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

" docker ps"

Bu yüzden " docker ps -a" denedim , zaten kaptan çıkıldığını görebiliyorum:

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

Yanlış yaptığım bir şey var mı? Bu sorunu nasıl giderebilirim?


1
"docker hello-world'u çalıştırır" <== mükemmel çalışır, ancak "docker run -d hello-world" komutunu çalıştırırsam, hala çalışan bir kap elde edemiyorum.
J John,

5
Ben benzer bir sorun vardı ama bunu kullanarak docker run -it -d <image> /bin/bashbir bash kabuk etkileşimli başlar ve kabuk işlemi etkin olduğundan kap kapatmaz kullanarak çalıştım .
Rtsne42

Yanıtlar:


495

Centos dockerfile varsayılan komutu vardır bash.

Bu, background ( -d) içinde çalıştırıldığında kabuğun hemen çıktığı anlamına gelir .

2017 Güncellemesi

Liman işçisi authorize daha yeni sürümleri hem bir kap çalıştırmak için müstakil modda ve içinde ön plan modunda ( -t, -iya da -it)

Bu durumda, herhangi bir ek komuta ihtiyacınız yoktur ve bu yeterlidir:

docker run -t -d centos

Bash arka planda bekleyecektir.
Yani başlangıçta bildirildi Kalyani-Chaudhari 'ın cevabı ve ayrıntıları forması fasulyesi ' ın cevabı .

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

Not Bunun için Alp , Marinos bir rapor yorumlarda :

docker run -t -d alpine/gitsüreci devam ettirmez.
Yapmak zorundaydım:docker run --entrypoint "/bin/sh" -it alpine/git


Orijinal cevap (2015)

Bu makalede belirtildiği gibi :

İle çalışmak yerine docker run -i -t image your-command, kullanılması -dönerilir çünkü konteynırınızı tek bir komutla çalıştırabilirsiniz ve Ctrl+ P+ tuşlarına basarak konteynerin terminalini ayırmanız gerekmez Q.

Ancak, -dseçenekle ilgili bir sorun var . Komutlar ön planda çalışmadığı sürece kabınız hemen durur .
Docker, ön planda çalışmaya devam etmek için komutunuzu istiyor. Aksi takdirde, uygulamalarınızın kapsayıcıyı durdurup kapattığını düşünür.

Sorun, bazı uygulamaların ön planda çalışmadığıdır. Bunu nasıl kolaylaştırabiliriz?

Bu durumda, tail -f /dev/nullkomutunuza ekleyebilirsiniz .
Bunu yaparak, ana komutunuz arka planda çalışsa bile, kabınız durmaz çünkü kuyruk ön planda çalışmaya devam eder.

Yani bu işe yarar:

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

A docker ps, hala çalışan centos kabını gösterir.

Oradan, ona ekleyebilir veya ondan (veya docker execbazı komutlardan) ayırabilirsiniz .


Üzgünüz, bir soru daha, başlangıçta çalıştırmam gereken bir komut dosyası var, /etc/rc.d/rc.local artık çalışmıyor gibi görünüyor (zihniyetim hala docker'ı OS gibi tedavi ediyor), docker dosyasının bu konuda daha iyi bir seçenek olduğunu varsayıyorum durum?
J John

5
@GuruprasadGV Bu bekleniyor. Docker ataşmanı kullanmak yerine kullanın docker exec -it <yourContainer> bash.
VonC

3
Bu, giriş noktası dosyasının sonuna tail komutu eklerseniz de çalışır.
yara

2
Son (uzun süren) komutum olarak sshd kullandım. Daha sonra kapsayıcıyı bir VM'de yaptığınız gibi ssh edebilirsiniz (.ssh / yetkili_anahtarlar vb. Ayarladıktan sonra) ... Kapsayıcıyı ansible kullanarak yapılandırmaya da devam edebilirsiniz.
andrew pate

1
Komutumu ve yukarıda listelenen eski düzeltmeyi yürütmek için bunu yaptım: docker run image_name / bin / bash -c "my / command && tail -f / dev / null"
Geordie

58

Bu cevaba göre , -tbayrağın eklenmesi arka planda çalışırken kabın çıkmasını engelleyecektir. Daha sonra docker exec -i -t <image> /bin/bashbir kabuk istemine girmek için kullanabilirsiniz .

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

Yardım, "sahte bir TTY ayırdığını" söylüyor olsa da , -t seçeneğinin çok iyi belgelenmediği anlaşılıyor.


10
Güzel. tail -f /dev/null
Eklemekten

Teşekkürler! Bu, birinin şansına yardımcı olmak için, Emacs Eshell'de iyi davranmıyor.
Peter Becich

2
docker run -t -d --name mysql -p 3306:3306 mysql- benim için çalışmıyor (Ubuntu 14.04.5): STATUS = Çıkış (1) 4 saniye önce
Putnik

İstemediğiniz sürece burada <komut> 'a ihtiyacınız olmadığını buldum. Garip bir şekilde, -t yerine -i (interaktif) kullanılması da işe yarar. Doktor -t ve -i kombine kullanmanın bir kabuk gibi davranacağından bahsediyor.
jersey fasulye

43

Arka fon

Docker kapsayıcısı, onu canlı tutan bir işlem ("komut" veya "giriş noktası") çalıştırır. Komut çalışmaya devam ettiği sürece kap çalışmaya devam edecektir.

Sizin durumunuzda, komut ( /bin/bashvarsayılan olarak açık centos:latest) hemen çıkar (bash bir terminale bağlı olmadığında ve çalışacak hiçbir şeyi olmadığında).

Normalde, bir kapsayıcıyı daemon modunda (ile -d) çalıştırdığınızda, kapsayıcı bir çeşit daemon işlemi (gibi httpd) çalıştırır. Bu durumda, httpd arka plan programı çalıştığı sürece kap canlı kalır.

Yapmaya çalıştığınız şey, kap içinde bir daemon işlemi olmadan kapsayıcıyı canlı tutmaktır. Bu biraz garip (çünkü konteyner onunla etkileşime girene kadar yararlı bir şey yapmıyor, belki de ile docker exec), ancak böyle bir şey yapmanın mantıklı olabileceği bazı durumlar var.

(Konteyner içinde bir bash istemine mi girmek istediniz? Bu kolay! docker run -it centos:latest)

Çözüm

Bir kapsayıcıyı daemon modunda süresiz olarak canlı tutmanın basit bir yolu sleep infinity, kabın komutu olarak çalıştırmaktır . Bu, arka plan modunda bir TTY ayırmak gibi garip şeyler yapmaya dayanmaz. Her ne kadar sleepbirincil komutunuz olarak kullanmak gibi garip şeyler yapmaya dayanıyor olsa da .

$ 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

Alternatif çözüm

Cjsimon ile belirtildiği gibi, -tseçenek bir "sözde tty" tahsis eder. Bu hileler, interaktif bir TTY'ye bağlı olduğunu düşündüğü için süresiz olarak çalışmaya devam etmeyi basar (geçmezseniz, belirli TTY ile etkileşime girme imkanınız olmasa bile -i). Her neyse, bu da hile yapmalı:

$ docker run -t -d centos:latest

-tDiğer garip etkileşimleri üretip üretmeyeceğinden % 100 emin değilim ; belki varsa aşağıya bir yorum bırakın.


BusyBox'ın uykusu kabul etmediği için bunun alp üzerinde çalışmadığını unutmayın infinity.
John Kugelman

Bu beni, teşekkür ederim bir amazon-linux görüntüsünü gidermek yardımcı
akın

18

Merhaba bu sorun, kapsayıcı çalışan bir uygulama yoksa docker kapsayıcılar çıkmak çünkü.

-d 

seçeneği sadece bir kapsayıcı deamon modunda çalıştırmaktır.

Bu nedenle, konteynırınızın sürekli çalışmasını sağlamak için hile, docker'da uygulamanızın çalışmasını sağlayacak bir kabuk dosyasını işaret eder. Bir start.sh dosyasıyla deneyebilirsiniz

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

Bu start.sh, hiç bitmeyen bir uygulamayı göstermelidir.

Herhangi bir uygulamanın çalışmasını istemiyorsanız, monit , docker konteynerinizin çalışmasını sağlayacak . Lütfen bu iki vakanın konteynırınızı çalışır durumda tutmanız için işe yarayıp yaramadığını bize bildirin.

Herşey gönlünce olsun


12

İstediğinizi aşağıdakilerden biriyle gerçekleştirebilirsiniz:

docker run -t -d <image-name>

veya

docker run -i -d <image-name>

veya

docker run -it -d <image-name>

Diğer yanıtlar tarafından önerilen komut parametresi (yani tail -f / dev / null) tamamen isteğe bağlıdır ve kapsayıcısının arka planda çalışmasını sağlamak için GEREKMEZ.

Ayrıca Docker belgelerinde -i ve -t seçeneklerinin birleştirilmesinin kabuk gibi davranmasına neden olacağını önerdiğini unutmayın.

Görmek:

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


9

ENTRYPOINTDocker dosyamda çalıştırmak bu kod snippet'i var :

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

Yerleşik docker görüntüsünü şu şekilde çalıştırın:

docker run -td <image name>

Konteyner kabuğuna giriş yapın:

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

bunun için sonsuz döngü oluşturduğunuz çözüm bu mu? : D
Muhammed SaLman

8

komutu aşağıdaki gibi yürütün:

docker run -t -d <image-name>

bağlantı noktasını belirtmek istiyorsanız aşağıdaki komutu verin:

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

çalışan komutu aşağıdaki komutu kullanarak doğrulayın:

docker ps

Aslında bu cevabı en çok beğeniyorum, çünkü en popüler cevap bir komuta ihtiyacınız olduğunu gösteriyor (yani tail -f / dev / null). Komut tamamen isteğe bağlıdır. Burada anahtar -t kullanmaktır. Ben de -t yerine -i iş buldum, ya da her ikisini de kullanabilirsiniz -it kombine (belgelerin bir kabuk olarak çalışacağını önerdiği gibi).
jersey fasulye

-t -dVs kullanmanın herhangi bir avantajı var mı -i -d? Her ikisi de kabı çalışır durumda tutacaktır.
wisbucky

5

Docker, ön planda çalışmaya devam etmek için komutunuzu istiyor. Aksi takdirde, uygulamalarınızın kapsayıcıyı durdurup kapattığını düşünür.

Dolayısıyla, docker giriş komut dosyanız aşağıdaki gibi bir arka plan işlemiyse:

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

'&', Daha sonra tetiklenen başka bir ön plan işlemi yoksa kabın durmasını ve çıkmasını sağlar. Bu yüzden çözüm sadece '&' işaretini kaldırmak veya sonrasında başka bir ön plan CMD'nin çalışmasını sağlamaktır .

tail -f server.log

touchBir günlük dosyası bulamamanız durumunda, önce bu dosyayı kullanmak isteyebilirsiniz .
Samuel Elh

Genellikle kuyruğum günlük dosyası, geçerli sunucu günlüğü veya yönlendirme çıkışıdır ve işlem başladıktan sonra zaten orada olmalıdır.
Hu

4

Docker kapsayıcısı içinde görev tamamlandıysa çıkar, bu nedenle herhangi bir işi olmasa veya zaten bitirmiş olsa bile hayatta kalmasını istiyorsanız yapabilirsiniz docker run -di image. Bunu yaptıktan sonra docker container lsçalıştığını göreceksiniz.


3

Belki de sadece benim ama CentOS 7.3.1611 ve Docker 1.12.6'da ama bu çalışmayı güvenilir bir şekilde elde etmek için @VonC & @Christopher Simon tarafından gönderilen cevapların bir kombinasyonunu kullanmak zorunda kaldım. Bundan önce yaptığım hiçbir şey, CMD'yi başarıyla çalıştırdıktan sonra konteynerin çıkmasını durduramaz. Oracle-xe-11Gr2 ve sshd'ye başlıyorum.

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

Sonra çalıştırmak için -d -t ve -i

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 

Sonunda saatlerce kafamı duvara daldırdıktan sonra

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

Herhangi bir nedenle, kuyruk -f kaldırılırsa veya -t -d -i seçeneklerinden herhangi biri atlanırsa, CMD yürütüldükten sonra yukarıdakiler çıkacaktır.



1

Aynı sorun vardı, sadece üzerinde bir bash ile başka bir terminal açmak benim için çalıştı:

kap oluştur:

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

başlangıç ​​kabı:

docker start 52bbc9b30557

kabı çalışır durumda tutmak için bash'ı başlat:

docker exec -it 52bbc9b30557 bash

İhtiyacınız olan süreci başlatın:

docker exec -it 52bbc9b30557 /path_to_cool_your_app

1

Dockerfile dosyanızın sonunda CMD kullanıyorsanız, yapabileceğiniz şey kodu sonuna eklemektir. Bu yalnızca docker cihazınız ubuntu veya bash kullanabilen herhangi bir işletim sistemi üzerine kurulmuşsa çalışır.

&& /bin/bash

Kısaca Dockerfile dosyanızın sonu böyle bir şeye benzeyecektir.

...

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

Dolayısıyla, docker görüntünüzü çalıştırdıktan sonra otomatik olarak çalışan bir şey varsa ve görev tamamlandığında, bash terminali docker'ınızın içinde etkin olacaktır. Böylece kabuk komutlarını girebilirsiniz.


1

Bağlantı istasyonunu etkileşimli modda çalıştırmak sorunu çözebilir.

Etkileşimli modda ve etkileşimli modda görüntü çalıştırma örneği

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

KONTEYNER KİMLİĞİ GÖRÜNTÜ KOMUTU OLUŞTURULMUŞ DURUM LİMANLARI İSİMLERİ

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

KONTEYNER KİMLİĞİ GÖRÜNTÜ KOMUT OLUŞTURULMUŞ DURUM LİMANLARI İSİMLERİ c3d6a9529fd7 test_again1.0 "bash" 2 saniye önce Yukarı 1 saniye awesome_haibt


0

konteyner üzerinde çalışmak istiyorsanız, canlı tutmak için ön planda çalıştırmanız gerekir.


-1

Bağımsız değişken siparişi önemlidir

Jersey Beans cevabı (tüm 3 örnek) benim için çalıştı. Biraz deneme yanılma sonrasında argümanların sırasının önemli olduğunu fark ettim.

Kapsayıcıyı arka planda çalışır halde tutar: docker run -t -d <image-name>

Konteyneri ön planda çalışır halde tutar: docker run <image-name> -t -d

Powershell geçmişinden geldiğim açık değildi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.