Wadah buruh pelabuhan akan otomatis berhenti setelah "buruh pelabuhan menjalankan -d"

333

Menurut tutorial yang saya baca sejauh ini, gunakan " docker run -d" akan memulai sebuah wadah dari gambar, dan wadah itu akan berjalan di latar belakang. Begini tampilannya, kita bisa melihat kita sudah memiliki id kontainer.

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

Tetapi jika saya berlari " docker ps", tidak ada yang dikembalikan.

Jadi saya mencoba " docker ps -a", saya dapat melihat wadah sudah keluar:

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

Adakah yang saya lakukan salah? Bagaimana saya bisa memecahkan masalah ini?

John
sumber
1
"buruh pelabuhan menjalankan halo-dunia" <== bekerja dengan sempurna, tetapi jika saya menjalankan "buruh pelabuhan menjalankan-halo-dunia", saya masih tidak bisa mendapatkan wadah yang berjalan.
J John
5
Saya memiliki masalah yang serupa tetapi saya membuatnya bekerja dengan menggunakan docker run -it -d <image> /bin/bashini memulai bash shell secara interaktif dan tidak menutup wadah karena proses shell aktif.
Rtsne42

Jawaban:

495

The CentOS dockerfile memiliki perintah default bash.

Itu berarti, ketika dijalankan di latar belakang ( -d), shell segera keluar.

Perbarui 2017

Versi terbaru dari buruh pelabuhan mengizinkan untuk menjalankan wadah baik dalam mode terpisah dan dalam mode latar depan ( -t, -iatau -it)

Dalam hal ini, Anda tidak memerlukan perintah tambahan dan ini sudah cukup:

docker run -t -d centos

Pesta akan menunggu di latar belakang.
Yang awalnya dilaporkan di kalyani-chaudhari 's jawaban dan rinci dalam jersey kacang ' s jawaban .

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

Perhatikan bahwa untuk alpine , Marinos An melaporkan dalam komentar :

docker run -t -d alpine/gittidak melanjutkan proses.
Harus dilakukan:docker run --entrypoint "/bin/sh" -it alpine/git


Jawaban asli (2015)

Seperti disebutkan dalam artikel ini :

Alih-alih berjalan dengan docker run -i -t image your-command, -ddisarankan menggunakan karena Anda dapat menjalankan wadah Anda hanya dengan satu perintah dan Anda tidak perlu melepaskan terminal kontainer dengan menekan Ctrl+ P+ Q.

Namun, ada masalah dengan -dopsi. Wadah Anda segera berhenti kecuali perintah tidak berjalan di latar depan .
Docker membutuhkan perintah Anda untuk terus berjalan di latar depan. Kalau tidak, ia berpikir bahwa aplikasi Anda berhenti dan mematikan wadah.

Masalahnya adalah beberapa aplikasi tidak berjalan di latar depan. Bagaimana kita bisa membuatnya lebih mudah?

Dalam situasi ini, Anda dapat menambah tail -f /dev/nullperintah Anda.
Dengan melakukan ini, bahkan jika perintah utama Anda berjalan di latar belakang, wadah Anda tidak berhenti karena ekor terus berjalan di latar depan.

Jadi ini akan berhasil:

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

A docker psakan menunjukkan wadah centos masih berjalan.

Dari sana, Anda dapat melampirkan atau melepaskannya (atau docker execbeberapa perintah).

VONC
sumber
Maaf, satu pertanyaan lagi, saya harus menjalankan skrip saat startup, sepertinya /etc/rc.d/rc.local tidak lagi berfungsi (pola pikir saya masih memperlakukan buruh pelabuhan seperti OS), saya menganggap file buruh pelabuhan adalah pilihan yang lebih baik dalam hal ini kasus?
J John
5
@GuruprasadGV Itu yang diharapkan. Alih-alih menggunakan docker attach, gunakan docker exec -it <yourContainer> bash.
VonC
3
Ini juga berfungsi jika Anda menambahkan perintah ekor di akhir file entrypoint.
yara
2
Saya menggunakan sshd sebagai perintah terakhir saya (lama berjalan). Anda kemudian dapat ssh pada wadah Anda juga seperti pada VM (setelah Anda mengatur .ssh / official_keys dll) ... Anda juga dapat melanjutkan untuk mengkonfigurasi wadah menggunakan ansible.
andrew pate
1
Saya akhirnya melakukan ini untuk mengeksekusi perintah saya ditambah perbaikan lama yang tercantum di atas: buruh pelabuhan menjalankan image_name / bin / bash -c "my / command && tail -f / dev / null"
Geordie
58

Menurut jawaban ini , menambahkan -tbendera akan mencegah wadah keluar saat berjalan di latar belakang. Anda kemudian dapat menggunakan docker exec -i -t <image> /bin/bashuntuk masuk ke prompt shell.

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

Tampaknya opsi -t tidak didokumentasikan dengan baik , meskipun bantuan mengatakan bahwa "mengalokasikan pseudo-TTY."

cjsimon
sumber
10
Bagus. Tampak kurang tail -f /dev/null
hacky
Terima kasih! Jika ini membantu seseorang, ini tidak berlaku baik di Emacs Eshell.
Peter Becich
2
docker run -t -d --name mysql -p 3306:3306 mysql- tidak bekerja untuk saya (ubuntu 14.04.5): STATUS = Keluar (1) 4 detik yang lalu
Putnik
Saya menemukan bahwa Anda tidak perlu <perintah> di sini, kecuali jika Anda mau. Anehnya, ini juga berfungsi untuk mengganti -t dengan -i (interaktif). Doc tidak menyebutkan penggunaan -t dan -i yang dikombinasikan akan berperilaku seperti sebuah shell.
Kacang jersey
44

Latar Belakang

Wadah Docker menjalankan proses ("perintah" atau "titik masuk") yang membuatnya tetap hidup. Kontainer akan terus berjalan selama perintah terus berjalan.

Dalam kasus Anda, perintah ( /bin/bash, secara default, aktif centos:latest) segera keluar (seperti yang dilakukan bash ketika tidak terhubung ke terminal dan tidak ada yang dijalankan).

Biasanya, ketika Anda menjalankan sebuah wadah dalam mode daemon (dengan -d), wadah menjalankan semacam proses daemon (seperti httpd). Dalam hal ini, selama daemon httpd berjalan, wadah akan tetap hidup.

Apa yang Anda coba lakukan adalah menjaga wadah tetap hidup tanpa proses daemon berjalan di dalam wadah. Ini agak aneh (karena wadah tidak melakukan sesuatu yang berguna sampai Anda berinteraksi dengannya, mungkin dengan docker exec), tetapi ada beberapa kasus di mana masuk akal untuk melakukan sesuatu seperti ini.

(Apakah Anda bermaksud untuk mendapatkan bash prompt di dalam wadah? Itu mudah! docker run -it centos:latest)

Larutan

Cara sederhana untuk menjaga wadah tetap hidup dalam mode daemon tanpa batas adalah dengan menjalankannya sleep infinitysebagai perintah penampung. Ini tidak mengandalkan melakukan hal-hal aneh seperti mengalokasikan TTY dalam mode daemon. Meskipun tidak mengandalkan melakukan hal-hal aneh seperti menggunakan sleepsebagai perintah utama Anda.

$ 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

Solusi alternatif

Seperti yang ditunjukkan oleh cjsimon, -topsi mengalokasikan "pseudo-tty". Trik ini gagal terus berjalan tanpa batas karena dianggap terhubung ke TTY interaktif (meskipun Anda tidak memiliki cara untuk berinteraksi dengan TTY tertentu jika Anda tidak lulus -i). Bagaimanapun, ini harus melakukan trik juga:

$ docker run -t -d centos:latest

Tidak 100% yakin apakah -takan menghasilkan interaksi aneh lainnya; mungkin tinggalkan komentar di bawah jika ya.

mkasberg
sumber
Perhatikan bahwa ini tidak berfungsi pada alpine karena tidur BusyBox tidak dapat diterima infinity.
John Kugelman
ini membantu saya memecahkan masalah gambar amazon-linux, terima kasih
influen
18

Hai masalah ini karena wadah buruh pelabuhan keluar jika tidak ada aplikasi yang berjalan di dalam wadah.

-d 

opsi hanya menjalankan wadah dalam mode deamon.

Jadi trik untuk membuat wadah Anda terus berjalan adalah arahkan ke file shell di docker yang akan membuat aplikasi Anda tetap berjalan. Anda dapat mencoba dengan file start.sh

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

Start.sh ini harus mengarah ke aplikasi yang tidak pernah berakhir.

Jika Anda tidak ingin aplikasi apa pun berjalan, Anda dapat menginstal monityang akan membuat wadah buruh pelabuhan Anda tetap berjalan. Beri tahu kami jika kedua kasing ini berfungsi agar wadah Anda tetap beroperasi.

Semua yang terbaik

Pratik
sumber
12

Anda dapat mencapai apa yang Anda inginkan dengan:

docker run -t -d <image-name>

atau

docker run -i -d <image-name>

atau

docker run -it -d <image-name>

Parameter perintah seperti yang disarankan oleh jawaban lain (mis. Tail -f / dev / null) sepenuhnya opsional, dan TIDAK diperlukan untuk membuat wadah Anda tetap berjalan di latar belakang.

Perhatikan juga dokumentasi Docker menyarankan bahwa menggabungkan opsi -i dan -t akan membuatnya berperilaku seperti shell.

Lihat:

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

kacang jersey
sumber
9

Saya menjalankan potongan kode ini dari ENTRYPOINTdalam file docker saya:

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

Jalankan gambar buruh pelabuhan yang dibangun sebagai:

docker run -td <image name>

Masuk ke shell kontainer:

docker exec -it <container id> /bin/bash
Binita Bharati
sumber
apakah ini solusi yang Anda buat loop tak terbatas untuk ini? : D
Muhammad SaLman
8

jalankan perintah sebagai berikut:

docker run -t -d <image-name>

jika Anda ingin menentukan port maka perintah seperti di bawah ini:

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

verifikasi wadah berjalan menggunakan perintah berikut:

docker ps
kalyani chaudhari
sumber
Saya benar-benar menyukai jawaban ini yang terbaik, karena jawaban paling populer menunjukkan bahwa Anda memerlukan perintah (yaitu tail -f / dev / null). Perintah ini sepenuhnya opsional. Kuncinya di sini adalah menggunakan -t. Saya juga menemukan -i bekerja di tempat -t, atau Anda juga dapat menggunakan keduanya-itu dikombinasikan (seperti dokumentasi menunjukkan itu akan berjalan sebagai shell).
Kacang jersey
Apakah ada keuntungan menggunakan -t -dvs -i -d? Keduanya akan menjaga wadah tetap berjalan.
wisbucky
5

Docker membutuhkan perintah Anda untuk terus berjalan di latar depan. Kalau tidak, ia berpikir bahwa aplikasi Anda berhenti dan mematikan wadah.

Jadi jika skrip entri buruh pelabuhan Anda adalah proses latar belakang seperti berikut:

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

Tanda '&' membuat wadah berhenti dan keluar jika tidak ada proses latar depan lain yang dipicu nanti. Jadi solusinya hanya menghapus '&' atau memiliki CMD foreground lain setelahnya , seperti

tail -f server.log
Peiming Hu
sumber
Mungkin ingin touchfile itu dulu, kalau-kalau Anda tidak dapat menemukan file log.
Samuel Elh
Biasanya file log yang saya tail adalah log server saat ini atau output redirection, yang seharusnya sudah ada setelah proses dimulai.
Peiming Hu
4

Wadah Docker keluar jika tugas di dalamnya selesai, jadi jika Anda ingin tetap hidup meskipun tidak memiliki pekerjaan atau sudah menyelesaikannya, Anda dapat melakukannya docker run -di image. Setelah Anda melakukannya, docker container lsAnda akan melihatnya berjalan.

Vrangz
sumber
3

Mungkin hanya saya tetapi pada CentOS 7.3.1611 dan Docker 1.12.6 tetapi saya akhirnya harus menggunakan kombinasi jawaban yang diposting oleh @VonC & @Christopher Simon untuk mendapatkan pekerjaan ini dengan andal. Tidak ada yang saya lakukan sebelum ini akan menghentikan wadah keluar setelah menjalankan CMD dengan sukses. Saya memulai oracle-xe-11Gr2 dan 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

Kemudian tambahkan -d -t dan -i untuk dijalankan

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 

Akhirnya setelah berjam-jam memukul kepala saya ke dinding

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

Untuk alasan apa pun di atas akan keluar setelah mengeksekusi CMD jika tail -f dihapus, atau opsi -t -d -i dihilangkan.

steven87vt
sumber
1

Saya memiliki masalah yang sama, hanya membuka terminal lain dengan bash di atasnya bekerja untuk saya:

buat wadah:

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

mulai wadah:

docker start 52bbc9b30557

mulai bash untuk menjaga wadah berjalan:

docker exec -it 52bbc9b30557 bash

mulai proses yang Anda butuhkan:

docker exec -it 52bbc9b30557 /path_to_cool_your_app
Aduh
sumber
1

Jika Anda menggunakan CMD di akhir Dockerfile Anda, yang bisa Anda lakukan adalah menambahkan kode di akhir. Ini hanya akan berfungsi jika buruh pelabuhan Anda dibangun di ubuntu, atau OS apa pun yang dapat menggunakan bash.

&& /bin/bash

Secara singkat ujung Dockerfile Anda akan terlihat seperti ini.

...

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

Jadi, jika Anda memiliki sesuatu yang berjalan secara otomatis setelah Anda menjalankan gambar buruh pelabuhan Anda, dan ketika tugas selesai terminal bash akan aktif di dalam buruh pelabuhan Anda. Dengan demikian, Anda dapat memasukkan perintah shell Anda.

Ekin
sumber
1

Menjalankan buruh pelabuhan dengan mode interaktif mungkin menyelesaikan masalah.

Berikut adalah contoh untuk menjalankan gambar dengan dan tanpa mode interaktif

chaitra @ RSK-IND-BLR-L06: ~ / buruh pelabuhan $ sudo buruh pelabuhan menjalankan -d -t -i test_again1.0 b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18

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

KOMANDA ID GAMBAR PERINTAH NAMA STATUS BUATAN STATUS

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

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

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c3d6a9529fd7 test_again1.0 "bash" 2 detik yang lalu Naik 1 detik awesome_haibt

Chaitra
sumber
0

jika Anda ingin beroperasi pada wadah, Anda harus menjalankannya di latar depan agar tetap hidup.

lwpro2
sumber
-1

Urutan argumen penting

Jersey Beans answer (ketiga contoh) bekerja untuk saya. Setelah sedikit trial and error saya menyadari bahwa urutan argumen itu penting.

Membuat wadah tetap berjalan di latar belakang: docker run -t -d <image-name>

Membuat wadah tetap berjalan di latar depan: docker run <image-name> -t -d

Bagi saya tidak jelas berasal dari latar belakang Powershell.

HVL71
sumber