Bagaimana cara menjalankan perintah pada wadah Docker yang sudah ada?

493

Saya membuat wadah dengan -dsehingga tidak interaktif.

docker run -d shykes/pybuilder bin/bash

Saya melihat bahwa wadah telah keluar:

CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS                      PORTS               NAMES
d6c45e8cc5f0        shykes/pybuilder:latest   "bin/bash"          41 minutes ago      Exited (0) 2 seconds ago                        clever_bardeen

Sekarang saya ingin menjalankan perintah sesekali pada mesin dan keluar. Hanya untuk mendapat tanggapan.

Saya mencoba menyalakan mesin. Saya mencoba melampirkan. Saya pikir saya bisa menelepon rundengan sebuah wadah, tetapi itu sepertinya tidak diizinkan. Menggunakan startsepertinya berjalan dan kemudian ada dengan cepat.

Saya ingin kembali ke mode interaktif setelah keluar.

Saya mencoba:

docker attach d6c45e8cc5f0

Tapi saya mendapatkan:

2014/10/01 22:33:34 You cannot attach to a stopped container, start it first

Tetapi jika saya memulainya, itu tetap keluar. Tangkap 22. Saya tidak bisa menang.

Johnston
sumber
bagaimana Anda tahu bahwa kontainer telah keluar? perintah apa yang kamu jalankan?
Thufir
docker container ls -a
Brandon Manchester
Jika Anda hanya memerlukan sistem file: Bagaimana cara memulai wadah Docker yang berhenti dengan perintah yang berbeda? (Perhatikan bahwa variabel lingkungan dan hal-hal lain dalam memori sudah hilang ketika wadah berhenti.)
Franklin Yu

Jawaban:

548

Pada Oktober 2014 tim Docker memperkenalkan docker execperintah : https://docs.docker.com/engine/reference/commandline/exec/

Jadi sekarang Anda dapat menjalankan perintah apa pun dalam wadah yang sedang berjalan hanya dengan mengetahui ID (atau namanya):

docker exec -it <container_id_or_name> echo "Hello from container!"

Perhatikan bahwa execperintah hanya berfungsi pada wadah yang sudah berjalan. Jika kontainer saat ini dihentikan, Anda harus menjalankannya dengan perintah berikut:

docker run -it -d shykes/pybuilder /bin/bash

Yang paling penting di sini adalah -dopsi, yang merupakan kependekan detached. Ini berarti bahwa perintah yang awalnya Anda berikan ke wadah ( /bin/bash) akan dijalankan di latar belakang dan wadah tidak akan segera berhenti .

Scadge
sumber
120
Ini tidak berfungsi pada wadah yang berhenti, hanya yang berjalan. Jadi, jika Anda memiliki wadah yang segera berhenti sendiri, seperti dalam pertanyaan, ini tidak akan berfungsi untuk membuat sesuatu berjalan di dalamnya.
interfect
4
@interfect benar, dan CDR LDN memiliki jawaban yang lebih komprehensif.
Dr. Jan-Philip Gehrcke
6
@ Jan-PhilipGehrcke Btw nama pengguna orang ini telah berubah dari CDR LDNmenjadi cdrevuntuk jawaban di bawah ini ( stackoverflow.com/a/26181666/149428 ).
Taylor Edmiston
3
Kenapa lewat -it?
Iulian Onofrei
4
OMG mengapa ini sangat rumit? Sepertinya hal paling mendasar yang perlu Anda lakukan. Kita tidak boleh menggunakannya dengan cara yang mereka inginkan.
sudo
287

Wadah Anda akan keluar karena perintah yang Anda berikan akan berakhir. Gunakan opsi berikut untuk tetap aktif:

  • -i Tetap buka STDIN meskipun tidak terpasang.
  • -t Alokasikan pseudo-TTY.

Jadi runperintah baru Anda adalah:

docker run -it -d shykes/pybuilder bin/bash

Jika Anda ingin melampirkan wadah yang sudah berjalan:

docker exec -it CONTAINER_ID /bin/bash

Dalam contoh /bin/bashini digunakan sebagai perintah.

cdrev
sumber
2
Mencoba docker exec -it CONTAINER_ID /bin/bash -c "export VAR=1 && echo $VAR"dan mencetak variabel kosong (diharapkan 1). Apa yang saya lewatkan?
yellow01
setelah menjalankan 'docker exec -it CONTAINER_ID / bin / bash' ia pergi ke bash dengan benar tetapi tidak dapat berinteraksi dengannya.
Blue Clouds
1
Tetapi jika saya menggunakan docker-compose -ittidak tersedia.
adnanmuttaleb
120

Jadi saya pikir jawabannya lebih sederhana daripada banyak jawaban menyesatkan di atas.

Untuk memulai wadah yang sudah ada yang dihentikan

docker start <container-name/ID>

Untuk menghentikan wadah yang sedang berjalan

docker stop <container-name/ID>

Kemudian untuk login ke shell interaktif wadah

docker exec -it <container-name/ID> bash

Untuk memulai wadah yang ada dan melampirkannya dalam satu perintah

docker start -ai <container-name/ID>

Hati-hati, ini akan menghentikan wadah saat keluar. Tetapi secara umum, Anda harus memulai wadah, pasang dan hentikan setelah Anda selesai.

Peter T.
sumber
buruh pelabuhan melampirkan <nama wadah / ID> yang sedang berjalan
KunMing Xie
9
@ Peter T. Sebenarnya, saya menemukan jawaban Anda jauh lebih ringkas daripada yang diberikan orang lain. Saya tidak mengerti mengapa orang lebih memilih untuk mempersulit pertanyaan yang sangat sederhana. Terima kasih Peter jawaban ini.
Helen Neely
1
ini mensyaratkan bahwa ketika Anda membuat buruh pelabuhan, Anda melakukannya dengan -it stackoverflow.com/questions/45216612/... jika tidak, ia tidak akan mulai .. jadi Anda akan melakukan buruh pelabuhan memulai <container-id> dan kemudian buruh pelabuhan ps -l dan Anda akan melihat itu tidak sampai setelah start. dan kemudian lampiran akan gagal. Jadi harus buat dengan -itu juga.
barlop
1
@ Peter Jawaban yang paling relevan
Nilanjan Sarkar
1
Ini jawaban yang paling akurat!
nagendra547
91

Untuk memperluas jawaban katrmr, jika wadah dihentikan dan tidak dapat dimulai karena kesalahan, Anda harus commitmembawanya ke gambar. Kemudian Anda dapat meluncurkan bash di gambar baru:

docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
Aaron V
sumber
1
FYI, saya melakukan ini sangat banyak sehingga saya mengumpulkan perintah yang dipanggil dshelluntuk melakukannya secara otomatis dalam berbagai situasi - github.com/avirshup/docker-cli-sugar
Aaron V
41

Beberapa jawaban di sini menyesatkan karena menyangkut kontainer yang sedang berjalan, bukan berhenti.

Sven Dowideit menjelaskan di forum Docker bahwa kontainer terikat dengan proses mereka (dan Docker tidak dapat mengubah proses dari kontainer yang dihentikan, tampaknya setidaknya disebabkan oleh struktur internalnya: https://github.com/docker/docker/issues / 1437 ). Jadi, pada dasarnya satu-satunya pilihan adalah ke commitwadah dan gambarrun dengan perintah yang berbeda.

Lihat https://forums.docker.com/t/run-command-in-stopped-container/343
(saya percaya pendekatan " ENTRYPOINTdengan argumen" tidak akan berhasil, karena Anda masih tidak akan dapat mengubah argumen ke wadah yang dihentikan.)

katrmr
sumber
2
Perhatikan: berjalan bin/bashtanpa -ittidak akan mengubah apa pun dalam wadah, jadi melakukan itu tidak benar-benar diperlukan dan CDR LDN memberikan jawaban yang tepat untuk situasi khusus OP. Namun, commitadalah jawaban untuk masalah teknis tentang cara mengubah proses wadah.
katrmr
Komentar oleh candlerb di run-command-in-stops-container menyarankan untuk menggunakan gambar sekali pakai dengan volume dari wadah tidak aktif bekerja untuk saya: docker run --rm --volumes-from CONTAINER -i busybox tar cO / var / DIR | gzip -c> ~ / mydir_backup.tgz
eel ghEEz
Ini adalah jawaban aktual untuk pertanyaan yang diajukan. Kontainer terikat pada proses mereka, sehingga perintah tidak dapat diubah.
cjsimon
21

Saya harus menggunakan bash -c untuk menjalankan perintah saya: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

velop
sumber
1
-c bekerja untukku. bertanya-tanya mengapa bash saja tidak akan berhasil (tidak mendapatkan prompt)
André Werlang
18

Membuat wadah dan mengirim perintah kepadanya, satu per satu:

docker create --name=my_new_container -it ubuntu
docker start my_new_container
// ps -a says 'Up X seconds'
docker exec my_new_container /path/to/my/command
// ps -a still says 'Up X+Y seconds'
docker exec my_new_container /path/to/another/command
langlauf.io
sumber
Ini adalah jawaban yang bagus untuk pertanyaan itu. Jika Anda ingin memulai wadah setelah membuat dan dapat "perintah docker exec" ke dalamnya, Anda harus membuatnya dengan bendera "-it" di perintah pembuat docker.
joanlofe
8

Ini adalah jawaban gabungan yang saya buat menggunakan jawaban LDN CDR di atas dan jawaban yang saya temukan di sini .

Contoh berikut memulai wadah Arch Linux dari gambar, dan kemudian menginstal gitpada wadah itu menggunakan pacmanalat:

sudo docker run -it -d archlinux /bin/bash
sudo docker ps -l
sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm"

Itu semuanya.

imriss
sumber
5

Jika Anda mencoba menjalankan skrip shell, Anda perlu menjalankannya sebagai bash.

docker exec -it containerid bash -c /path/to/your/script.sh
MrKulli
sumber
4

Pipa perintah ke stdin

Harus menghapus -tagar berfungsi:

echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash

Ini kadang lebih nyaman jika menggunakan opsi CLI.

Diuji dengan:

sudo docker run --name ub16 -it ubuntu:16.04 bash

lalu pada shell lain:

echo 'touch myfile' | sudo docker exec -i ub16 bash

Kemudian pada shell pertama:

ls -l myfile

Diuji pada Docker 1.13.1, host Ubuntu 16.04.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
3

Dengan asumsi gambar menggunakan titik masuk default /bin/sh -c, menjalankan /bin/bashakan segera keluar dalam mode daemon ( -d). Jika Anda ingin wadah ini menjalankan shell interaktif, gunakan -itsebagai ganti -d. Jika Anda ingin menjalankan perintah sewenang-wenang dalam sebuah wadah yang biasanya menjalankan proses lain, Anda mungkin ingin mencoba nsenteratau nsinit. Lihat https://blog.codecentric.de/en/2014/07/enter-docker-container/ untuk detailnya.

Andreas Steffan
sumber
3

Sayangnya tidak mungkin untuk menimpa ENTRYPOINTdengan argumen dengan docker run --entrypointuntuk mencapai tujuan ini.

Catatan: Anda dapat mengganti pengaturan ENTRYPOINT menggunakan --entrypoint, tetapi ini hanya dapat mengatur biner ke exec (tidak ada sh -c yang akan digunakan).

wieczorek1990
sumber
3

Saya ingin mencatat bahwa jawaban teratas sedikit menyesatkan.

Masalah dengan eksekusi docker run adalah bahwa wadah baru dibuat setiap saat. Namun, ada beberapa kasus di mana kami ingin mengunjungi kembali wadah lama atau tidak menghabiskan ruang dengan wadah baru.

(Diberikan clever_bardeen adalah nama wadah yang dibuat ...)

Dalam kasus OP, pastikan gambar buruh pelabuhan pertama kali berjalan dengan menjalankan perintah berikut:

docker start clever_bardeen

Kemudian, jalankan wadah buruh pelabuhan menggunakan perintah berikut:

docker exec -it clever_bardeen /bin/bash
Josh
sumber
2

Untuk Mac:

$ docker exec -it <container-name> sh

jika Anda ingin terhubung sebagai pengguna root:

$ docker exec -u 0 -it <container-name> sh
Lyncean Patel
sumber
1

Jawaban sederhana: mulai dan lampirkan secara bersamaan. Dalam hal ini Anda melakukan persis apa yang Anda minta.

docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME> 

pastikan untuk berubah <CONTAINER_ID/CONTAINER_NAME>

pengguna353305
sumber
1
# docker exec -d container_id command 

Ex:

# docker exec -d xcdefrdtt service jira stop 
Rajesh Gurram
sumber
1

Saya menjalankan wadah windows dan saya perlu melihat ke dalam wadah buruh pelabuhan untuk file dan folder yang dibuat dan disalin.

Untuk melakukan itu, saya menggunakan perintah entry docker berikut untuk mendapatkan command prompt berjalan di dalam wadah atau melampirkan ke wadah.

ENTRYPOINT ["C:\\Windows\\System32\\cmd.exe", "-D", "FOREGROUND"]

Itu membantu saya untuk command prompt melampirkan wadah dan menjaga wadah tetap hidup. :)

Jenish Rabadiya
sumber
0

Cara cepat untuk melanjutkan dan mengakses wadah yang terakhir keluar:

docker start -a -i `docker ps -q -l`
Pierz
sumber
0

Saya biasanya menggunakan ini:

    docker exec -it my-container-name bash

untuk terus berinteraksi dengan wadah yang sedang berjalan.

Amin Shojaei
sumber