기존 Docker 컨테이너에서 명령을 어떻게 실행합니까?


492

-d대화식이 아닌 컨테이너를 만들었습니다 .

docker run -d shykes/pybuilder bin/bash

컨테이너가 종료되었음을 알 수 있습니다.

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

이제 기계에서 가끔 명령을 실행하고 종료하고 싶습니다. 응답을 받으려면

나는 기계를 시작하려고했습니다. 나는 첨부를 시도했다. run컨테이너로 전화 할 수 있다고 생각 했지만 허용되지 않는 것 같습니다. 사용하는 start것만으로도 빠르게 작동하는 것 같습니다.

종료 후 대화식 모드로 돌아가고 싶습니다.

나는 시도했다 :

docker attach d6c45e8cc5f0

그러나 나는 얻는다 :

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

그러나 시작하면 어쨌든 종료됩니다. 22를 잡아라. 나는 이길 수 없다.


도커 컨테이너가 나왔다는 것을 어떻게 알았습니까? 어떤 명령을 실행 했습니까?
— Thufir

docker container ls -a
— 브랜든 맨체스터

파일 시스템이 필요한 경우 : 다른 명령으로 중지 된 Docker 컨테이너를 시작하는 방법? (컨테이너가 중지되면 환경 변수와 메모리에있는 다른 것들이 이미 손실되었습니다.)
— Franklin Yu

답변:


548

2014 년 10 월 Docker 팀은 docker exechttps://docs.docker.com/engine/reference/commandline/exec/ 명령을 도입했습니다 .

이제 실행중인 컨테이너에서 ID (또는 이름)를 알고있는 명령을 실행할 수 있습니다.

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

주의 exec명령은 이미 실행중인 컨테이너에서 작동합니다. 컨테이너가 현재 중지 된 경우 먼저 다음 명령을 사용하여 컨테이너를 실행해야합니다.

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

여기서 가장 중요한 것은 -d옵션입니다 detached. 이는 처음에 컨테이너 ( /bin/bash)에 제공 한 명령이 백그라운드에서 실행되고 컨테이너가 즉시 중지 되지 않음을 의미 합니다 .


120
이것은 중지 된 컨테이너에서 작동하지 않으며 실행중인 컨테이너에서만 작동합니다. 따라서 질문에서와 같이 즉시 중지되는 컨테이너가 있으면 실제로 다른 컨테이너를 실행하는 데 효과적이지 않습니다.
— interfect

4
@interfect가 옳고 CDR LDN에 더 포괄적 인 답변이 있습니다.
— Dr. Jan-Philip Gehrcke

6
@ 1 월 PhilipGehrcke은 Btw는이 사람의 이름이 변경되었습니다 CDR LDN에 cdrev아래의 답변을 (위해 stackoverflow.com/a/26181666/149428 ).
— Taylor Edmiston

3
왜 지나가는가 -it?
— Iulian Onofrei

4
왜 이렇게 복잡한가요? 당신이해야 할 가장 기본적인 것 같습니다. 의도 한대로 사용해서는 안됩니다.
— sudo

287

지정한 명령 이 종료 되면 컨테이너가 종료 됩니다. 다음 옵션을 사용하여 그대로 유지하십시오.

  • -i 부착하지 않아도 STDIN을 열어 두십시오.
  • -t 의사 TTY를 할당하십시오.

따라서 새로운 run명령은 다음과 같습니다.

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

이미 실행중인 컨테이너에 연결하려는 경우 :

docker exec -it CONTAINER_ID /bin/bash

이 예에서는 /bin/bash명령으로 사용됩니다.


2
docker exec -it CONTAINER_ID /bin/bash -c "export VAR=1 && echo $VAR"빈 변수를 시도 하고 인쇄했습니다 (예상 1). 내가 무엇을 놓치고 있습니까?
— yellow01

'docker exec -it CONTAINER_ID / bin / bash'를 실행하면 bash로 올바르게 이동하지만 상호 작용할 수 없습니다.
— Blue Clouds

1
그러나 docker-compose를 사용하는 경우 -it사용할 수 없습니다.
— adnanmuttaleb

120

그래서 나는 그 대답이 위의 많은 오도 된 대답보다 간단하다고 생각합니다.

중지 된 기존 컨테이너를 시작하려면

docker start <container-name/ID>

실행중인 컨테이너를 중지하려면

docker stop <container-name/ID>

그런 다음 컨테이너의 대화식 쉘에 로그인

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

기존 컨테이너를 시작하고 하나의 명령으로 첨부하려면

docker start -ai <container-name/ID>

종료시 컨테이너가 중지됩니다. 그러나 일반적으로 컨테이너를 시작하고 완료 한 후 연결 및 중지해야합니다.


실행중인 docker attach <container-name / ID>
— KunMing Xie

9
@ 피터 T. 사실, 나는 당신의 대답이 다른 사람들이 제공 한 것보다 훨씬 간결하다는 것을 알았습니다. 사람들이 왜 매우 간단한 질문을 복잡하게 하는지를 이해하지 못합니다. 피터이 답변에 감사드립니다.
— Helen Neely

1
이것은 docker create를 할 때 -it stackoverflow.com/questions/45216612/로 수행해야합니다. 그렇지 않으면 시작되지 않습니다. 따라서 docker start <container-id>를 누른 다음 docker ps -l 시작 후에도 작동하지 않는 것을 볼 수 있습니다. 그런 다음 연결이 실패합니다. 따라서 -it로도 작성해야합니다.
— barlop

1
@Peter 가장 관련성있는 답변
— Nilanjan Sarkar

1
이것이 가장 정확한 답변입니다!
— nagendra547

91

katrmr의 답변을 확장하려면 컨테이너가 중지되어 오류로 인해 시작할 수없는 경우 이미지로 가져와야 commit합니다. 그런 다음 새 이미지에서 bash를 시작할 수 있습니다.

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

1
참고로,이 작업을 너무 많이 dshell수행하여 다양한 상황에서 자동으로 수행하도록 하는 명령 을 구성했습니다. github.com/avirshup/docker-cli-sugar
— Aaron V

41

여기에있는 답변 중 일부는 멈추지 않고 실행중인 컨테이너와 관련이 있기 때문에 오해의 소지가 있습니다.

Sven Dowideit는 Docker 포럼에서 컨테이너가 프로세스에 바인딩되어 있다고 설명했으며 Docker는 적어도 내부 구조로 인해 중지 된 컨테이너의 프로세스를 변경할 수없는 것으로 보입니다 : https://github.com/docker/docker/issues / 1437 ). 따라서 기본적으로 유일한 옵션은 commit이미지 에 대한 컨테이너 run와 다른 명령을 사용하는 것입니다.

https://forums.docker.com/t/run-command-in-stopped-container/343을 참조 하십시오
( ENTRYPOINT여전히 " with arguments"접근 방식이 작동하지 않을 것이라고 생각합니다. 중지 된 컨테이너에 대한 인수)


2
주의 : 컨테이너 bin/bash없이 실행 해도 -it컨테이너의 내용이 변경되지 않으므로 실제로 커밋 할 필요가 없으며 CDR LDN은 OP의 특정 상황에 대한 올바른 답변을 제공합니다. 여전히 commit컨테이너 프로세스를 변경하는 방법의 기술적 문제에 대한 해답입니다.
— katrmr

비활성 컨테이너의 볼륨과 함께 폐기 이미지를 사용하는 것이 좋습니다. DIR | gzip -c> ~ / mydir_backup.tgz
— eel ghEEz

이것은 질문에 대한 실제 답변입니다. 컨테이너는 프로세스에 바인딩되므로 명령을 변경할 수 없습니다.
— cjsimon

21

bash -c를 사용하여 명령을 실행해야했습니다. docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"


1
-c는 나를 위해 일했다. bash만으로는 왜 작동하지 않는지 궁금해 (프롬프트가 표시되지 않음)
— André Werlang

18

컨테이너를 만들고 하나씩 명령을 보냅니다.

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

이것이 질문에 대한 정답입니다. 작성 후 컨테이너를 시작하고 "docker exec"명령을 컨테이너에 넣으려면 docker create 명령에서 "-it"플래그를 사용하여 작성해야합니다.
— joanlofe

8

위의 CDR LDN 답변과 여기 에서 찾은 답변을 사용하여 작성한 조합 답변 입니다.

다음 예제는 이미지에서 Arch Linux 컨테이너를 시작한 다음 도구를 git사용하여 해당 컨테이너에 설치합니다 pacman.

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"

그게 다야


5

쉘 스크립트를 실행하려면 bash로 실행해야합니다.

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

4

stdin에 명령을 파이프

작동하려면를 제거해야 -t합니다.

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

CLI 옵션을 사용하는 것이 더 편리 할 수 ​​있습니다.

로 테스트 :

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

그런 다음 다른 쉘에서 :

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

그런 다음 첫 번째 쉘에서 :

ls -l myfile

Docker 1.13.1, Ubuntu 16.04 호스트에서 테스트되었습니다.


3

이미지가 기본 진입 점을 사용한다고 가정하면 /bin/sh -crunning /bin/bash은 데몬 모드 ( -d) 에서 즉시 종료됩니다 . 이 컨테이너가 대화식 쉘을 실행하도록하려면 -it대신을 사용하십시오 -d. 일반적으로 다른 프로세스를 실행하는 컨테이너에서 임의의 명령을 실행하려면 nsenter또는 을 시도 할 수 있습니다 nsinit. 자세한 내용 은 https://blog.codecentric.de/en/2014/07/enter-docker-container/ 를 참조하십시오.


3

불행히도이 목표를 달성하기 위해 ENTRYPOINT인수 로 재정의 하는 것은 불가능합니다 docker run --entrypoint.

참고 : --entrypoint를 사용하여 ENTRYPOINT 설정을 무시할 수 있지만 바이너리는 exec로만 설정할 수 있습니다 (sh -c는 사용되지 않음).


3

가장 좋은 답변은 약간의 오해의 소지가 있습니다.

실행 문제 docker run는 매번 새 컨테이너가 생성된다는 것입니다. 그러나 오래된 컨테이너를 다시 방문하거나 새 컨테이너로 공간을 차지하지 않으려는 경우가 있습니다.

(주어진 clever_bardeen컨테이너의 이름은 ...)

OP의 경우 다음 명령을 실행하여 도커 이미지가 먼저 실행되고 있는지 확인하십시오.

docker start clever_bardeen

그런 다음 다음 명령을 사용하여 도커 컨테이너를 실행하십시오.

docker exec -it clever_bardeen /bin/bash

2

Mac의 경우 :

$ docker exec -it <container-name> sh

루트 사용자로 연결하려는 경우 :

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

1

간단한 답변 : 동시에 시작하고 첨부하십시오. 이 경우에 당신은 당신이 요구 한 것을 정확하게하고 있습니다.

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

반드시 변경하십시오 <CONTAINER_ID/CONTAINER_NAME>



1

Windows 컨테이너를 실행 중이며 도커 컨테이너 내부에서 파일 및 폴더를 만들고 복사해야합니다.

이를 위해 다음 docker entrypoint 명령을 사용하여 컨테이너 내에서 명령 프롬프트를 실행하거나 컨테이너에 연결했습니다.

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

그러면 컨테이너에 연결하는 명령 프롬프트와 컨테이너를 활성 상태로 유지할 수있었습니다. :)


0

가장 최근에 종료 한 컨테이너를 재개하고 액세스하는 빠른 방법 :

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

0

나는 보통 이것을 사용합니다 :

    docker exec -it my-container-name bash

실행중인 컨테이너와 지속적으로 상호 작용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.