Jak uruchomić polecenie na już istniejącym kontenerze Docker?

492

Stworzyłem pojemnik, -dwięc nie jest interaktywny.

docker run -d shykes/pybuilder bin/bash

Widzę, że kontener wyszedł:

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

Teraz chciałbym uruchamiać sporadyczne polecenia na komputerze i wychodzić. Tylko po to, by uzyskać odpowiedź.

Próbowałem uruchomić maszynę. Próbowałem dołączyć. Myślałem, że mogę zadzwonić runz kontenerem, ale wydaje się to niedozwolone. Korzystanie startwydaje się działać, a następnie szybko istnieć.

Chciałbym wrócić do trybu interaktywnego po wyjściu.

Próbowałem:

docker attach d6c45e8cc5f0

Ale dostaję:

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

Ale jeśli zacznę, i tak wychodzi. Złap 22. Nie mogę wygrać.

Johnston
źródło
skąd wiedziałeś, że kontener dokujący wyszedł? jakie polecenie wykonałeś?
Thufir
docker container ls -a
Brandon Manchester,
Jeśli potrzebujesz tylko systemu plików: Jak uruchomić zatrzymany kontener Docker za pomocą innego polecenia? (Należy pamiętać, że zmienne środowiskowe i inne rzeczy w pamięci są już tracone, gdy kontener się zatrzyma).
Franklin Yu

Odpowiedzi:

548

W październiku 2014 r. Zespół dokerów wprowadził docker execpolecenie : https://docs.docker.com/engine/reference/commandline/exec/

Teraz możesz uruchomić dowolne polecenie w działającym kontenerze, znając tylko jego identyfikator (lub nazwę):

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

Zauważ, że execpolecenie działa tylko na już działającym kontenerze. Jeśli kontener jest obecnie zatrzymany, musisz go najpierw uruchomić za pomocą następującego polecenia:

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

Najważniejszą rzeczą jest tutaj -dopcja, która oznacza detached. Oznacza to, że polecenie, które początkowo podałeś kontenerowi ( /bin/bash), zostanie uruchomione w tle, a kontener nie zatrzyma się natychmiast .

Scadge
źródło
120
To nie działa na zatrzymanym kontenerze, tylko na działającym. Więc jeśli masz pojemnik, który natychmiast się zatrzymuje, tak jak w pytaniu, to tak naprawdę nie zadziała, aby uruchomić w nim coś innego.
interfect
4
@interfect ma rację, a CDR LDN ma bardziej wyczerpującą odpowiedź.
Dr Jan-Philip Gehrcke
6
@ Jan-PhilipGehrcke Btw nazwa użytkownika tej osoby zmieniła się z CDR LDNna cdrevdla odpowiedzi poniżej ( stackoverflow.com/a/26181666/149428 ).
Taylor Edmiston
3
Po co przechodzić -it?
Iulian Onofrei
4
omg, dlaczego to takie skomplikowane? Wydaje się to najbardziej podstawową rzeczą, którą musisz zrobić. Nie wolno nam używać go tak, jak zamierzają.
sudo
287

Twój kontener zostanie zamknięty, ponieważ wydane polecenie zakończy się. Użyj następujących opcji, aby utrzymać go na żywo:

  • -i Trzymaj STDIN otwarty, nawet jeśli nie jest podłączony.
  • -t Przydziel pseudo-TTY.

Więc twoje nowe runpolecenie to:

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

Jeśli chcesz dołączyć do już działającego kontenera:

docker exec -it CONTAINER_ID /bin/bash

W tych przykładach /bin/bashzastosowano jako polecenie.

cdrev
źródło
2
Sprawdzona docker exec -it CONTAINER_ID /bin/bash -c "export VAR=1 && echo $VAR"i wydrukowana pusta zmienna (oczekiwana 1). czego mi brakuje?
żółty 01
po uruchomieniu „docker exec -it CONTAINER_ID / bin / bash” przechodzi do basha poprawnie, ale nie może z nim współdziałać.
Blue Clouds,
1
Ale jeśli korzystam z komponentu dokującego, -itnie jest on dostępny.
adnanmuttaleb
120

Myślę więc, że odpowiedź jest prostsza niż wiele mylących odpowiedzi powyżej.

Aby uruchomić istniejący kontener, który jest zatrzymany

docker start <container-name/ID>

Aby zatrzymać działający kontener

docker stop <container-name/ID>

Następnie, aby zalogować się do interaktywnej powłoki kontenera

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

Aby uruchomić istniejący kontener i dołączyć do niego jednym poleceniem

docker start -ai <container-name/ID>

Uwaga, spowoduje to zatrzymanie pojemnika przy wyjściu. Ale ogólnie rzecz biorąc, musisz uruchomić pojemnik, dołączyć i zatrzymać go po zakończeniu.

Peter T.
źródło
docker attach <nazwa-kontenera / identyfikator>, który jest uruchomiony
KunMing Xie
9
@Peter T. Właściwie znalazłem twoją odpowiedź o wiele bardziej zwięzłą niż to, co podali inni. Nie rozumiem, dlaczego ludzie wolą skomplikować bardzo proste pytanie. Dzięki Peter, ta odpowiedź.
Helen Neely
1
wymaga to, aby po utworzeniu okna dokowanego zrobiłeś to z -it stackoverflow.com/questions/45216612/... w przeciwnym razie nie uruchomi się on, więc uruchomisz okno dokowane <container-id>, a następnie doker ps -l i zobaczysz, że nie jest uruchomiony po starcie. i wtedy dołączenie się nie powiedzie. Więc też muszę stworzyć z -it.
barlop
1
@Peter Najbardziej odpowiednia odpowiedź
Nilanjan Sarkar
1
To jest najdokładniejsza odpowiedź!
nagendra547,
91

Aby rozwinąć odpowiedź katrmr, jeśli kontener jest zatrzymany i nie można go uruchomić z powodu błędu, musisz committo zrobić na obrazie. Następnie możesz uruchomić bash na nowym obrazku:

docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
Aaron V.
źródło
1
Do twojej wiadomości, robię to tak bardzo, że stworzyłem polecenie wywoływane, dshellaby zrobić to automatycznie w różnych sytuacjach - github.com/avirshup/docker-cli-sugar
Aaron V
41

Niektóre odpowiedzi tutaj wprowadzają w błąd, ponieważ dotyczą kontenerów, które są uruchomione, a nie zatrzymane.

Sven Dowideit wyjaśnił na forum Dockera, że ​​kontenery są związane z ich procesem (a Docker nie może zmienić procesu zatrzymanego kontenera, najwyraźniej z powodu jego wewnętrznej struktury: https://github.com/docker/docker/issues / 1437 ). Zasadniczo jedyną opcją jest commitprzejście do kontenera na obraz i runza pomocą innego polecenia.

Zobacz https://forums.docker.com/t/run-command-in-stopped-container/343
(Wierzę, że ENTRYPOINTpodejście „ z argumentami” też nie zadziałałoby, ponieważ nadal nie będziesz w stanie zmienić argumenty do zatrzymanego kontenera).

katrmr
źródło
2
Uwaga: uruchomienie bin/bashbez -itzmiany nie zmieni niczego w kontenerze, więc zatwierdzenie tego nie jest tak naprawdę konieczne, a CDR LDN daje właściwą odpowiedź na konkretną sytuację PO. Nadal commitjest odpowiedzią na techniczny problem zmiany procesu kontenerowego.
katrmr
Dla mnie zadziałał komentarz candlerb z run-command-in-zatrzymany-kontener sugerujący użycie zrzutu obrazu z woluminem z nieaktywnego kontenera: docker run --rm --volumes-from CONTAINER -i busybox tar cO / var / DIR | gzip -c> ~ / mydir_backup.tgz
węgorz ghEEz
To jest faktyczna odpowiedź na zadane pytanie. Kontenery są powiązane z procesem, więc polecenia nie można zmienić.
cjsimon
21

Musiałem użyć bash -c, aby uruchomić polecenie: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

velop
źródło
1
-c pracował dla mnie. zastanawiam się, dlaczego sam bash nie zadziała (nie wyświetla monitu)
André Werlang
18

Tworzenie kontenera i wysyłanie do niego poleceń, jeden po drugim:

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
źródło
To dobra odpowiedź na pytanie. Jeśli chcesz uruchomić kontener po utworzeniu i móc w nim wykonywać polecenia „docker exec”, musisz go utworzyć za pomocą flag „-it” w poleceniu create dokera.
joanlofe,
8

To jest połączona odpowiedź, którą wymyśliłem przy użyciu powyższej odpowiedzi CDR LDN i odpowiedzi, którą znalazłem tutaj .

Poniższy przykład uruchamia kontener Arch Linux z obrazu, a następnie instaluje się gitw tym kontenerze za pomocą pacmannarzędzia:

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"

To wszystko.

imriss
źródło
5

Jeśli próbujesz uruchomić skrypt powłoki, musisz uruchomić go jako bash.

docker exec -it containerid bash -c /path/to/your/script.sh
MrKulli
źródło
4

Potokuj polecenie, aby rozpocząć

Musisz usunąć -t, aby działało:

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

Może to być wygodniejsze niż czasami korzystanie z opcji CLI.

Testowane z:

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

następnie na innej powłoce:

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

Następnie na pierwszej powłoce:

ls -l myfile

Testowany na Docker 1.13.1, host Ubuntu 16.04.

Ciro Santilli
źródło
3

Zakładając, że obraz używa domyślnego punktu wejścia /bin/sh -c, uruchamianie /bin/bashnatychmiast zakończy działanie w trybie demona ( -d). Jeśli chcesz, aby ten kontener uruchamiał interaktywną powłokę, użyj -itzamiast -d. Jeśli chcesz wykonać dowolne polecenia w kontenerze zwykle wykonującym inny proces, możesz spróbować nsenterlub nsinit. Szczegółowe informacje można znaleźć na https://blog.codecentric.de/en/2014/07/enter-docker-container/ .

Andreas Steffan
źródło
3

Niestety nie można zastąpić ENTRYPOINTargumentami, docker run --entrypointaby osiągnąć ten cel.

Uwaga: możesz zastąpić ustawienie ENTRYPOINT za pomocą --entrypoint, ale może to tylko ustawić plik binarny na exec (nie będzie używane SH-C).

wieczorek1990
źródło
3

Chciałbym zauważyć, że najlepsza odpowiedź jest nieco myląca.

Problem z wykonywaniem docker run polega na tym, że za każdym razem tworzony jest nowy kontener. Są jednak przypadki, w których chcielibyśmy ponownie odwiedzić stare pojemniki lub nie zajmować miejsca z nowymi pojemnikami.

(Dany clever_bardeen jest nazwa utworzonego kontenera ...)

W przypadku OP upewnij się, że obraz dokera jest najpierw uruchomiony, wykonując następujące polecenie:

docker start clever_bardeen

Następnie uruchom kontener dokowania za pomocą następującego polecenia:

docker exec -it clever_bardeen /bin/bash
Josh
źródło
2

Dla Maca:

$ docker exec -it <container-name> sh

jeśli chcesz połączyć się jako użytkownik root:

$ docker exec -u 0 -it <container-name> sh
Lyncean Patel
źródło
1

Prosta odpowiedź: zacznij i dołącz jednocześnie. W tym przypadku robisz dokładnie to, o co prosiłeś.

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

pamiętaj o zmianie <CONTAINER_ID/CONTAINER_NAME>

użytkownik353305
źródło
1
# docker exec -d container_id command 

Dawny:

# docker exec -d xcdefrdtt service jira stop 
Rajesh Gurram
źródło
1

Korzystam z kontenera systemu Windows i muszę zajrzeć do kontenera dokera w poszukiwaniu plików i folderów utworzonych i skopiowanych.

Aby to zrobić, użyłem następującego polecenia docker entrypoint, aby uruchomić wiersz polecenia w kontenerze lub dołączyć do kontenera.

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

Pomogło mi to zarówno w podłączeniu wiersza polecenia do kontenera, jak i utrzymaniu kontenera w stanie aktywnym. :)

Jenish Rabadiya
źródło
0

Szybki sposób na wznowienie i dostęp do ostatnio opuszczonego kontenera:

docker start -a -i `docker ps -q -l`
Pierz
źródło
0

Zwykle używam tego:

    docker exec -it my-container-name bash

do ciągłej interakcji z działającym kontenerem.

Amin Shojaei
źródło