既存のDockerコンテナでコマンドを実行するにはどうすればよいですか?


493

でコンテナを作成した-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.勝てない。


dockerコンテナーが終了したことをどのようにして知りましたか?どのコマンドを実行しましたか?
Thufir 2017年

docker container ls -a
ブランドンマンチェスター

ファイルシステムだけが必要な場合:停止したDockerコンテナーを別のコマンドで開始する方法は?(コンテナーが停止すると、メモリ内の環境変数やその他のものはすでに失われていることに注意してください。)
フランクリンユー

回答:


548

2014年10月、Dockerチームはdocker execコマンドを導入しましたhttps : //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
これは停止したコンテナでは機能せず、実行中のコンテナでのみ機能します。したがって、質問のように、それ自体をすぐに停止するコンテナがある場合、これは実際には内部で何かを実行するようには機能しません。
2015

4
@interfectは正解で、CDR LDNにはより包括的な答えがあります。
Jan-Philip Gehrcke博士、2015年

6
@ Jan-PhilipGehrckeところで、この人のユーザー名は、以下の回答のためにからCDR LDNに変更されcdrevました(stackoverflow.com/a/26181666/149428)。
テイラーエドミストン2016年

3
なぜ合格-it
Iulian Onofrei 2017

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

既存のコンテナを開始して1つのコマンドでそれにアタッチするには

docker start -ai <container-name/ID>

注意してください、これは出口でコンテナを停止します。ただし、一般的には、コンテナーを開始し、完了後にアタッチして停止する必要があります。


実行中の
docker

9
@ピーター・T。実際、私はあなたの答えが他の人が提供したものよりもずっと簡潔であることに気づきました。人々が非常に単純な質問を複雑にすることを好む理由がわかりません。ピーター、この回答に感謝します。
Helen Neely 2017

1
これは、あなたがドッキングウィンドウを作成しなかったとき、あなたは-itでそれをやったことが必要です stackoverflow.com/questions/45216612/... それ以外の場合は、あなたがドッキングウィンドウの開始<コンテナ-id>を行うと思います..だから開始し、ドッキングウィンドウのps -lませんそして、あなたはそれが開始後アップしていないことがわかります。そして、アタッチは失敗します。したがって、-itも使用して作成する必要があります。
barlop

1
@ピーター最も適切な答え
Nilanjan Sarkar '29

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引数付き」のアプローチは、変更することができないため、どちらも機能しないと思います。停止したコンテナへの引数。)


2
注意:bin/bashなしで実行-itしてもコンテナーの内容は変更されないため、コミットする必要はなく、CDR LDNはOPの特定の状況に適切な答えを与えます。それでも、commitコンテナープロセスを変更する方法の技術的な問題への答えです。
katrmr 2015年

run-command-in-stopped-containerのcandlerbによるコメントは、非アクティブなコンテナーからのボリュームで使い捨てイメージを使用することを提案しました:docker run --rm --volumes-from CONTAINER -i busybox tar cO / var / DIR | gzip -c>〜/ mydir_backup.tgz
eel ghEEz 2016年

これは、尋ねられた質問に対する実際の回答です。コンテナはプロセスにバインドされているため、コマンドを変更することはできません。
cjsimon

21

コマンドを実行するには、bash -cを使用する必要がありました。 docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"


1
-cは私のために働いた。不思議なぜbashが一人で考えていない作業(プロンプトを取得しません)
アンドレ・Werlang

18

コンテナーを作成し、コマンドを1つずつコンテナーに送信します。

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

コマンドを標準入力にパイプする

-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 -c、running /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イメージが最初に実行されていることを確認します。

docker start clever_bardeen

次に、次のコマンドを使用してdockerコンテナーを実行します。

docker exec -it clever_bardeen /bin/bash

2

Mac用:

$ docker exec -it <container-name> sh

rootユーザーとして接続する場合:

$ 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コンテナー内で確認する必要があります。

そのために、次のdocker entrypointコマンドを使用して、コンテナー内でコマンドプロンプトを実行するか、コンテナーにアタッチしました。

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

これにより、コマンドプロンプトをコンテナーにアタッチし、コンテナーをライブに保つことができました。:)


0

最近終了したコンテナを再開してアクセスする簡単な方法:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.