【図解】Dockerコンテナに入る方法:docker exec
コマンドを解説
Dockerは現代のソフトウェア開発・運用の現場で不可欠な技術となりました。アプリケーションとその依存関係をまとめてコンテナ化することで、開発環境、テスト環境、本番環境といった異なる環境間での一貫性を保ち、デプロイや管理を劇的に効率化できます。しかし、コンテナはホストOSから隔離された環境であり、その内部で何が起きているかを直接確認するのは、仮想マシンや物理サーバーに比べて少し特殊な方法を必要とします。
コンテナが期待通りに動作しない場合、内部の設定を確認したい場合、あるいは単に学習目的でコンテナのファイルシステムやプロセスを覗いてみたい場合など、稼働中のコンテナの内部に「入る」必要が生じることがよくあります。この記事では、そのための最も一般的で強力なコマンドであるdocker exec
コマンドについて、その使い方から詳細なオプション、応用例、関連するコマンドとの比較、トラブルシューティング、そして利用時の注意点まで、約5000語にわたり徹底的に解説します。
この記事を読むことで、あなたは以下のことをマスターできます。
- なぜコンテナ内に入る必要があるのか、その具体的なシナリオ
docker exec
コマンドの基本的な使い方- インタラクティブシェル(Bashなど)を起動してコンテナを操作する方法
-i
、-t
、-d
、-u
などの主要オプションの意味と使い方- コンテナ内で実行できる様々なコマンドとその目的
docker exec
利用時のトラブルシューティング方法docker exec
を安全かつ効果的に利用するためのベストプラクティスdocker attach
など、他の関連コマンドとの違い
それでは、Dockerコンテナの世界に踏み込んでみましょう。
1. はじめに:なぜDockerコンテナの内部に「入る」必要があるのか?
Dockerコンテナは、アプリケーションを実行するための軽量で移植可能な実行環境です。各コンテナはホストOSから隔離されており、独自のファイルシステム、プロセス空間、ネットワークインターフェースなどを持っています。この隔離性が、コンテナの大きな利点である移植性や一貫性を実現しています。
しかし、この隔離ゆえに、コンテナ内部の状態を外部から直接把握するのは容易ではありません。通常、コンテナは定義されたプロセス(例えばWebサーバーやデータベースプロセス)を実行し続けるだけで、その内部のファイル構造や実行中の詳細なプロセス、ネットワーク設定などを直接確認する機会は少ないかもしれません。
ですが、以下のような状況では、コンテナの内部にアクセスして調査を行う必要が出てきます。
- デバッグとトラブルシューティング:
- アプリケーションが期待通りに動作しない。エラーメッセージだけでは原因が特定できない。
- 設定ファイルが正しく配置・読み込まれているか確認したい。
- 特定のファイルやディレクトリが存在するか確認したい。
- コンテナ内のサービスが起動しているか、予期しないプロセスが動いていないか確認したい。
- ネットワーク接続の問題を診断したい(例: 外部サービスへの疎通確認)。
- 設定の確認と一時的な変更:
- コンテナイメージに含まれるソフトウェアのバージョンや設定を確認したい。
- 開発中やテスト中に、一時的に設定ファイルを変更して動作を確認したい(ただし、これはデバッグ目的であり、本番環境でのイミュータブル性の原則に反する行為なので注意が必要)。
- データベースコンテナで簡単なクエリを実行してデータを確認したい。
- 学習と実験:
- 特定のコンテナイメージがどのようなファイル構造やソフトウェア構成になっているか興味がある。
- コンテナ環境で特定のコマンドやスクリプトを実行してみたい。
- 軽量なLinux環境として利用してみたい。
- 稼働中のプロセスの監視:
- リソース使用量を確認したい(CPU、メモリなど)。
- 実行中のプロセスの詳細を知りたい。
これらのシナリオにおいて、稼働中のコンテナを停止させることなく、その内部にアクセスしてコマンドを実行できることは非常に重要です。なぜなら、多くのコンテナは長時間稼働することを前提としており、停止・再起動がサービス中断につながる可能性があるからです。また、問題が発生しているまさにその状態のコンテナを調査することが、原因究明に不可欠な場合も多いです。
ここで登場するのが、docker exec
コマンドです。
2. Dockerコンテナの理解:なぜコンテナに入るのか?
docker exec
を効果的に使うためには、Dockerコンテナがどのように隔離されているかを少し理解しておくと役立ちます。コンテナは仮想マシンとは異なり、ホストOSのカーネルを共有しつつ、主にLinuxの名前空間 (Namespaces) と コントロールグループ (cgroups) という機能を使って隔離を実現しています。
- 名前空間 (Namespaces): プロセスID、ネットワークインターフェース、マウントポイント、ユーザーIDなどのリソースを分離します。これにより、コンテナ内のプロセスはコンテナ独自のPID 1から始まり、ホストOSや他のコンテナのプロセスを見ることはできません(特に設定しない限り)。また、コンテナ独自のファイルシステムビューを持ちます。
- コントロールグループ (cgroups): CPU、メモリ、ネットワーク帯域、ディスクI/Oなどのリソース使用量を制限・管理します。
docker exec
コマンドは、指定したコンテナの名前空間内で、新しいプロセスを起動するという動作をします。これにより、その新しいプロセスはあたかもコンテナ内部で実行されているかのように、コンテナのファイルシステム、ネットワーク設定、プロセス空間(ただし、他のコンテナのプロセスは見えない)、環境変数などにアクセスできます。
コンテナイメージは、アプリケーションとその依存関係を含む「設計図」のようなもので、通常は必要最小限のツールしか含まれていません。軽量化のために、ping
, netstat
, top
, vim
などのよく使う診断ツールやエディタが含まれていないことがよくあります。docker exec
を使ってコンテナに入った後で、これらのツールが必要になる場面も出てきます。
また、コンテナは基本的にイミュータブル(不変)であるべき、という原則があります。これは、一度デプロイされたコンテナは変更せず、変更が必要な場合は新しいコンテナイメージを作成してデプロイし直す、という考え方です。docker exec
を使ってコンテナ内部の設定ファイルを変更することは技術的には可能ですが、それはあくまで一時的なデバッグ手段と捉えるべきであり、本番運用で恒久的な変更を加えるために使うべきではありません。恒久的な変更は、Dockerfileを修正して新しいイメージをビルドするか、設定ファイルをボリュームとしてマウントすることで行うのが正しいアプローチです。
これらの点を踏まえた上で、docker exec
コマンドの使い方を見ていきましょう。
3. docker exec
コマンド:コンテナ内への窓
docker exec
コマンドは、実行中のコンテナ内で新しいコマンドを実行するために使用します。これが、コンテナ内部にアクセスする最も一般的かつ推奨される方法です。
3.1. コマンドの基本構文
docker exec
コマンドの基本的な構文は以下の通りです。
bash
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
[OPTIONS]
: コマンドの動作を変更するためのオプションを指定します(後述)。CONTAINER
: コマンドを実行したい対象のコンテナを指定します。コンテナのIDまたは名前を使用できます。COMMAND
: コンテナ内で実行したいコマンドを指定します。[ARG...]
:COMMAND
に渡す引数を指定します。
3.2. 最も一般的な使い方:インタラクティブシェルへのアクセス
docker exec
の最も一般的な使い方は、稼働中のコンテナ内でインタラクティブなシェル(BashやShなど)を起動し、対話的にコマンドを実行することです。これにより、あたかもSSHでリモートサーバーにログインしたかのように、コンテナ内部を自由に探索・操作できます。
この目的でdocker exec
を使用する場合、通常は以下のオプションを組み合わせます。
bash
docker exec -it <container_id_or_name> <shell_command>
ここで使用している重要なオプションは -i
と -t
です。
-i
,--interactive
: 標準入力を開いたままにします。これにより、コンテナ内で実行されるコマンド(特にシェル)がキーボードからの入力を受け付けられるようになります。このオプションがないと、シェルはすぐに終了してしまうか、入力に対して反応しません。-t
,--tty
: 擬似ターミナル(pseudo-TTY)を割り当てます。これにより、コンテナ内で実行されるコマンドの出力を整形し、ターミナルで扱いやすい形式(色付け、カーソル移動など)で表示できるようになります。このオプションがないと、シェルからの出力(プロンプトなど)が適切に表示されず、操作が困難になります。
インタラクティブなシェルセッションを行うためには、-i
と -t
の両方のオプションを組み合わせることがほぼ必須です。-it
とまとめて指定するのが一般的です。
<shell_command>
としては、コンテナイメージに含まれているシェルを指定します。一般的なLinuxディストリビューションベースのイメージ(Ubuntu, Debian, CentOSなど)では /bin/bash
がよく使われます。軽量なイメージ(Alpine Linuxなど)では /bin/sh
や /bin/ash
が使われることが多いです。どのシェルが使えるかは、コンテナイメージによります。
例1:UbuntuベースのコンテナでBashシェルを起動する
まず、適当なUbuntuコンテナをバックグラウンドで起動します。
bash
docker run -d --name myubuntu ubuntu sleep infinity
これで、myubuntu
という名前のUbuntuコンテナがバックグラウンドで起動し続けています。
次に、このコンテナ内でBashシェルを起動します。
bash
docker exec -it myubuntu /bin/bash
このコマンドを実行すると、プロンプトがコンテナ内部のシェルに切り替わります。
root@<container_id>:/#
これで、あなたはmyubuntu
コンテナの内部にいることになります。ここで様々なコマンドを実行できます。
“`bash
root@
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@
/
root@
NAME=”Ubuntu”
VERSION=”20.04.3 LTS (Focal Fossa)”
ID=ubuntu
…(省略)…
root@
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2424 604 ? Ss 01:23 0:00 sleep infinity
root 11 0.0 0.0 18840 3240 pts/0 Ss 01:25 0:00 /bin/bash
root 18 0.0 0.0 18840 2856 pts/0 R+ 01:25 0:00 ps aux
“`
ps aux
の出力を見ると、PID 1で起動したオリジナルのsleep infinity
プロセスと、docker exec
によって起動されたPID 11の/bin/bash
プロセス、そして今実行したps aux
プロセス(PID 18)が見えます。これは、docker exec
がコンテナ内で新しいプロセスとしてシェルを起動したことを示しています。
コンテナ内部での操作が終わったら、exit
コマンドを入力するか、Ctrl+Dを押してシェルセッションを終了します。
bash
root@<container_id>:/# exit
exit
これにより、ホストOSのターミナルに戻ります。docker exec
によって起動されたシェルのプロセスは終了しますが、コンテナ自体(sleep infinity
プロセス)は引き続きバックグラウンドで実行されています。
bash
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<container_id> ubuntu "sleep infinity" 2 minutes ago Up 2 minutes myubuntu
例2:Alpine LinuxベースのコンテナでShシェルを起動する
軽量イメージとして人気のAlpine Linuxでは、デフォルトシェルは /bin/sh
です。
bash
docker run -d --name myalpine alpine sleep infinity
bash
docker exec -it myalpine /bin/sh
/ #
これでAlpineコンテナの内部に入れました。AlpineにはBashが含まれていないため、/bin/bash
を指定するとエラーになります。
bash
docker exec -it myalpine /bin/bash
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
コンテナイメージに含まれるシェルが分からない場合は、/bin/sh
を試してみるのが一般的です。多くのLinuxイメージには/bin/sh
(またはそのシンボリックリンク)が含まれています。
3.3. -i
と -t
オプションの詳細解説
なぜ -i
と -t
がインタラクティブセッションに必須なのか、さらに詳しく見てみましょう。
-
-i
(Interactive): 標準入力 (stdin
) を開いたままにします。-i
なし: コマンド(特にシェル)は入力を受け付けません。すぐにEOFを受け取ったとみなされ、終了します。-i
あり: コマンドは入力を待ち続けます。キーボードからの入力が可能になります。
-
-t
(TTY): 擬似ターミナル (pseudo-TTY
) を割り当てます。-t
なし: コマンドの出力は raw なバイトストリームとして扱われます。プロンプトが表示されなかったり、コマンドの出力(例えばls
のカラム表示)が崩れたりします。特にシェルを使う場合、コマンド補完やカーソル移動などがうまく機能しません。-t
あり: コマンドの出力はターミナルに適した形式に整形されます。シェルがプロンプトを表示し、インタラクティブな操作(コマンド履歴、補完、カーソル移動など)が可能になります。
-i
と -t
の組み合わせによる挙動の違いの具体例 (テキストでの概念的な図解):
コンテナ名: myubuntu
、コンテナ内で実行するコマンド: /bin/bash
-
docker exec myubuntu /bin/bash
(-i
なし,-t
なし)- 実行しても何も表示されないか、すぐに終了します。
- 標準入力が閉じているため、シェルがすぐに終了するためです。
- 出力も整形されないため、たとえシェルが起動してもプロンプトなどは見えません。
$ docker exec myubuntu /bin/bash
# 何も表示されずに終了
$ _
-
docker exec -i myubuntu /bin/bash
(-i
あり,-t
なし)- 標準入力は開きますが、擬似ターミナルがないため出力が整形されません。
- プロンプトは表示されず、コマンドの出力も読みにくいかもしれません。
- コマンドを入力することは可能ですが、エコーバックされない場合が多く、入力が分かりません。
$ docker exec -i myubuntu /bin/bash
# プロンプトは出ないが、入力待ち状態になる
ls # 入力しても画面に表示されないことが多い
# 入力したlsコマンドの実行結果がrawな形式で出力される(読みにくい)
bin etc lib mnt root srv usr
boot home lib64 opt run sys var
dev media proc sbin tmp
exit # 入力
$ _
-
docker exec -t myubuntu /bin/bash
(-i
なし,-t
あり)- 擬似ターミナルは割り当てられますが、標準入力が閉じているため、シェルはすぐに終了します。
$ docker exec -t myubuntu /bin/bash
root@<container_id>:/# exit
$ _- プロンプトは一瞬表示されるかもしれませんが、入力を待たずに即座に終了します。
-
docker exec -it myubuntu /bin/bash
(-i
あり,-t
あり)- 標準入力が開いており、擬似ターミナルが割り当てられます。
- これが、インタラクティブなシェルセッションに最適な状態です。
$ docker exec -it myubuntu /bin/bash
root@<container_id>:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@<container_id>:/# pwd
/
root@<container_id>:/# exit
exit
$ _- プロンプトが表示され、コマンドの入出力がターミナルで自然に扱える形式になります。
この詳細な説明から、なぜインタラクティブなシェルセッションには -it
オプションが必要なのかが理解できたかと思います。
3.4. 特定のコマンドを単発で実行する
docker exec
はシェルを起動するだけでなく、コンテナ内で任意のコマンドを単発で実行するためにも使えます。この場合、通常はインタラクティブセッションは不要なので、-it
オプションは使いません。
例:コンテナ内の特定のファイルの内容を確認する
bash
docker exec myubuntu cat /etc/hosts
このコマンドは、myubuntu
コンテナ内でcat /etc/hosts
というコマンドを実行し、その標準出力をホストOSのターミナルに表示します。
bash
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
172.17.0.2 <container_id>
例:コンテナ内のディレクトリリストを表示する
bash
docker exec myubuntu ls -l /app
このコマンドは、コンテナ内の /app
ディレクトリのファイルリストを詳細形式で表示します。
単発コマンドの実行は、コンテナの状態を非対話的に確認したい場合に便利です。例えば、監視スクリプトの中でコンテナ内の特定の値をチェックしたり、CI/CDパイプラインの中でデバッグ情報を収集したりする際に利用できます。
3.5. docker exec
の仕組み:新しいプロセスの起動
ここで改めて強調しておきたいのは、docker exec
が実行中のコンテナのメインプロセスにアタッチするのではなく(これを行うのはdocker attach
コマンドです)、そのコンテナと同じ名前空間を共有する新しいプロセスを起動するという点です。
概念図 (テキスト表現):
+---------------------+
| ホストOS |
| +-----------------+ |
| | Docker Daemon| |
| +-----------------+ |
| | |
| +-----v-----+ |
| | コンテナ A | |
| | (メインプロセス) | |
| | PID 1 | |
| +-------------+ |
| | | `docker exec`コマンド
| | |
| +-----v-----+ |
| | 新しいプロセス| | <- `docker exec`で起動
| | (シェルなど) | |
| | PID > 1 | |
| +-------------+ |
+---------------------+
docker exec
で起動されたプロセスは、コンテナのファイルシステム、ネットワーク、ユーザー/グループなどの環境を共有しますが、ホストOSのPID空間からは隔離されており、コンテナ内の他のプロセスとは独立したPIDを持ちます(ただし、コンテナ内のPID空間内ではPID > 1となります)。
この「新しいプロセスを起動する」という特性は、いくつかの点で重要です。
- メインプロセスがハングしていても、新しいプロセスを起動できる可能性があるため、原因調査が可能です。
- 新しいプロセスは独立して終了するため、シェルセッションを終了してもメインプロセスには影響しません。
- デフォルトでは、
docker exec
で起動されたプロセスはメインプロセスと同じユーザー権限で実行されます(通常はroot)。
4. docker exec
コマンドの詳細オプションと応用
docker exec
には、基本的な使い方をさらに柔軟にするための様々なオプションがあります。
4.1. -d, --detach
: バックグラウンドでコマンドを実行
-d
または --detach
オプションを使うと、docker exec
で実行するコマンドをバックグラウンドで実行できます。これは、時間のかかるスクリプトを実行したり、ログのtailをバックグラウンドで実行したりするのに便利です。
例:バックグラウンドでスクリプトを実行する
コンテナ内に myscript.sh
というスクリプトがあるとします。
bash
docker exec -d myubuntu /path/to/myscript.sh
このコマンドはすぐに制御をホストOSに戻し、スクリプトはコンテナ内で非同期に実行されます。スクリプトの標準出力/エラー出力は、特にリダイレクトしない限りDockerのログシステムには出力されません(これは docker logs
で見られるコンテナのメインプロセスのログとは別です)。バックグラウンド実行したコマンドの出力を見たい場合は、コンテナ内のファイルにリダイレクトするなどの工夫が必要です。
4.2. -e, --env <key>=<value>
: 環境変数の設定
-e
または --env
オプションを使うと、docker exec
で実行するコマンドに対して、特定の環境変数を設定できます。これにより、実行するコマンドの挙動を環境変数によって制御できます。複数の -e
オプションを指定することで、複数の環境変数を設定できます。
例:環境変数を設定してPythonスクリプトを実行する
コンテナ内に、DEBUG
環境変数の値によって挙動を変えるPythonスクリプト my_app.py
があるとします。
“`python
my_app.py (コンテナ内)
import os
debug_mode = os.environ.get(‘DEBUG’, ‘false’).lower() == ‘true’
if debug_mode:
print(“Debug mode is ON”)
else:
print(“Debug mode is OFF”)
“`
このスクリプトを通常通り実行すると:
bash
docker exec myubuntu python /path/to/my_app.py
Debug mode is OFF
-e
オプションで環境変数を設定して実行すると:
bash
docker exec -e DEBUG=true myubuntu python /path/to/my_app.py
Debug mode is ON
環境変数は、データベースの接続情報やAPIキーなど、コマンド実行時に動的に渡したい情報にも利用できます(ただし、セキュリティには注意が必要です。機密情報は環境変数ではなく、Docker Secretsなどを使うのが推奨されます)。
また、--env-file <path/to/.env>
オプションを使えば、ファイルから環境変数をまとめて読み込むことも可能です。
4.3. -u, --user <user>[:<group>]
: 実行ユーザーの指定
デフォルトでは、docker exec
はコンテナのメインプロセスと同じユーザー(通常はイメージ作成時のユーザー、多くの場合root)としてコマンドを実行します。セキュリティ上の理由から、必要以上に高い権限でコマンドを実行したくない場合があります。-u
または --user
オプションを使うと、コンテナ内の特定のユーザーまたはユーザーID (UID) でコマンドを実行できます。
例:root以外のユーザーでコマンドを実行する
Ubuntuイメージにはデフォルトでdaemon
ユーザーなどが存在します。
bash
docker exec -u daemon myubuntu whoami
daemon
ユーザーIDを指定することも可能です。例えば、UID 1000 のユーザーで実行する場合:
bash
docker exec -u 1000 myubuntu whoami
(コンテナ内にUID 1000のユーザーが存在しない場合は、そのUIDでコマンドを実行します。ユーザー名が表示されるかどうかは、イメージによって異なります。)
本番環境でコンテナ内のシェルに入る場合など、誤ってシステムファイルを変更してしまうリスクを減らすために、-u
オプションで可能な限り低い権限のユーザーを指定するのが良い習慣です。
4.4. -w, --workdir <path>
: 作業ディレクトリの指定
-w
または --workdir
オプションを使うと、docker exec
で実行するコマンドの作業ディレクトリを指定できます。これは、特定のディレクトリにあるスクリプトを実行したり、特定のディレクトリを起点にファイル操作を行ったりする場合に便利です。
例:/appディレクトリ内でlsを実行する
コンテナ内で/app
ディレクトリを作成しておきます。
bash
docker exec myubuntu mkdir /app
docker exec myubuntu touch /app/file1.txt /app/file2.txt
デフォルトの作業ディレクトリ(通常はDockerfileで指定されたものか、/
)でlsを実行すると:
bash
docker exec -it myubuntu /bin/bash
root@<container_id>:/# pwd
/
root@<container_id>:/# ls /app
file1.txt file2.txt
root@<container_id>:/# exit
exit
-w
オプションを使って作業ディレクトリを指定すると:
bash
docker exec -w /app myubuntu ls -l
-rw-r--r-- 1 root root 0 Dec 15 02:40 file1.txt
-rw-r--r-- 1 root root 0 Dec 15 02:40 file2.txt
docker exec
に続けて実行されるコマンド (ls -l
in this case) は、指定された/app
ディレクトリをカレントディレクトリとして実行されます。これは、シェルを起動してcd
する手間を省きたい場合に便利です。
4.5. その他の便利なオプション
--privileged
: コンテナに拡張された権限を与えてコマンドを実行します。通常は推奨されません。カーネルレベルの操作など、特殊なデバッグが必要な場合にのみ検討します。--userland-proxy
/--no-userland-proxy
: ユーザーランドプロキシを使用するかどうか(主にネットワーク関連の設定ですが、docker exec
では通常使用しません)。--interactive
/--no-interactive
:-i
のロングオプション。--tty
/--no-tty
:-t
のロングオプション。
これらのオプションを適切に組み合わせることで、docker exec
の機能を最大限に活用できます。
4.6. 応用例
- データベースコンテナでSQLを実行:
- MySQLコンテナの場合:
docker exec -it mymysql mysql -u root -p<password> -e "SELECT * FROM mytable;"
- PostgreSQLコンテナの場合:
docker exec -it mypostgres psql -U postgres -d mydatabase -c "SELECT * FROM mytable;"
- 対話的にSQLを実行したい場合は、上記コマンドの末尾から
-e "..."
や-c "..."
を外し、単にmysql -u root -p<password>
やpsql -U postgres -d mydatabase
として実行します。
- MySQLコンテナの場合:
- Webサーバーコンテナのログファイルをリアルタイム監視:
- Apacheコンテナの場合:
docker exec myapache tail -f /var/log/apache2/access.log
- Nginxコンテナの場合:
docker exec mynginx tail -f /var/log/nginx/access.log
- これは
-d
オプションと組み合わせてバックグラウンドで実行することも可能ですが、通常はフォアグラウンドで実行してログの出力を見続けます。終了するにはCtrl+Cを押します。
- Apacheコンテナの場合:
- 複数のコマンドをまとめて実行:
- シェルスクリプトとして実行したいコマンドを文字列として渡すことができますが、スペースや特殊文字の扱いに注意が必要です。クォーテーションで囲む必要があります。
- 例:
docker exec myubuntu sh -c "cd /app && ls -l"
(sh -c
を使うと、指定した文字列をシェルコマンドとして実行できます)
- デバッグツールの使用:
- ネットワークデバッグ:
docker exec mycontainer ping example.com
またはdocker exec mycontainer nc -vz <host> <port>
- システムコールトレース:
docker exec mycontainer strace <command>
(ただし、コンテナイメージにstrace
がインストールされている必要があります) - プロファイリング:
docker exec mycontainer perf top
(ホストOSとコンテナの権限設定によります)
- ネットワークデバッグ:
これらの応用例は、docker exec
が単にシェルに入るだけでなく、コンテナ内部で様々なタスクを実行するための汎用的なツールであることを示しています。
5. コンテナ内での具体的な操作と調査
docker exec -it <container> <shell>
でコンテナ内部に入った後、具体的にどのような操作ができるかを見ていきましょう。基本的に、そのコンテナイメージに含まれるコマンドであれば何でも実行できます。一般的なデバッグや調査に役立つコマンドをいくつか紹介します。
5.1. ファイルシステム構造の理解と操作
コンテナ内のファイルシステムは、ホストOSのファイルシステムとは独立しています(ボリュームマウントされている箇所を除く)。docker exec
で入ったシェルからは、このコンテナ独自のファイルシステムが見えます。
- 現在のディレクトリを確認:
pwd
- ディレクトリの内容を確認:
ls
,ls -l
,ls -a
- ディレクトリを移動:
cd <directory>
- ファイルの内容を表示:
cat <file>
,less <file>
,more <file>
- ファイルの検索:
find <path> -name "<filename>"
- ディスク使用量を確認:
df -h
- ディレクトリ使用量を確認:
du -sh <directory>
例: アプリケーションの設定ファイルがどこにあるか分からない場合、/etc
や/usr/local/etc
、アプリケーションのインストールディレクトリなどを ls
や find
で探します。
5.2. プロセスの確認と管理
コンテナ内で実行中のプロセスは、コンテナ独自のPID空間で見えます。PID 1は通常、コンテナ起動時に指定されたメインプロセス(例えば、Webサーバーやアプリケーション本体、あるいは sleep infinity
のようなダミーコマンド)です。docker exec
で起動されたシェルやコマンドは、PID 1とは異なるPIDを持ちます。
- 実行中のプロセスを確認:
ps aux
,ps ef
ps aux
: 全ユーザーのプロセスを詳細表示。ps ef
: プロセスツリーを表示(docker exec
で起動したプロセスがメインプロセスの下に表示されるわけではない点に注意。新しい独立したプロセスとして表示されます)。
- リソース使用量を確認:
top
,htop
(インストールされている場合)top
: CPU、メモリ、プロセス情報などをリアルタイム表示。コンテナ内の限られたリソースビューを表示します。
- 特定のプロセスを検索:
ps aux | grep <process_name>
- プロセスを終了させる:
kill <pid>
例: アプリケーションがCPUを大量に消費している場合、top
コマンドでどのプロセスがリソースを使っているかを確認します。予期しないプロセスが起動していないかもチェックできます。
5.3. ネットワーク設定と接続テスト
コンテナは独自のネットワークインターフェース(通常はホストOSのDockerデーモンが管理するブリッジネットワークに接続)を持ちます。docker exec
で入ったシェルから、コンテナ視点でのネットワーク設定を確認したり、疎通確認を行ったりできます。
- IPアドレスやネットワークインターフェースを確認:
ip addr
,ifconfig
(インストールされている場合) - ルーティングテーブルを確認:
ip route
,netstat -r
(インストールされている場合) - ポートのリスニング状況を確認:
netstat -tulnp
(インストールされている場合) - DNS設定を確認:
cat /etc/resolv.conf
- 疎通確認:
ping <host_or_ip>
,nc -vz <host> <port>
(インストールされている場合)- コンテナから外部のホストやサービスに接続できるか確認できます。
- HTTP接続テスト:
curl <url>
(インストールされている場合)
例: データベースコンテナに接続できない場合、アプリケーションコンテナに入ってping database-host
やnc -vz database-host 5432
のようなコマンドを実行することで、ネットワークレベルの問題か、認証などのアプリケーションレベルの問題かを切り分けられます。
5.4. 設定ファイルの確認と編集
コンテナイメージに含まれる設定ファイルや、ボリュームとしてマウントされた設定ファイルの内容を確認・編集できます。
- ファイルの内容を確認:
cat
,less
などを使用。 - ファイルを編集:
vi
,nano
などを使用。- 注意: 多くの軽量コンテナイメージにはエディタが含まれていません。エディタがない場合は、以下のいずれかの方法を取る必要があります。
docker exec
でシェルに入り、パッケージマネージャー(apt-get
,apk
,yum
など)を使ってエディタを一時的にインストールする。
bash
root@<container_id>:/# apt-get update && apt-get install -y nano
root@<container_id>:/# nano <file>
ただし、これはコンテナイメージ自体を変更する行為であり、コンテナが削除・再作成されると失われます。また、本番環境で不要なツールをインストールするのはセキュリティリスクになります。docker cp
コマンドを使って、設定ファイルをホストOSにコピーし、ホストOS側のお気に入りのエディタで編集し、編集後再びdocker cp
でコンテナに戻す。
bash
docker cp mycontainer:/path/to/config.conf /tmp/config.conf
# ホストOS側で /tmp/config.conf を編集
vim /tmp/config.conf
# 編集後、コンテナに戻す
docker cp /tmp/config.conf mycontainer:/path/to/config.conf
この方法はコンテナ内の状態を変更しますが、エディタのインストールは不要です。- そもそも設定ファイルはボリュームとしてマウントし、ホストOS側で管理・編集するのがベストプラクティスです。
- 注意: 多くの軽量コンテナイメージにはエディタが含まれていません。エディタがない場合は、以下のいずれかの方法を取る必要があります。
イミュータブルコンテナの原則に従うなら、デバッグ目的以外でコンテナ内のファイルを直接編集することは避けるべきです。
5.5. 必要なツールの追加インストール
前述のように、多くの軽量コンテナイメージにはデバッグや診断に必要なツール(ping
, netstat
, curl
, vim
, htop
, strace
など)が含まれていません。これらのツールが必要な場合は、docker exec
でシェルに入ってからパッケージマネージャーを使ってインストールできます。
- Debian/Ubuntuベース:
bash
apt-get update
apt-get install -y <package_name> - Alpine Linuxベース:
bash
apk update
apk add <package_name> - CentOS/Fedoraベース:
bash
yum update
yum install -y <package_name>
または
bash
dnf update
dnf install -y <package_name>
注意: これらのインストールは、そのdocker exec
セッション中、またはコンテナが停止するまで有効です。コンテナが削除・再作成されると、インストールしたツールは失われます。デバッグ終了後は、速やかにセッションを終了することが望ましいです。恒久的に特定のツールを含めたい場合は、DockerfileにRUN
命令でインストールステップを追加して、新しいイメージをビルドする必要があります。
5.6. ログファイルの確認方法
アプリケーションが標準出力/標準エラー出力にログを出力するように設計されている場合、docker logs <container>
コマンドでログを確認できます。しかし、アプリケーションがコンテナ内の特定のファイルにログを出力する場合もあります。この場合は、docker exec
を使ってそのログファイルの内容を確認する必要があります。
- ログファイルの内容を表示:
docker exec myapp cat /var/log/myapp/app.log
- ログファイルをリアルタイム監視:
docker exec myapp tail -f /var/log/myapp/app.log
ログファイルの場所はアプリケーションやイメージによって異なります。ドキュメントを確認するか、コンテナ内を探索してログファイルを見つける必要があります(例: /var/log
, /app/logs
など)。
6. docker exec
の代替手段と使い分け
コンテナの状態を確認したり、内部の情報を取得したりするためのコマンドはdocker exec
だけではありません。状況に応じて他のコマンドが適している場合もあります。
6.1. docker attach
との比較:メインプロセス vs. 新規プロセス
docker attach <container_id_or_name>
コマンドは、実行中のコンテナのメインプロセスの標準入力、標準出力、標準エラー出力にアタッチします。
docker attach
の特性:
- コンテナのメインプロセスに接続する。
- 通常、コンテナ起動時のコマンド(
CMD
やENTRYPOINT
で指定されたもの)がインタラクティブなシェルである場合に有用。 - アタッチ中にCtrl+Cを押すと、コンテナ内のメインプロセスがシグナルを受け取り、コンテナ自体が停止してしまう可能性がある(特に、メインプロセスがシグナルハンドリングをしていない場合)。
- 複数の端末から同じコンテナに
attach
すると、入力が混ざったり出力が重複したりすることがある。
docker exec
の特性:
- コンテナの名前空間内で新しいプロセスを起動する。
- コンテナのメインプロセスがどのようなものであっても利用できる(Webサーバー、データベース、バックグラウンドプロセスなど)。
docker exec -it
で起動したシェルからexit
しても、新しく起動したシェルプロセスが終了するだけで、コンテナのメインプロセスには影響しない。- 複数の端末から同じコンテナに対して
docker exec
を実行しても、それぞれ独立した新しいプロセスが起動するため干渉しない。
使い分け:
- コンテナのメインプロセスがBashなどのインタラクティブなシェルであり、かつそのメインプロセス(例えば、開発中に一時的に起動したコンテナ)と直接やり取りしたい場合は、
docker attach
が使えることがあります。 - 稼働中のサービスを提供しているコンテナのデバッグや調査、あるいはメインプロセスに関わらずコンテナ内部で特定のコマンドを実行したい場合は、
docker exec
を使うのが圧倒的に一般的で安全です。特に、コンテナを停止させたくない本番環境では、docker exec
一択と考えて良いでしょう。
6.2. docker logs
:ログ確認の基本
docker logs <container_id_or_name>
コマンドは、コンテナの標準出力 (stdout) と標準エラー出力 (stderr) に出力されたログを確認するためのコマンドです。
- コンテナ内のアプリケーションが標準出力/標準エラー出力にログを出力するように設計されている場合に非常に強力です。
docker logs -f <container>
でリアルタイムにログを追跡できます (tail -f
のような挙動)。docker logs --since <timestamp>
やdocker logs --until <timestamp>
で期間を指定したり、docker logs --tail <number>
で末尾の行数を指定したりと、便利なオプションがあります。
使い分け:
- アプリケーションが標準出力/標準エラー出力にログを出力している場合は、まず
docker logs
でログを確認するのが最も手軽です。 - アプリケーションがファイルにログを出力している場合や、ログ以外の情報(プロセス情報、ファイルシステムなど)を確認したい場合は、
docker exec
を使ってコンテナ内に入る必要があります。
6.3. docker cp
:ホストとのファイル連携
docker cp <container_id_or_name>:<path/in/container> <path/on/host>
または docker cp <path/on/host> <container_id_or_name>:<path/in/container>
コマンドは、ホストOSとコンテナ間でファイルをコピーするためのコマンドです。
使い分け:
- コンテナ内の特定のファイルをローカルに持ってきて詳しく調査したい場合や、ローカルで編集した設定ファイルをコンテナに戻したい場合に便利です。
- ただし、大きなファイルやディレクトリを頻繁にコピーする場合は、ボリュームマウントを検討した方が効率的です。
- コンテナ内のファイル内容を一時的に確認したいだけであれば、
docker exec <container> cat <file>
の方が手軽な場合があります。
6.4. docker inspect
:詳細情報の取得
docker inspect <container_id_or_name>
コマンドは、コンテナの様々な詳細情報をJSON形式で表示します。コンテナの設定、ネットワーク設定、ボリューム、環境変数、状態などを確認できます。
使い分け:
- コンテナ内部に入る前に、基本的な設定情報や状態を知りたい場合に非常に役立ちます。
- 例えば、コンテナのIPアドレス、マウントされているボリューム、公開されているポート、設定されている環境変数などを知りたい場合は、
docker inspect
を使います。 docker exec
はコンテナ「の中」で何かを実行するためのコマンドですが、docker inspect
はコンテナ「そのもの」に関するメタ情報を取得するためのコマンドです。
これらの関連コマンドとdocker exec
を組み合わせることで、Dockerコンテナの運用・管理・デバッグの効率を大幅に向上させることができます。多くの場合、まずdocker ps
でコンテナの状態を確認し、docker logs
でログをチェックし、必要であればdocker inspect
で設定を確認し、それでも問題が解決しない場合にdocker exec -it
でコンテナに入って詳細調査を行う、という流れになります。
7. docker exec
利用時のトラブルシューティング
docker exec
を使用する際によく遭遇する問題とその解決策を見ていきましょう。
7.1. “Error: No such container: “
指定したコンテナIDまたは名前が見つかりません。
- 原因: コンテナが停止している、削除されている、あるいは指定したID/名前が間違っている。
- 解決策:
docker ps -a
コマンドを実行して、全てのコンテナ(停止中のものも含む)のリストを表示し、正しいコンテナIDまたは名前を確認してください。コンテナが停止している場合は、docker start <container>
で起動してから再度docker exec
を試みてください。
7.2. “OCI runtime exec failed: exec failed: container_linux.go:…: starting container process caused: exec: ““: stat : no such file or directory: unknown”
指定したコマンドがコンテナ内で見つかりません。
- 原因: 実行しようとしたコマンド(例えば
/bin/bash
や特定のツール)が、コンテナイメージに含まれていない。特に軽量イメージ(Alpineなど)では、標準的なツールが削られていることが多いです。 - 解決策:
- 使用しているコンテナイメージのベースOSを確認し、利用可能なシェルを探します。例えば、
/bin/bash
がなければ/bin/sh
や/bin/ash
を試してください。 - 実行したいコマンド(
ping
,vim
など)がイメージに含まれていない場合は、docker exec -it <container> <shell>
でコンテナに入り、パッケージマネージャーを使って一時的にインストールするか、docker cp
でホストからツールを持ち込むことを検討します(セクション5.4, 5.5参照)。
- 使用しているコンテナイメージのベースOSを確認し、利用可能なシェルを探します。例えば、
7.3. シェルの違い(bash, sh, ash)への対応
前述の「コマンドが見つからない」問題と関連しますが、特にシェルを指定する際に重要です。
- 原因: コンテナイメージによってデフォルトで含まれるシェルが異なります。
- 解決策: 一般的な順序で
/bin/bash
,/bin/sh
,/bin/ash
を試します。Dockerfileを確認して、ベースイメージやインストールされているパッケージを確認するのも有効です。
7.4. パーミッション関連のエラー
コンテナ内でファイルを作成・編集したり、特定のコマンドを実行したりする際に「Permission denied」のようなエラーが発生する。
- 原因:
docker exec
をrootユーザー以外で実行しており、そのユーザーにファイルへのアクセス権限がない。- コンテナ内で実行しているユーザーに、特定の操作(例: パッケージインストール、システムディレクトリへの書き込み)を行う権限がない。
- 解決策:
docker exec
をデフォルトのユーザー(通常はroot)で試してみてください(docker exec -it mycontainer /bin/bash
)。ただし、不必要なroot権限での操作は避けるべきです。-u
オプションでrootユーザーを指定して実行します(docker exec -u 0 -it mycontainer /bin/bash
)。- コンテナ内のファイルやディレクトリのパーミッション(
ls -l
で確認)と、コマンドを実行しているユーザーの権限を確認します。
7.5. インタラクティブセッションに関する問題
シェルがすぐに終了してしまう、プロンプトが表示されない、キーボード入力ができない、コマンド補完やカーソル移動ができない。
- 原因:
-i
オプションや-t
オプションの付け忘れ。 - 解決策: インタラクティブなシェルセッションを行う場合は、必ず
-it
オプションを付けてください (docker exec -it ...
)。セクション3.3を参照してください。
7.6. コンテナが停止している場合
docker exec
は実行中のコンテナに対してのみ機能します。停止中のコンテナに対して実行しようとするとエラーになります。
- 原因: 対象のコンテナが停止している。
- 解決策:
docker ps -a
でコンテナの状態を確認します。STATUSがExited
になっている場合は、docker start <container>
で起動してからdocker exec
を実行します。
7.7. “the input device is not a TTY” / “Pseudo-terminal will not be allocated because stdin is not a TTY.”
このエラーメッセージは、docker exec
コマンドが擬似ターミナル (-t
) を割り当てようとしたが、その標準入力がターミナル(TTY)に接続されていない場合に発生することがあります。例えば、スクリプトからdocker exec -it
を実行しようとした場合などです。
- 原因: コマンドの標準入力がターミナルに接続されていない環境(例: スクリプト、パイプライン)で
-t
オプションを使用した場合。あるいは、標準入力が開かれていない環境で-i
オプションを使用した場合。 - 解決策:
- 非インタラクティブな環境で
docker exec
を実行する場合は、-it
オプションを外し、単にコマンドとその引数を指定します。 - どうしてもスクリプトなどからインタラクティブなシェルを起動したい場合は、スクリプト実行環境自体をインタラクティブなターミナルから実行する必要があります。または、expectのようなツールを使ってスクリプトから対話的なセッションを制御することを検討します。
- 非インタラクティブな環境で
これらのトラブルシューティングは、docker exec
を効果的に使いこなす上で非常に役立ちます。エラーメッセージをよく読み、それぞれの原因と解決策を理解することが重要です。
8. セキュリティとベストプラクティス
docker exec
は強力なツールであり、不適切に使用するとセキュリティリスクにつながる可能性があります。特に本番環境で使用する場合は、以下の点に注意し、ベストプラクティスに従うことが重要です。
8.1. 本番環境でのdocker exec
使用に関する注意
本番環境で稼働中のコンテナに対して docker exec
を実行することは、デバッグや緊急対応のために有用ですが、リスクも伴います。
- 意図しない変更: コンテナ内のファイルシステムや設定を誤って変更してしまう可能性があります。これにより、アプリケーションの動作がおかしくなったり、復旧が難しくなったりする可能性があります。
- セキュリティホール:
docker exec
でシェルを提供することは、コンテナ内部に直接アクセスできるバックドアを提供するようなものです。コンテナやホストOSに脆弱性がある場合、攻撃者に悪用されるリスクが高まります。 - 監査性:
docker exec
で実行されたコマンドは、デフォルトではDockerのログには記録されません。誰が、いつ、どのような操作をコンテナ内部で行ったかを追跡するのが難しくなります。
可能な限り、本番環境での docker exec
の使用は避けるべきです。デバッグは開発環境やステージング環境で行い、本番環境ではログ分析や監視ツールによる情報収集を主に行うのが理想です。どうしても本番環境で必要な場合は、使用を最小限にとどめ、許可されたユーザーのみがアクセスできるように制限する必要があります。
8.2. 最小権限の原則(-u
オプションの活用)
コンテナ内でコマンドを実行する際は、必要最小限の権限を持つユーザーを使用すべきです。デフォルトのrootユーザーではなく、アプリケーションを実行しているユーザーや、UIDを指定して実行することを検討します。
docker exec -u <non-root-user> -it <container> <shell>
これにより、誤って重要なシステムファイルを変更してしまうリスクを減らすことができます。
8.3. 機密情報の取り扱いリスク
docker exec
を使ってコンテナ内の設定ファイルや環境変数にアクセスすることは、機密情報(パスワード、APIキーなど)を閲覧できることを意味します。これらの情報がコンテナ内に平文で保存されている場合、docker exec
アクセス権を持つ誰もがそれらを閲覧できてしまいます。
機密情報はDocker SecretsやKubernetes Secretsのような安全な方法で管理すべきです。docker exec
で機密情報を扱う必要がある場合は、そのリスクを十分に理解し、アクセス権を厳重に管理する必要があります。
8.4. デバッグ後のクリーンアップ
デバッグのためにコンテナ内に一時的にツール(vim
, strace
など)をインストールした場合、それはそのコンテナインスタンスにのみ影響します。コンテナが削除されると失われますが、デバッグセッション終了後は速やかにシェルを閉じ、不用意にツールがコンテナに残ったままにならないように注意します(ただし、これは主に手動でのインストールに限られます。Dockerfileでインストールされたものはイメージに含まれます)。
8.5. イメージ設計の観点
docker exec
でコンテナ内部に入ることが頻繁に必要になる場合は、コンテナイメージの設計を見直す必要があるかもしれません。
- 必要なデバッグツールを含める: 開発環境やステージング環境で使用するイメージには、一般的なデバッグツール(
ping
,netstat
,curl
,vim
,less
,tcpdump
,strace
など)を最初から含めておくと便利です。ただし、本番環境用イメージは可能な限り軽量化し、不要なツールは含めないようにします。 - ログ出力の設計: アプリケーションのログは、標準出力/標準エラー出力に出力するように設計するのがDockerの推奨パターンです。これにより、
docker logs
コマンドで簡単にログを確認できるようになり、docker exec
でファイルを探しに行く手間が省けます。 - 設定の外部化: 設定ファイルはボリュームとしてマウントするか、環境変数で渡すようにします。これにより、設定変更のためにコンテナに入る必要がなくなります。
- 監視・メトリクス: アプリケーションやコンテナの状態を示すメトリクスを収集し、監視システムで確認できるようにします。これにより、問題発生時に
docker exec
で手動調査を行う前に、多くの情報を得られるようになります。
9. docker exec
のさらなる活用と技術的背景
docker exec
は手動でのデバッグや操作だけでなく、自動化の一部として利用されることもあります。
9.1. 自動化スクリプトとの連携
CI/CDパイプラインのデバッグステップや、自動化されたヘルスチェックの中でdocker exec
を使ってコンテナ内の特定のコマンドを実行することができます。
- 例: デプロイ後の自動テストで、アプリケーションコンテナ内で特定のテストスクリプトを実行する。
bash
docker exec myapp /app/test_script.sh - 例: 定期的にコンテナの内部状態をチェックするスクリプトの中で、ファイルの内容を確認したり、プロセスの状態をチェックしたりする。
bash
if docker exec myapp cat /tmp/healthcheck_status | grep -q "OK"; then
echo "App is healthy"
else
echo "App check failed"
fi
自動化の中でdocker exec
を使う場合は、インタラクティブな操作は不要なので、通常は-it
オプションは付けません。標準出力/標準エラー出力はスクリプト側で受け取って処理します。
9.2. コンテナ内部の技術:名前空間とcgroups(概要)
セクション2でも触れましたが、docker exec
がどのようにコンテナ内でプロセスを起動できるかを理解するために、Linuxの名前空間とcgroupsについてもう少し掘り下げてみましょう。
docker exec
コマンドが実行されると、DockerデーモンはホストOS上で新しいプロセスを起動します。この新しいプロセスは、clone(2)
システムコールなどを使って、対象となるコンテナが持つ以下の名前空間を共有するように設定されます。
- PID名前空間: 新しいプロセスはコンテナのPID空間に参加します。コンテナのPID 1が見え、自分自身はそれ以外のPID(通常はPID 2以降)を持ちます。
- Network名前空間: コンテナのネットワークインターフェース、IPアドレス、ルーティングテーブルなどが共有されます。
- Mount名前空間: コンテナのファイルシステムツリー(ルートファイルシステムやマウントされたボリューム)が共有されます。
- UTS名前空間: ホスト名が共有されます。
- IPC名前空間: プロセス間通信(IPC)リソースが共有されます。
- User名前空間: コンテナ内のユーザー/グループマッピングが共有されます(ただし、
docker exec -u
で指定したユーザーIDは、そのユーザー名前空間内でのIDとして解釈されます)。
また、新しいプロセスは、対象コンテナが属するcgroupsにも参加します。これにより、CPU、メモリなどのリソース制限が、docker exec
で起動したプロセスにも適用されます。
このように、docker exec
は高度なLinuxカーネル機能を利用して、ホストOS上で起動したプロセスを、あたかもコンテナ内部で実行されているかのように見せかけているのです。これは、コンテナが軽量であり、ホストOSのカーネルを共有するからこそ可能な技術です。仮想マシンとは根本的に異なるアプローチです。
9.3. docker exec
がどのように隔離を維持しつつプロセスを起動するか
Dockerデーモンがdocker exec
リクエストを受け取ると、内部的には以下のようなステップを実行します(簡略化)。
- 対象のコンテナプロセスが使用している名前空間(PID, Net, Mntなど)を特定します。
- ホストOS上で新しいプロセスを起動します。
- 起動した新しいプロセスを、特定した名前空間に参加させます。これは
setns(2)
のようなシステムコールを使って行われます。 - 新しいプロセスのルートファイルシステムを、対象コンテナのルートファイルシステムに切り替えます(
chroot
やpivot_root
)。 - 指定されたコマンドを、新しいプロセスのコンテキスト(ユーザー、作業ディレクトリ、環境変数など)で実行します。
このプロセスを通じて、docker exec
で起動されたコマンドは、ホストOSのカーネル上で実行されながらも、コンテナ固有の隔離された環境を認識し、その中で操作を行うことができるようになります。
10. まとめ
この記事では、Dockerコンテナの内部にアクセスするための主要なコマンドであるdocker exec
について、その基本から応用、トラブルシューティング、セキュリティ、そして技術的な背景まで、詳細に解説しました。
docker exec
は、実行中のコンテナを停止することなく、その内部で新しいプロセスを起動し、コマンドを実行するための強力なツールです。特に、インタラクティブシェル(docker exec -it <container> <shell>
)を使ったデバッグやトラブルシューティングは、コンテナ環境における問題解決の最も一般的な手法の一つです。
主要なオプションである-i
(インタラクティブ)と-t
(擬似ターミナル)の組み合わせは、快適なシェル操作に不可欠であることを理解しました。また、-d
(バックグラウンド実行)、-e
(環境変数設定)、-u
(実行ユーザー指定)、-w
(作業ディレクトリ指定)といったオプションを使うことで、docker exec
をさらに柔軟に活用できることを学びました。
コンテナ内部に入った後は、ファイルシステム操作 (ls
, cd
, cat
)、プロセス管理 (ps
, top
)、ネットワーク診断 (ip addr
, ping
) など、様々なコマンドを実行してコンテナの状態を詳しく調査できることを具体的な例と共に示しました。必要なツールがコンテナイメージに含まれていない場合の対処法にも触れました。
また、docker attach
、docker logs
、docker cp
、docker inspect
といった関連コマンドとの違いや使い分けについても解説しました。これらのコマンドを適切に使い分けることで、より効率的にコンテナの運用・管理を行うことができます。
最後に、docker exec
は強力であるゆえに、特に本番環境での使用にはセキュリティ上のリスクが伴うことを強調しました。最小権限での実行、機密情報の安全な管理、そしてデバッグ目的以外でのコンテナ変更を避けるといったベストプラクティスに従うことが重要です。理想的には、イメージ設計やログ・監視の仕組みを改善することで、docker exec
による手動での調査が必要な状況を減らしていくことが望ましいでしょう。
docker exec
は、Dockerを扱うエンジニアにとって必須のコマンドです。この記事で解説した内容を理解し、練習することで、あなたはDockerコンテナ環境でのデバッグや運用作業をより効率的かつ自信を持って行えるようになるはずです。
これで、Dockerコンテナに「入る」ための窓であるdocker exec
コマンドの解説を終わります。この知識が、あなたのDockerジャーニーの一助となれば幸いです。