この記事では、Dockerにおいて起動中のコンテナのシェルに接続する方法について詳しく解説する。
Udemyの「ゼロからはじめる Dockerによるアプリケーション実行環境構築」を参考。
接続する際の2つのコマンド
コンテナのシェルに接続するには、
- docker attach
- docker exec
のどちらかのコマンドを使用する。この2つのコマンドの違いを次に解説する。
①docker attachを使用するパターン
$ docker attach <コンテナ名 または コンテナID> # シェルに接続できるのはコンテナでシェルを実行している場合のみ
docker attachコマンドを使用した場合は、コンテナのPID 1(※)のプロセスの標準入出力に接続される。コンテナ起動時にコマンドでシェルを起動した場合は、attachを使用することでそのシェルに接続できる。
ただし、起動時にデーモン(※)を起動していた場合はそのデーモンの標準入出力に接続されてしまう。
また、attachで接続した後に「exit」で抜けた場合、pid 1のプロセスが終了してコンテナも停止してしまうことにも注意が必要。
プロセスを終了せずに接続状態を抜けるには、「Ctrl+P」を入力した後に、「Ctrl+Q」と 入力する。ただし、起動時に「-it」 オプションをつけていなければこれらのコマンドで抜けることはできない。
$ docker run --name connect-test -it(このオプションをつける) -d ubuntu /bin/bash(シェル)
【PID 1とは】
一般的にPID 1は「initプロセス」と呼ばれており、システムが起動した際に最初に起動するプロセス。このinitプロセスの役割は、ゾンビプロセスの除去とサブプロセスへのシグナルの伝搬。
引用元:https://casualdevelopers.com/tech-tips/how-to-fix-the-pid-1-problem-for-dockerized-nodejs-app/
【デーモンとは】
Linuxにおいて常駐型のプログラムのことをデーモンと言う。例えば、Webサーバーのプログラムなどはデーモンとして起動し続け、クライアントからのリクエストがあった際に常に応答を返せるように常駐する。
引用元:ゼロからはじめる Dockerによるアプリケーション実行環境構築
②docker execを使用するパターン
$ docker exec -it <コンテナ名 または コンテナID> /bin/bash # 今回はbashを使用しているが別のシェルでも可
docker exec自体は起動しているコンテナ内で、任意のコマンドを実行するためのコマンド。シェルの氷刃入出力に接続するには、シェルを「-it」オプション付きで実行する。
docker attachと違い、「exit」で抜けてもコンテナが停止することがなく、誤って停止させてしまうことを考慮するとdocker execの使用の方が望ましい。
まとめ
docker execを使用する方が、exitで抜けてもコンテナは起動状態を保つことができるので、単純にシェルに接続したい場合はdocker execを使用するのが安全。