甲斐正堂: これまでDockerコンテナの内部で何が起こっているか見る必要がありましたか?コンテナは冪等性を持つように設計されています:問題が発生した場合、新しいコンテナを展開します。しかし、人生はそんなに単純ではありません。問題を特定するためにコンテナ内でコマンドを実行する必要があります。ここでdocker exec
コマンドが役立ちます。
この記事では、docker exec
コマンドを使用して実行中のDockerコンテナでコマンドを実行する方法を学びます。
前提条件
この記事の例に従うには、以下を守る必要があります。
- Docker Desktopの最新バージョンがWindows、Linux、またはmacOSで動作します。このチュートリアルでは、Windows 10で実行されているv3.1.0を使用しています。
NGINXコンテナの起動
Docker exec
はコンテナ内でコマンドを実行します。ただし、その前に実行するコンテナが必要です。Dockerイメージをダウンロードし、デモコンテナを作成することから始めましょう。
- 新しいディレクトリを作成し、このチュートリアルではC:\gitrepos\testを使用して、コンテナで使用されるファイルを保持します。
2. ファイルを作成し、dockerfile(拡張子なし)という名前を付け、以下のコードを含めます。このDockerfileは、コンテナを作成するための手順を定義します。
3. 次に、同じディレクトリに、index.htmlという名前のファイルを作成し、以下のコードを含めます。これはHTMLファイルであり、コンテナが起動されるとHello Worldメッセージが表示されます。
4. これで、Nginx Dockerコンテナを作成します。Dockerfileが現在の作業ディレクトリにあるため、Dockerエンジンにそこを見るように指示するには、 .
を指定します。また、将来の参照のためにt
パラメータを使用してコンテナにmy-ngnix
のタグを付けるようにしてください。

5. これで、コンテナが構築されたので、Docker runコマンドでコンテナを起動します。

6. 最後に、ウェブブラウザを開いてhttp://localhost/
に移動して、以下を確認します。

Running Commands with Docker Exec
Dockerコンテナでコマンドを実行する際、対話的にコマンドを実行する必要がある場合があります。対話的なコマンドを実行すると、コマンドを入力してフィードバックを受け取り、別のコマンドを入力するなどの操作ができます。対話的なコマンドはセッションを占有し、他の操作ができなくなります。
しかし、事前にコンテナに送信するコマンドをすでに知っていて、バックグラウンドでコマンドを実行したい場合はどうなるでしょうか?その場合は、対話的でないコマンドを実行することができます。対話的でないコマンドは、コマンドをDockerに送信し、すぐにコンソールの制御を返すことができます。
コンテナの名前とIDの特定
コンテナが構築されたら、コンテナ内でコマンドを実行できます。コマンドを実行する前に、NGINXコンテナの名前またはIDを特定してください。名前またはIDのいずれかをDockerコマンドで使用することができます。そのため、名前よりもIDを覚える方が難しいかもしれません!
実行中のコンテナの情報を表示するには、Docker ps
コマンドを実行して次の情報を出力します。

一意のIDであるe17e4b6be01a
またはランダムに生成された名前mystifying_chandrasekhar
のいずれかをクリップボードにコピーして後で使用してください。
Docker Execを使用して非対話的なコマンドを実行する
非対話的なコマンドを実行する例として、以下のコマンドをコピーして実行し、/var/logディレクトリ内のファイルの一覧をls -l
コマンドで表示します。コンテナ名mystifying_chandrasekhar
の後にあるものを、Docker exec
コマンドに渡してください。

Dockerコマンドを使用してコンソール出力を回避する方法
ユーザーにシェル制御をすぐに返すことで、大規模な操作はコンソールを占有しません。デタッチドd
オプションを使用してコンソール出力を回避します。以下のコマンドは、コンテナ内でtouch
コマンドを使用してファイル/tmp/execWorksを作成し、コンソールに出力を表示しません。
Docker Execを使用して対話型コマンドを実行する
ここまでで、docker exec
を使用して非対話型のコマンドをDockerコンテナ内で実行する方法を学びました。ただし、コンテナをトラブルシューティングする必要がある場合、たとえば、コンテナに対してコマンドを対話的に発行する必要がある場合があります。その場合は、対話型でコマンドを実行する必要があります。
docker exec
を使用してコマンドを対話的に実行するには、i
オプションとt
オプションが必要です。 i
オプションはSTDINを開いたままにし、コンテナにコマンドを送信できるようにします。 t
オプションは、コマンドを入力するための疑似TTY(PTY)、通信チャネルを割り当てます。
実行中のDockerコンテナでBourne(sh)シェルを使用して対話型のコマンドプロンプトを開くには、次のコマンドをコピーして貼り付けます。プロンプトが/ #
に変わります。

シェルに入ったら、最後にコンテナ内からファイルの一覧を表示するために以下のコマンドを実行します。最後に、対話型シェルを終了するためにexit
コマンドを実行します。

特定のディレクトリで対話型プロンプトを開くには、
w
オプションにディレクトリのパスを渡し、Dockerに指定したディレクトリでシェルを起動するように指示します。
実行中のコンテナに環境変数を渡す
多くのプログラムは、起動時に設定を行うために環境変数を使用します。例えば、ほとんどのJavaアプリケーションは、JAVA_HOME
環境変数をJavaのパスに設定する必要があります。
e
オプションを使用してセッションに環境変数を渡すことができます。たとえば、実行中のコンテナにMYVAR="<some value>"
というキー/値のペアを提供する必要がある場合は、以下に示すようにe
オプションを使用します。

ファイルを使用した環境変数の渡し方
多くの環境変数がある場合や共有の構成がある場合は、それらの変数をファイルに保存すると便利です。ファイルを--env-file
オプションでDockerに相対パスまたは絶対パスで渡します。この技術は、コンテナに安全な資格情報を提供するためによく使用されます。資格情報をバージョン管理にコミットしないように注意してください!
env-vars.txt
という名前のテキストファイルを作成し、渡す環境変数とその値を指定します。このファイルの名前は任意であり、.txt
拡張子は必要ありません。

env-file
オプションを使用して環境変数をDockerに渡します。変数が利用可能かどうかは、以下のスクリーンショットに示すようにecho
コマンドで確認してください。

別のユーザーとして実行中のコンテナとの対話
本番環境では、アプリケーションはしばしば特定のユーザーとして実行され、アクセスが制限されます。本番環境でアプリケーションを特定のユーザーとして実行している場合は、コマンドをテストする際も同様にする必要があります。
この例では、Dockerコンテナがnginx
ユーザーとして実行されています。コンテナをnginx
アカウントとして開始するようにDockerに指示するには、w
オプションにユーザーを渡します。コンテナ内から実行されるwhoami
コマンドによって、nginx
ユーザーが実際に使用されていることが確認されます。

nginx
user.次のステップ
docker exec
コマンドを使用して実行中のコンテナ内でコマンドを実行する方法を学びました。実行中のコンテナに入り、照会するためにexec
コマンドを利用することで、Dockerコンテナのトラブルシューティングに強力な新しいツールを手に入れました。
これで、学んだことをさらに進めて、単一のファイルをコピーするのではなく、Gitバージョン管理を使用して静的ウェブサイトをコンテナに取り込んでみてください。Gitが初めての方には、記事Visual Studio CodeとGitの初心者ガイドが役立ちます。