Docker Exec:Dockerでコマンドを実行するためのGotoコマンド


甲斐正堂: これまでDockerコンテナの内部で何が起こっているか見る必要がありましたか?コンテナは冪等性を持つように設計されています:問題が発生した場合、新しいコンテナを展開します。しかし、人生はそんなに単純ではありません。問題を特定するためにコンテナ内でコマンドを実行する必要があります。ここでdocker execコマンドが役立ちます。

この記事では、docker execコマンドを使用して実行中のDockerコンテナでコマンドを実行する方法を学びます。

前提条件

この記事の例に従うには、以下を守る必要があります。

  • Docker Desktopの最新バージョンがWindows、Linux、またはmacOSで動作します。このチュートリアルでは、Windows 10で実行されているv3.1.0を使用しています。

NGINXコンテナの起動

Docker execはコンテナ内でコマンドを実行します。ただし、その前に実行するコンテナが必要です。Dockerイメージをダウンロードし、デモコンテナを作成することから始めましょう。

  1. 新しいディレクトリを作成し、このチュートリアルではC:\gitrepos\testを使用して、コンテナで使用されるファイルを保持します。

2. ファイルを作成し、dockerfile(拡張子なし)という名前を付け、以下のコードを含めます。このDockerfileは、コンテナを作成するための手順を定義します。

FROM nginx:alpine
 COPY index.html /usr/share/nginx/html/index.html

3. 次に、同じディレクトリに、index.htmlという名前のファイルを作成し、以下のコードを含めます。これはHTMLファイルであり、コンテナが起動されるとHello Worldメッセージが表示されます。

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
    <title>Hello World - Nginx Docker</title> 
    <style> 
       h1{ font-weight:lighter; font-family: Arial, Helvetica, sans-serif; 
       } 
    </style> 
    </head> 
    <body> 
       <h1> 
          Hello World 
       </h1> 

    </body> 
    </html>

4. これで、Nginx Dockerコンテナを作成します。Dockerfileが現在の作業ディレクトリにあるため、Dockerエンジンにそこを見るように指示するには、 . を指定します。また、将来の参照のためにtパラメータを使用してコンテナにmy-ngnixのタグを付けるようにしてください。

docker build -t my-nginx .
Creating a Docker container with the build command.

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

# rm - Dockerにコンテナが停止した後に削除するように通知
# d - コマンドが実行された後にコマンドラインの制御を返す
# p - 内部コンテナポート80を外部ポート80にマップdocker run --rm -d -p 80:80 my-nginx
Start the container with the Docker run command.

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

Output of the running NGINX container.

Running Commands with Docker Exec

Dockerコンテナでコマンドを実行する際、対話的にコマンドを実行する必要がある場合があります。対話的なコマンドを実行すると、コマンドを入力してフィードバックを受け取り、別のコマンドを入力するなどの操作ができます。対話的なコマンドはセッションを占有し、他の操作ができなくなります。

しかし、事前にコンテナに送信するコマンドをすでに知っていて、バックグラウンドでコマンドを実行したい場合はどうなるでしょうか?その場合は、対話的でないコマンドを実行することができます。対話的でないコマンドは、コマンドをDockerに送信し、すぐにコンソールの制御を返すことができます。

コンテナの名前とIDの特定

コンテナが構築されたら、コンテナ内でコマンドを実行できます。コマンドを実行する前に、NGINXコンテナの名前またはIDを特定してください。名前またはIDのいずれかをDockerコマンドで使用することができます。そのため、名前よりもIDを覚える方が難しいかもしれません!

実行中のコンテナの情報を表示するには、Docker psコマンドを実行して次の情報を出力します。

docker ps
Displaying running Docker containers.

一意のIDであるe17e4b6be01aまたはランダムに生成された名前mystifying_chandrasekharのいずれかをクリップボードにコピーして後で使用してください。

Docker Execを使用して非対話的なコマンドを実行する

非対話的なコマンドを実行する例として、以下のコマンドをコピーして実行し、/var/logディレクトリ内のファイルの一覧をls -lコマンドで表示します。コンテナ名mystifying_chandrasekharの後にあるものを、Docker execコマンドに渡してください。

docker exec mystifying_chandrasekhar ls -l /var/log
Executing a directory listing within the NGINX container.

Dockerコマンドを使用してコンソール出力を回避する方法

ユーザーにシェル制御をすぐに返すことで、大規模な操作はコンソールを占有しません。デタッチドdオプションを使用してコンソール出力を回避します。以下のコマンドは、コンテナ内でtouchコマンドを使用してファイル/tmp/execWorksを作成し、コンソールに出力を表示しません。

docker exec -d mystifying_chandrasekhar touch /tmp/execWorks

Docker Execを使用して対話型コマンドを実行する

ここまでで、docker execを使用して非対話型のコマンドをDockerコンテナ内で実行する方法を学びました。ただし、コンテナをトラブルシューティングする必要がある場合、たとえば、コンテナに対してコマンドを対話的に発行する必要がある場合があります。その場合は、対話型でコマンドを実行する必要があります。

docker execを使用してコマンドを対話的に実行するには、iオプションとtオプションが必要です。 iオプションはSTDINを開いたままにし、コンテナにコマンドを送信できるようにします。 tオプションは、コマンドを入力するための疑似TTY(PTY)、通信チャネルを割り当てます。

実行中のDockerコンテナでBourne(sh)シェルを使用して対話型のコマンドプロンプトを開くには、次のコマンドをコピーして貼り付けます。プロンプトが/ #に変わります。

docker exec -it mystifying_chandrasekhar sh
Running an interactive Docker shell.

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

ls -l /var/log
exit
Open an interactive command prompt to the container.

特定のディレクトリで対話型プロンプトを開くには、wオプションにディレクトリのパスを渡し、Dockerに指定したディレクトリでシェルを起動するように指示します。

実行中のコンテナに環境変数を渡す

多くのプログラムは、起動時に設定を行うために環境変数を使用します。例えば、ほとんどのJavaアプリケーションは、JAVA_HOME環境変数をJavaのパスに設定する必要があります。

eオプションを使用してセッションに環境変数を渡すことができます。たとえば、実行中のコンテナにMYVAR="<some value>"というキー/値のペアを提供する必要がある場合は、以下に示すようにeオプションを使用します。

docker exec -it -e MYVAR="hello" mystifying_chandrasekhar sh
echo $MYVAR
Pass environment variables

ファイルを使用した環境変数の渡し方

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

env-vars.txtという名前のテキストファイルを作成し、渡す環境変数とその値を指定します。このファイルの名前は任意であり、.txt拡張子は必要ありません。

Text file with environmental variables defined.

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

# env-vars.txtファイルを渡して対話型プロンプトを開きます
docker exec -it --env-file env-vars.txt mystifying_chandrasekhar sh
# Dockerコンテナ内で環境変数が利用可能かどうかを確認します
echo $MYVAR
echo $FOO
echo $SOMETHING
Passing a environmental variables file to Docker and verifying the environment variables exist in the container.

別のユーザーとして実行中のコンテナとの対話

本番環境では、アプリケーションはしばしば特定のユーザーとして実行され、アクセスが制限されます。本番環境でアプリケーションを特定のユーザーとして実行している場合は、コマンドをテストする際も同様にする必要があります。

この例では、Dockerコンテナがnginxユーザーとして実行されています。コンテナをnginxアカウントとして開始するようにDockerに指示するには、wオプションにユーザーを渡します。コンテナ内から実行されるwhoamiコマンドによって、nginxユーザーが実際に使用されていることが確認されます。

docker exec -it -u nginx mystifying_chandrasekhar sh
whoami
Running the container as the nginx user.

次のステップ

docker execコマンドを使用して実行中のコンテナ内でコマンドを実行する方法を学びました。実行中のコンテナに入り、照会するためにexecコマンドを利用することで、Dockerコンテナのトラブルシューティングに強力な新しいツールを手に入れました。

これで、学んだことをさらに進めて、単一のファイルをコピーするのではなく、Gitバージョン管理を使用して静的ウェブサイトをコンテナに取り込んでみてください。Gitが初めての方には、記事Visual Studio CodeとGitの初心者ガイドが役立ちます。

Source:
https://adamtheautomator.com/docker-exec/