下記はdocker exec
の説明だが、d
、t
、i
オプションはdocker run
にも当てはまる。
-d, --detach=false デタッチド・モード: コマンドをバックグラウンドで実行
-i, --interactive=false アタッチしていなくても STDIN をオープンにし続ける
-t, --tty=false 疑似ターミナル (pseudo-TTY) の割り当てhttp://docs.docker.jp/engine/reference/commandline/exec.html
※ tty:teletypewriter(仮想コンソール)
ubuntu:latest
を例に挙動を確認する。
(1) Dockerコンテナはルートプロセス(PID:1
)が終了したらコンテナが終了する。
(2) docker run
でt
オプションを付与することでPID:1
のbash
に擬似tty
(pts/1:pseudo-terminal)が接続されて、プロセスが稼働し続けるので(ルートプロセスが終了しないので)コンテナは終了しない。
(3) docker run
でi
オプションを付与することでアタッチしていなくても標準入力(STDIN
)が開いたままになる。
※ 例えばhttpd
はCMD
でデーモンを起動している。PID:1
にhttpd
デーモンが割り当てられるのでt
オプションを付与しなくてもコンテナは終了しない。
以下、ubuntu:latest
を例にしてdocker run
のオプションによる挙動の違いを確認する。
オプションを付与しない場合は、コンテナが直ちに終了する。
$ docker run ubuntu:latest
$ docker ps --all
# コンテナのSTATUSはExited
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b7ca3ef3875 ubuntu "bash" 5 seconds ago Exited (0) 4 seconds ago competent_keller
t
オプションを付与した場合は、コンテナは終了しない。
(挙動を確認するためにtオプションのみを付与しているが、現実的にi
オプションを付与しないで、t
オプションのみを付与するユースケースは思いつかない)
# 分かりやすさのためにデタッチする
$ docker run -dt ubuntu:latest
$ docker ps --all
# コンテナのSTAUSはUp
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8fe0d1b6fd7 ubuntu "bash" 27 seconds ago Up 26 seconds strange_shamir
Docker Composeでは ttyプロパティをtrueにする
参考までにデタッチしない場合を記載する。
# デタッチしない場合は疑似ttyが立ち上がった状態になる
# iオプションを指定しないので、入力はコンテナに渡らない
$ docker run -t ubuntu:latest
root@cbfb393cff94:/# echo HELLO
// 応答がない
// 入力を受け付けないのexitやCtrl + Cなども受け付けない
i
オプションを付与する(分かりやすさのためにt
オプションも付与する)。
疑似ttyが入力を受け付ける。
$ docker run -it ubuntu:latest
root@299f5cfdbbe0:/# echo 'Hello'
Hello
Docker Composeではstdin_open: true
とする。
ホストのttyを確認する。
$ tty
/dev/pts/0
ubuntu:latestを起動する
$ sudo docker run -itd --name ubuntu-sample ubuntu:latest
コンテナubuntu-sample
にログインしてプロセスを確認する。
以下例では簡略化のため示していないが2022年05月29日時点のDocker公式のubuntu:latestはpsコマンドが入っていないのでインストールする(apt install -y procps
)
$ sudo docker exec -it ubuntu-sample /bin/bash
root@f839023fec94:/# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 8 0.0 0.6 4628 3184 pts/1 Ss 01:34 0:00 /bin/bash
root 224 0.0 0.3 7060 1624 pts/1 R+ 01:34 0:00 \_ ps auxf
root 1 0.0 0.4 4492 2232 pts/0 Ss+ 01:33 0:00 bash
bash
のTTYにはコンテナ起動時にtオプションによって作成されたpts/0が接続/bin/bash
のTTYはpts/1が接続意味はないが参考までにhttpd:latestをtオプションを付与して起動してみる。
$ sudo docker run -td -p 8000:80 --name httpd-sample httpd
コンテナhttpd-sample
にログインしてプロセスを確認する。
以下例では簡略化のため示していないが2022年05月29日時点のDocker公式のhttpd:latestはpsコマンドが入っていないのでインストールする(apt install -y procps
)。
$ sudo docker exec -it httpd-sample /bin/bash
root@57a67d981f30:/usr/local/apache2# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 91 0.0 0.7 4484 3520 pts/1 Ss 01:56 0:00 /bin/bash
root 427 0.0 0.6 6700 2872 pts/1 R+ 02:00 0:00 \_ ps auxf
root 1 0.0 0.5 5936 2820 pts/0 Ss+ 01:56 0:00 httpd -DFOREGROUND
www-data 7 0.0 0.5 751860 2436 pts/0 Sl+ 01:56 0:00 httpd -DFOREGROUND
www-data 8 0.0 0.5 751860 2436 pts/0 Sl+ 01:56 0:00 httpd -DFOREGROUND
www-data 9 0.0 0.5 751860 2436 pts/0 Sl+ 01:56 0:00 httpd -DFOREGROUND
httpd -DFOREGROUND
のTTYにはコンテナ起動時にtオプションによって作成されたpts/0が接続/bin/bash
のTTYはpts/1が接続ちなみに起動時にtオプションを指定しないでhttpd:latestを起動した場合はhttpd -DFOREGROUND
は?
になる。
通常デーモンはTTYが接続されない。その場合にはpsコマンドのTTYは?
になる。
以下にtオプションを指定しない(こちらが通常)場合の例を示す。
root@08c958e0c19b:/usr/local/apache2# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 91 0.0 0.6 3968 2904 pts/0 Ss 02:03 0:00 /bin/bash
root 422 0.0 0.6 6700 2940 pts/0 R+ 02:03 0:00 \_ ps auxf
root 1 0.0 0.5 5936 2848 ? Ss 02:02 0:00 httpd -DFOREGROUND
www-data 7 0.0 0.5 751860 2396 ? Sl 02:03 0:00 httpd -DFOREGROUND
www-data 8 0.0 0.5 751860 2396 ? Sl 02:03 0:00 httpd -DFOREGROUND
www-data 9 0.0 0.5 751860 2396 ? Sl 02:03 0:00 httpd -DFOREGROUND
Docker Compose
tty: true
stdin_open: true
docker attach
とdocker exec
の違いでtオプションを理解する。ubuntu:latest
を例に挙動を確認する。
$ docker run -dit ubuntu:latest
44d6eef272553820e3aac6ef900c89bc84d49e20a139e9e2b45d1ca477fc1334
$ docker attach 44d6eef2725
root@44d6eef27255:/# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 0.1 4488 3732 pts/0 Ss 06:03 0:00 bash
root 8 0.0 0.0 7056 1608 pts/0 R+ 06:03 0:00 ps aux
root@44d6eef27255:/# exit
exit
上記のようにPIDが1のbashに標準入出力が接続されている。
よってexit
コマンドを発行した場合は、PIDが1のプロセス(ルートプロセス)が終了するのでコンテナも終了する。
$ docker ps --all
# コンテナSTATUSはExited
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44d6eef27255 ubuntu "bash" About a minute ago Exited (0) 9 seconds ago objective_elgamal
$ docker exec -it 44d6eef27255 /bin/bash
root@44d6eef27255:/# ps auxf
# 標準入出力はPIDが16の/bin/bashに接続されている。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 16 0.6 0.1 4488 3720 pts/1 Ss 06:11 0:00 /bin/bash
root 24 0.0 0.0 7056 1556 pts/1 R+ 06:11 0:00 \_ ps auxf
root 1 0.0 0.1 4488 3520 pts/0 Ss+ 06:10 0:00 bash
root@44d6eef27255:/# exit
exit
上記のように標準入出力はPIDが16の/bin/bashに接続される。exit
コマンドを発行した場合、PIDが16のプロセスが終了して、PIDが1のプロセス(ルートプロセス)は終了しないのでコンテナは稼働したままになる。
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44d6eef27255 ubuntu "bash" 10 minutes ago Up 3 minutes objective_elgamal
httpdはPIDが1のプロセスでhttpdデーモンが稼働する(httpd -DFOREGROUND
)。
よってオプションを付与しなくてもコンテナは終了しない。
$ docker run -d httpd:latest
bb5c45b3c38671265e5e96c71aee415981b45034f7e6dd5901a5ea1b7c8a5306
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb5c45b3c386 httpd "httpd-foreground" About a minute ago Up About a minute 80/tcp competent_curie
httpd:latestのPIDが1のプロセスはhttpdデーモンが稼働する。
よって以下はエラーにはならないが、bashに接続されるわけではない。
$ docker attach bb5c45b3c386
docker execでログインする。
psを見るために
procps`をインストールする。
$ docker exec -it bb5c45b3c386 /bin/bash
root@bb5c45b3c386:/usr/local/apache2# apt -y update && apt install -y procps
.....
.....
.....
root@bb5c45b3c386:/usr/local/apache# ps auxf
ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 92 0.0 0.1 3964 3300 pts/0 Ss 06:54 0:00 /bin/bash
root 423 0.0 0.1 6696 3040 pts/0 R+ 06:56 0:00 \_ ps auxf
root 1 0.0 0.2 5932 4524 ? Ss 06:54 0:00 httpd -DFOREGROUND
www-data 8 0.0 0.1 1210608 3492 ? Sl 06:54 0:00 httpd -DFOREGROUND
www-data 9 0.0 0.1 1210608 3560 ? Sl 06:54 0:00 httpd -DFOREGROUND
www-data 10 0.0 0.1 1210608 3492 ? Sl 06:54 0:00 httpd -DFOREGROUND
root@bb5c45b3c386:/usr/local/apache# exit
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb5c45b3c386 httpd "httpd-foreground" 3 minutes ago Up 3 minutes 80/tcp youthful_rubin