Mevcut bir Docker kapsayıcısında nasıl komut çalıştırırım?


492

-dEtkileşimli olmayan bir kap oluşturdum .

docker run -d shykes/pybuilder bin/bash

Konteynerin çıktığını görüyorum:

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

Şimdi makinede ara sıra komutları çalıştırmak ve çıkmak istiyorum. Sadece cevabı almak için.

Makineyi çalıştırmayı denedim. Takmayı denedim. runBir konteyner ile arayabileceğimi düşündüm , ama buna izin verilmiyor gibi görünüyor. Kullanmak startkoşmak gibi görünüyor ve sonra hızla var.

Çıktıktan sonra etkileşimli moda geri dönmek istiyorum.

Denedim:

docker attach d6c45e8cc5f0

Ama anladım:

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

Ama eğer başlatırsam, yine de çıkar. Yakala 22. Kazanamıyorum.


liman işçisi konteynerinin çıktığını nasıl bildiniz? hangi komutu çalıştırdın?
17'de Thufir

docker container ls -a
Brandon Manchester

Sadece dosya sistemine ihtiyacınız varsa: Farklı bir komutla durdurulmuş bir Docker kapsayıcısı nasıl başlatılır? (Konteyner durduğunda ortam değişkenleri ve bellekteki diğer şeylerin zaten kaybolduğunu unutmayın.)
Franklin Yu

Yanıtlar:


548

Ekim 2014'te Docker ekibi şu docker execkomutu tanıttı : https://docs.docker.com/engine/reference/commandline/exec/

Artık çalışan bir kapsayıcıda kimliğini (veya adını) bilerek herhangi bir komutu çalıştırabilirsiniz:

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

execKomutun yalnızca zaten çalışmakta olan kapsayıcıda çalıştığını unutmayın . Kap şu anda durdurulmuşsa, önce aşağıdaki komutla çalıştırmanız gerekir:

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

Buradaki en önemli şey, -dseçeneği temsil eden seçenektir detached. Bu, konteynere ( /bin/bash) ilk başta verdiğiniz komutun arka planda çalıştırılacağı ve kabın hemen durmayacağı anlamına gelir .


120
Bu, durdurulan bir kapta çalışmaz, sadece çalışan bir kapta çalışır. Yani, soruda olduğu gibi, kendisini hemen durduran bir kabınız varsa, bu aslında içinde başka bir şey çalıştırmak için işe yaramaz.
interfect

4
@interfect doğru ve CDR LDN'nin daha kapsamlı bir cevabı var.
Dr.Jan-Philip Gehrcke

6
@ Jan-PhilipGehrcke Btw bu kişinin adı değişti CDR LDNiçin cdrevaşağıda cevabını (için stackoverflow.com/a/26181666/149428 ).
Taylor Edmiston

3
Neden geçiyorsun -it?
Iulian Onofrei

4
aman tanrım bu neden bu kadar karmaşık? Yapmanız gereken en temel şey gibi görünüyor. Amaçlanan şekilde kullanmamalıyız.
sudo

287

Kapsayıcınız edecek çıkmak bunu sona erecek verdi komutu olarak. Canlı kalmasını sağlamak için aşağıdaki seçenekleri kullanın:

  • -i Takılmasa bile STDIN'i açık tutun.
  • -t Bir sözde TTY tahsis edin.

Yani yeni runkomutunuz:

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

Halihazırda çalışan bir kaba eklemek istiyorsanız:

docker exec -it CONTAINER_ID /bin/bash

Bu örneklerde /bin/bashkomut olarak kullanılmıştır.


2
Denenmiş docker exec -it CONTAINER_ID /bin/bash -c "export VAR=1 && echo $VAR"ve basılmış boş değişken (beklenen 1). Neyi kaçırıyorum?
yellow01

'docker exec -it CONTAINER_ID / bin / bash' komutunu çalıştırdıktan sonra bash'a doğru gider, ancak onunla etkileşime giremez.
Blue Clouds

1
Ama eğer docker-compose kullanıyorsanız -itbu kullanılamaz.
adnanmuttaleb

120

Bu yüzden cevabın yukarıdaki birçok yanıltıcı cevaptan daha basit olduğunu düşünüyorum.

Durdurulmuş var olan bir kapsayıcıyı başlatmak için

docker start <container-name/ID>

Çalışan bir kapsayıcıyı durdurmak için

docker stop <container-name/ID>

Ardından, bir kabın etkileşimli kabuğuna giriş yapmak için

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

Mevcut bir kapsayıcıyı başlatmak ve tek bir komutta eklemek için

docker start -ai <container-name/ID>

Dikkat edin, bu çıkışta kabı durduracaktır. Ancak genel olarak, kabı başlatmanız, bitirdikten sonra takmanız ve durdurmanız gerekir.


liman işçisi çalışmakta olan <container-name / ID>
kodunu ekleyin

9
@Peter T. Aslında, cevabınızı başkalarının verdiklerinden çok daha özlü buldum. İnsanların neden çok basit bir soruyu zorlaştırmayı tercih ettiğini anlamıyorum. Teşekkürler Peter bu cevap.
Helen Neely

1
bunun için docker oluşturduğunuzda -it stackoverflow.com/questions/45216612/… ile başlamanız gerekir, aksi takdirde başlamaz .. böylece docker start <container-id> ve sonra docker ps -l ve başladıktan sonra bitmediğini göreceksiniz. ve sonra ek başarısız olur. Yani -it ile de yaratmalıyız.
barlop

1
@Peter En alakalı cevap
Nilanjan Sarkar

1
Bu en doğru cevap!
nagendra547

91

Katrmr'ın cevabını genişletmek için, kap durdurulmuşsa ve bir hata nedeniyle başlatılamıyorsa, commitbir resme vermeniz gerekir . Ardından bash'ı yeni görüntüde başlatabilirsiniz:

docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image

1
FYI, bunu o kadar çok yapıyorum ki dshell, çeşitli durumlarda otomatik olarak yapmak için çağrılan bir komutu bir araya getirdim
Aaron V

41

Buradaki cevapların bazıları yanıltıcıdır, çünkü çalışan, durmayan kaplarla ilgilidir.

Sven Dowideit, Docker forumunda kapsayıcıların işlemlerine bağlı olduğunu açıkladı (ve Docker, görünüşte en azından iç yapısından dolayı, durmuş bir kapsayıcı sürecini değiştiremez: https://github.com/docker/docker/issues / 1437 ). Yani, temelde tek seçenek commitbir görüntüye kapsayıcı ve runfarklı bir komutla.

Bkz. Https://forums.docker.com/t/run-command-in-stopped-container/343
("Bağımsız ENTRYPOINTdeğişkenlerle" yaklaşımının da işe yaramayacağına inanıyorum , çünkü hala değiştiremezsiniz. durdurulan bir kapsayıcıya ilişkin argümanlar.)


2
Uyarı: bin/basholmadan çalışmak -itkaptaki hiçbir şeyi değiştirmez, bu yüzden bunu yapmak gerçekten gerekli değildir ve CDR LDN OP'nin özel durumu için doğru cevabı verir. Yine de, commitkonteyner sürecinin nasıl değiştirileceğine ilişkin teknik sorunun cevabıdır.
15:15

Durdurulan kapsayıcıdaki run-command-in-stop-konteynırındaki yorum, etkin olmayan kapsayıcıdan gelen hacimle bir atanabilir görüntü kullanmayı önerdi: docker run --rm --volumes-from CONTAINER -i busybox tar cO / var / DIR | gzip -c> ~ / mydir_backup.tgz
eel ghEEz

Bu, sorulan sorunun gerçek cevabıdır. Kapsayıcılar işlemlerine bağlıdır, bu nedenle komut değiştirilemez.
cjsimon

21

Komutumu çalıştırmak için bash -c kullanmak zorunda kaldım: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"


1
-c benim için çalıştı. neden
bash'ın

18

Bir kapsayıcı oluşturma ve komutları tek tek gönderme:

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

Bu sorunun iyi cevabı. Oluşturduktan sonra kapsayıcıyı başlatmak ve içine "docker exec" komutları gönderebilmek istiyorsanız, docker create komutundaki "-it" bayraklarıyla oluşturmalısınız.
joanlofe

8

Bu, yukarıdaki CDR LDN cevabını ve burada bulduğum cevabı kullanarak oluşturduğum birleşik bir cevap .

Aşağıdaki örnek bir Arch Linux kapsayıcısını bir görüntüden başlatır gitve pacmanaracı kullanarak bu kapsayıcıya yüklenir :

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"

Hepsi bu.


5

Kabuk betiğini çalıştırmaya çalışıyorsanız, bunu bash olarak çalıştırmanız gerekir.

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

4

Stdin'e bir emir vermek

-tÇalışması için kaldırılmalıdır :

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

Bu bazen CLI seçeneklerini kullanmaktan daha uygun olabilir.

Şununla test edildi:

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

sonra başka bir kabukta:

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

Sonra ilk kabukta:

ls -l myfile

Docker 1.13.1, Ubuntu 16.04 ana bilgisayarında test edildi.


3

Görüntünün varsayılan giriş noktasını kullandığını varsayarsak /bin/sh -c, çalışma /bin/bashdaemon modunda hemen çıkar ( -d). Bu kabın etkileşimli bir kabuk çalıştırmasını istiyorsanız, -ityerine kullanın -d. Genellikle başka bir işlemi yürüten bir kapta rasgele komutlar yürütmek istiyorsanız, nsenterveya seçeneğini deneyebilirsiniz nsinit. Göz at https://blog.codecentric.de/en/2014/07/enter-docker-container/ detaylar için.


3

Maalesef bu hedefe ulaşmak için ENTRYPOINTtartışmaları geçersiz kılmak imkansızdır docker run --entrypoint.

Not: --entrypoint kullanarak ENTRYPOINT ayarını geçersiz kılabilirsiniz, ancak bu yalnızca ikili dosyayı exec olarak ayarlayabilir (sh -c kullanılmaz).


3

Üst cevabın biraz yanıltıcı olduğunu belirtmek isterim.

Yürütmeyle ilgili sorun, docker runher seferinde yeni bir kapsayıcı oluşturulmasıdır. Ancak, eski konteynırları tekrar ziyaret etmek veya yeni konteynırlarla yer kaplamamak istediğimiz durumlar vardır.

(Verilen clever_bardeenkonteynerin adıdır ...)

OP durumunda, docker görüntüsünün ilk önce aşağıdaki komutu uygulayarak çalıştığından emin olun:

docker start clever_bardeen

Ardından, aşağıdaki komutu kullanarak docker kapsayıcısını yürütün:

docker exec -it clever_bardeen /bin/bash

2

Mac için:

$ docker exec -it <container-name> sh

root kullanıcısı olarak bağlanmak istiyorsanız:

$ docker exec -u 0 -it <container-name> sh

1

Basit cevap: aynı anda başlayın ve ekleyin. Bu durumda tam olarak ne istediğinizi yaparsınız.

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

değiştiğinden emin ol <CONTAINER_ID/CONTAINER_NAME>


1
# docker exec -d container_id command 

Ör:

# docker exec -d xcdefrdtt service jira stop 

1

Windows kapsayıcısı çalıştırıyorum ve oluşturulan ve kopyalanan dosyalar ve klasör için docker kapsayıcısına bakmam gerekiyor.

Bunu yapmak için kapsayıcı içinde çalışan veya kapsayıcıya komut istemi almak için docker giriş noktası komutunu kullandım.

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

Bu, hem komut istemine kapsayıcıya ekleme ve kapsayıcıyı canlı tutmama yardımcı oldu. :)


0

En son çıkan kapsayıcıya devam etmenin ve erişmenin hızlı bir yolu:

docker start -a -i `docker ps -q -l`

0

Genellikle bunu kullanıyorum:

    docker exec -it my-container-name bash

çalışan bir konteyner ile sürekli etkileşim için.

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.