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ć.


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 .


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.


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.


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

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).


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"


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

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.


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

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.


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/ .


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).


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

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

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>


1
# docker exec -d container_id command 

Dawny:

# docker exec -d xcdefrdtt service jira stop 

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. :)


0

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

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

0

Zwykle używam tego:

    docker exec -it my-container-name bash

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.