Dockerexecを使用してDockerコンテナでコマンドを実行する方法
序章
Docker は、開発者がポータブルで一貫性のあるLinuxコンテナーを作成および管理するのに役立つコンテナー化ツールです。
コンテナを開発またはデプロイするときは、実行中のコンテナの内部を調べて、現在の状態を調べたり、問題をデバッグしたりする必要があります。 この目的のために、Dockerはdocker exec
コマンドを提供して、すでに実行されているコンテナーでプログラムを実行します。
このチュートリアルでは、docker exec
コマンドと、それを使用してコマンドを実行し、実行中のDockerコンテナーでインタラクティブシェルを取得する方法について学習します。
前提条件
このチュートリアルでは、Dockerが既にインストールされており、ユーザーがdocker
を実行する権限を持っていることを前提としています。 root ユーザーとしてdocker
を実行する必要がある場合は、このチュートリアルのコマンドの前にsudo
を付けることを忘れないでください。
sudo
アクセスなしでDockerを使用する方法の詳細については、Dockerチュートリアルのインストール方法のSudoなしでDockerコマンドを実行する」セクションを参照してください。
テストコンテナの開始
docker exec
コマンドを使用するには、実行中のDockerコンテナーが必要です。 コンテナがまだない場合は、次のdocker run
コマンドを使用してテストコンテナを開始します。
docker run -d --name container-name alpine watch "date >> /var/log/date.log"
このコマンドは、公式アルパインイメージから新しいDockerコンテナを作成します。 これは、軽量で最小限のLinuxディストリビューションである AlpineLinuxを使用する人気のあるLinuxコンテナーイメージです。
-d
フラグを使用して、コンテナーをターミナルから切り離し、バックグラウンドで実行します。 --name container-name
は、コンテナにcontainer-name
という名前を付けます。 ここで好きな名前を選択するか、これを完全に省略して、Dockerに新しいコンテナーの一意の名前を自動的に生成させることができます。
次に、alpine
があります。これは、コンテナーに使用するイメージを指定します。
そして最後にwatch "date >> /var/log/date.log"
があります。 これは、コンテナで実行するコマンドです。 watch
は、デフォルトで2秒ごとに、指定されたコマンドを繰り返し実行します。 この場合、watch
が実行するコマンドはdate >> /var/log/date.log
です。 date
は、次のように現在の日付と時刻を出力します。
OutputFri Jul 23 14:57:05 UTC 2021
コマンドの>> /var/log/date.log
部分は、date
からの出力をリダイレクトし、ファイル/var/log/date.log
に追加します。 2秒ごとに新しい行がファイルに追加され、数秒後には次のようになります。
OutputFri Jul 23 15:00:26 UTC 2021 Fri Jul 23 15:00:28 UTC 2021 Fri Jul 23 15:00:30 UTC 2021 Fri Jul 23 15:00:32 UTC 2021 Fri Jul 23 15:00:34 UTC 2021
次のステップでは、Dockerコンテナーの名前を見つける方法を学習します。 これは、ターゲットにしているコンテナがすでにあるが、その名前がわからない場合に役立ちます。
Dockerコンテナの名前を見つける
docker exec
に、操作するコンテナーの名前(またはコンテナーID)を指定する必要があります。 この情報は、docker ps
コマンドを使用して見つけることができます。
docker ps
このコマンドは、サーバー上で実行されているすべてのDockerコンテナーを一覧表示し、それらに関するいくつかの高レベルの情報を提供します。
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76aded7112d4 alpine "watch 'date >> /var…" 11 seconds ago Up 10 seconds container-name
この例では、コンテナIDと名前が強調表示されています。 どちらを使用しても、使用するコンテナをdocker exec
に指示できます。
コンテナの名前を変更する場合は、docker rename
コマンドを使用します。
docker rename container-name new-name
次に、docker exec
を使用して、実行中のDockerコンテナーでコマンドを実行するいくつかの例を実行します。
Dockerコンテナでのインタラクティブシェルの実行
Dockerコンテナー内で対話型シェルを開始する必要がある場合、おそらくファイルシステムを探索したり、実行中のプロセスをデバッグしたりする場合は、-i
フラグと-t
フラグを指定してdocker exec
を使用します。
-i
フラグは、コンテナーへの入力を開いたままにし、-t
フラグは、シェルが接続できる疑似端末を作成します。 これらのフラグは、次のように組み合わせることができます。
docker exec -it container-name sh
これにより、指定されたコンテナでsh
シェルが実行され、基本的なシェルプロンプトが表示されます。 コンテナを終了するには、exit
と入力し、ENTER
を押します。
exit
コンテナイメージにbash
などのより高度なシェルが含まれている場合は、上記のsh
をbash
に置き換えることができます。
Dockerコンテナでの非対話型コマンドの実行
実行中のDockerコンテナー内でコマンドを実行する必要があるが、対話機能は必要ない場合は、フラグなしでdocker exec
コマンドを使用します。
docker exec container-name tail /var/log/date.log
このコマンドは、container-name
コンテナでtail /var/log/date.log
を実行し、結果を出力します。 デフォルトでは、tail
コマンドはファイルの最後の10行を出力します。 最初のセクションで設定したデモコンテナを実行している場合は、次のように表示されます。
OutputMon Jul 26 14:39:33 UTC 2021 Mon Jul 26 14:39:35 UTC 2021 Mon Jul 26 14:39:37 UTC 2021 Mon Jul 26 14:39:39 UTC 2021 Mon Jul 26 14:39:41 UTC 2021 Mon Jul 26 14:39:43 UTC 2021 Mon Jul 26 14:39:45 UTC 2021 Mon Jul 26 14:39:47 UTC 2021 Mon Jul 26 14:39:49 UTC 2021 Mon Jul 26 14:39:51 UTC 2021
これは基本的に、Dockerコンテナーの対話型シェルを開いて(前の手順でdocker exec -it container-name sh
を使用して行ったように)、tail /var/log/date.log
コマンドを実行するのと同じです。 ただし、このコマンドは、シェルを開いてコマンドを実行してからシェルを閉じるのではなく、疑似端末を開かずに1つのコマンドで同じ出力を返します。
Dockerコンテナの代替ディレクトリでコマンドを実行する
コンテナの特定のディレクトリでコマンドを実行するには、--workdir
フラグを使用してディレクトリを指定します。
docker exec --workdir /tmp container-name pwd
このコマンド例では、/tmp
ディレクトリを作業ディレクトリとして設定してから、pwd
コマンドを実行します。これにより、現在の作業ディレクトリが出力されます。
Output/tmp
pwd
コマンドは、作業ディレクトリが/tmp
であることを確認しました。
Dockerコンテナで別のユーザーとしてコマンドを実行する
コンテナ内で別のユーザーとしてコマンドを実行するには、--user
フラグを追加します。
docker exec --user guest container-name whoami
これは、 guest ユーザーを使用して、コンテナーでwhoami
コマンドを実行します。 whoami
コマンドは、現在のユーザーのユーザー名を出力します。
Outputguest
whoami
コマンドは、コンテナーの現在のユーザーがguestであることを確認します。
Dockerコンテナへの環境変数の受け渡し
実行するコマンドとともに、環境変数をコンテナに渡す必要がある場合があります。 -e
フラグを使用すると、環境変数を指定できます。
docker exec -e TEST=sammy container-name env
このコマンドは、TEST
環境変数をsammy
と等しくなるように設定してから、コンテナー内でenv
コマンドを実行します。 次に、env
コマンドは、すべての環境変数を出力します。
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy HOME=/root
TEST
変数はsammy
に設定されます。
複数の変数を設定するには、それぞれに対して-e
フラグを繰り返します。
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
環境変数でいっぱいのファイルを渡したい場合は、--env-file
フラグを使用して渡すことができます。
まず、テキストエディタでファイルを作成します。 ここでnano
を使用して新しいファイルを開きますが、使い慣れた任意のエディターを使用できます。
nano .env
ファイル名として.env
を使用しています。これは、これらの種類のファイルを使用してバージョン管理外の情報を管理するための一般的な標準です。
次のように、KEY=value
変数を1行に1つずつファイルに書き込みます。
.env
TEST=sammy ENVIRONMENT=prod
ファイルを保存して閉じます。 ファイルを保存してnano
を終了するには、CTRL+O
、ENTER
の順に押して保存し、CTRL+X
を押して終了します。
次に、docker exec
コマンドを実行し、--env-file
の後に正しいファイル名を指定します。
docker exec --env-file .env container-name env
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy ENVIRONMENT=prod HOME=/root
ファイル内の2つの変数が設定されます。
複数の--env-file
フラグを使用して、複数のファイルを指定できます。 ファイル内の変数が互いに重複している場合、コマンドの最後にリストされているファイルが前のファイルを上書きします。
一般的なエラー
docker exec
コマンドを使用すると、いくつかの一般的なエラーが発生する場合があります。
Error: No such container: container-name
No such container
エラーは、指定されたコンテナーが存在しないことを意味し、コンテナー名のスペルが間違っている可能性があります。 docker ps
を使用して、実行中のコンテナーをリストし、名前を再確認してください。
Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running
このnot running
メッセージは、コンテナーが存在するが停止していることを意味します。 docker start container-name
でコンテナを起動できます
Error response from daemon: Container container-name is paused, unpause the container before exec
Container is paused
エラーは、問題をかなりよく説明しています。 続行する前に、docker unpause container-name
でコンテナの一時停止を解除する必要があります。
結論
このチュートリアルでは、実行中のDockerコンテナーでコマンドを実行する方法と、実行時に使用できるいくつかのコマンドラインオプションについて学習しました。
Docker全般の詳細については、 Dockerタグページ 、Dockerチュートリアル、Docker関連のQ&Aページなどへのリンクがあります。
Dockerのインストールについては、 Ubuntu20.04にDockerをインストールして使用する方法をご覧ください。