- docker container run {イメージ名} : 指定したイメージからコンテナを生成して実行する
- -i : 標準入力を有効化(Interactable Shell)
- -t :疑似ターミナルとの接続
- –rm : コンテナを実行した後に自動で削除する
- –name {コンテナ名}: コンテナ生成時に名前を自分でつける
- docker container inspect : コンテナの詳細情報を表示する
- docker container prune : 停止中のコンテナをすべて削除する
まずは、この記事で使用するイメージについて解説します。
前回の記事では、hello-worldというイメージを使用しました。このイメージは、こちらからの入力を受け付けず(-iオプションを付けても)、出力だけを行って終了するものでした。
今回は、より実践的なUbuntuイメージを使って、実際の使用例に近い使い方を解説していきたいと思います。
どちらもよくわからないという方は、以下のように理解していただければ大丈夫だと思います。
- Ubuntu: Linuxディストリビューションの一つで、実際のOS環境を再現するために使用される
前回の記事で解説したイメージのpullから実行を行うための、一番シンプルなコマンドを使用していました。
具体的には、以下のコマンドです。
- imageのDocker Hubからのpull ( image pull )
- コンテナの生成 ( container create )
- コンテナの開始 ( container start )
しかし、毎回これを打っていては手間がかかる + 入力ミスが増えるので、docker container run {イメージ名}コマンドを使うことで、先程の3つのコマンドを一気に実行できます。
docker container run ubuntu
実行すると、以下のような出力がされると思います。pullに少し時間がかかる可能性があります。
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
9f23a71f1e31: Pull complete
Digest: sha256:8a37d68f4f73ebf3d4efafbcf66379bf3728902a8038616808f04e34a9ab63ee
Status: Downloaded newer image for ubuntu:latest
このコマンドの出力を日本語に訳すと、以下のようになります。
Docker ubuntu:latestというimageがローカルで見つかりませんでした
最新 : library/ubuntuからPullを行います
9f23a71f1e31: Pull完了
Digest : sha256:....
Status: ubuntu:latestというイメージを新しくダウンロードしました
そもそも、ubuntuのシェルとはなにかという話ですが、シェルとは、Linuxカーネルと私達が対話するためのインターフェイスのようなものです。
このシェルを通して、私達は、コマンドを打って処理を実行しています。
しかし、DockerでUbuntuをrunしても何も表示されませんでした。
試しにDocker container ls -aコマンドを使用して今作成したコンテナの状態を確認してみます。
docker container ls -a
以下のようなコンテナ一覧が出力されると思います。
ここで注目するのがコンテナ実行時のデフォルト実行コマンド(COMMAND)
です。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e4186b24d43b ubuntu "/bin/bash" 12 hours ago Exited (0) 12 hours ago blissful_bardeen
今回の場合、COMMANDは/bin/bash
になっています。
つまりは、bashをデフォルトで起動するはずです。
bashはシェルですが、以下の2つのモードがあります。
- Interactive Shell(対話的シェル)
- ユーザーからの入力を受け付ける
- コマンド実行後もシェルは終了せずに次の入力を待つ
- Non-Interactive Shell(非対話的シェル)
- ユーザーからの入力を受け付けない
- スクリプトやコマンドを実行し、タスクが終了するとシェルも自動終了する
今回コンテナに対して入力ができずにすぐに止まってしまったのは、Non-Interactive Shell
モードで起動しているのが原因ということがあります。
Dockerのコンテナ内のbashは明示的にInteractive Shell
モードに設定しないと、デフォルトではNon-Interactive Shell
モードになっています。
Interactive Shell
モードを有効にするには、コンテナ生成時(create,run)に-i(interactive)オプション
をつけることで有効にできます。
一度-i
オプションを付けずにコンテナを作ってしまった場合、そのコンテナではInteractive Shell
モードで実行することはできません。Interactive Shell
モードが有効になっているコンテナがいい場合は、再度新しいコンテナを生成し、-i
オプションを付与する必要があります。
今回の場合docker contaienr run ubuntu
というコマンドを実行しているのでこのコンテナではもうInteractive Shell
モードとしてコンテナを実行することできないということになります。
では、今度はInteractive Shell
モードを有効化してUbuntuコンテナを生成してみます。
docker container run -i ubuntu
実行すると、何も表示されずにカーソルが1つ下の行に動いただけだと思います。
実はこれでInteractive Shell
モードでシェルが動いています。
試しに、ls
コマンドを実行して、カレントディレクトリのファイルを表示してみます
ls
bin
boot
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
わかりにくいですが、表示自体はうまくできているようです。
Shellにコマンドを送れるのは確認できたので、exit
コマンドを使ってShellを抜けようと思います。
exit
exitコマンドを実行すると、いつものシェルが表示されると思います。
しかし今の状態では、Shellとの対話はできているが、ターミナルのように入力や現在の状態を表示、サポートする機能
が無効になっている状態になっているのがわかったかと思います。
それを解決するのが、-t
オプションになります
Dockerコマンドにおける -t
オプションは、疑似ターミナル(pseudo-TTY)を割り当てるために使用されます。具体的には、以下の機能を提供します。
- 疑似ターミナルの割り当て:コンテナ内で実行されるプロセスに対して、ターミナル特有の機能を利用可能にします。
- ターミナル制御:コマンドライン編集、テキストのカラー表示、シグナルの送信(例:Ctrl+Cでの中断)などが可能になります。
つまりは、-tオプションをつけることで、今実行しているターミナルをコンテナ内のbashを実行するターミナルと紐づける事ができるということです。
これも-i
オプションと同じように、一度コンテナを作ってしまうと変更できないオプションになるので注意してください。
基本的には、-i
と-t
オプションは一緒に使用するので、セットで-it
として打つことができます。(他にも組み合わせは可能ですが、とりあえず)
では-it
オプションを付けた新しいコンテナを生成して動作が理想的なものかを確認します。
docker container run -it ubuntu
実行した結果も問題なくよく見るターミナル(-t)とシェル(-i)の表示になりました
root@7eb01937ee25:/# ls
bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
-it
オプションはシンプルなDockerコマンドのdocker container create ubuntu
などのコンテナを生成するときにもつけることができます。
どちらかというと、docker contaienr run
コマンドに-it
オプションを付けている場合、内部ではdocker container create
のときに-it
オプションを付けている挙動になっているので、もしdocker container create
を使う場合かつターミナルを使いたい場合は、-it
オプションをつけるようにしてください。
Dockerのコンテナは一回だけの使い捨てのような使い方をする場合もあります。
その場合は、今までのように-it
を指定せずにNon-Interactive Shell
モードを使ってコンテナを実行するほうがスマートです。
まずは、ls
コマンドをコンテナに実行させようと思います。
docker container run ubuntu ls
実行するとすぐに以下のような出力があります。
コンテナは当然lsコマンドを実行後に停止するので、これでOKです。
bin
boot
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
しかし、使い終わったコンテを削除を毎回するのは面倒なので、--rm
オプションを使って実行後コンテンを自動削除するようにできます。
docker container run --rm ubuntu ls
出力は何も変わりません。
bin
boot
dev
etc
home
lib
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
実行後のコンテナが消えていることをdocker contaiern ls -a
で確認して見ると削除されていることがわかるかと思います。
コンテナに名前をつける : docker container run –name {名前} {イメージ名}
Dockerのコンテナは同じイメージから何個も生成したり、作って後で使うなどのケースが多くあります。
そのような場合に便利なのがコンテナに名前をつける事ができるオプションの--name
になります。
コンテナ起動や実行時にコンテナID
やよくわからない名前
よりはタイポや認識ミスが少なくなるという効果も期待できます。
使い方は簡単で以下のようにrun
のあとに--name {コンテナ名} {イメージ名}
のように記述することでコンテナ名をつけることができます。
docker container run --name test ubuntu
確かに、NAMESの部分がtestとなっています。
これでコンテナの識別がよりしやすくなると思います。
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ec9b2639567 ubuntu "/bin/bash" 4 seconds ago Exited (0) 4 seconds ago test
このオプションは、docker container create
のときにも指定できるので合わせて使ってみてください
以前作成したコンテナのオプションを忘れてしまった場合や「何だこのコンテナ動かないぞ」と思ったときに想定されるオプション(-it)がついているかを確認することで原因の究明をします。
そのような場合に使うのが、docker container inspect {コンテナID or コンテナ名}
というコマンドです。
試しに別々のオプションを設定した2種類のコンテナを作成して、見比べてみます
- docker container create –name test1 ubuntu
- docker container create –name test2 -it ubuntu
test1のコンテナは何もオプションをつけずに、test2のコンテナはコンテナのシェルをInteractive Shell
モードにするのと、擬似ターミナル
の設定を有効にしています。
まずtest1のコンテナに対してdocker container inspect
コマンドを実行してみます
docker container inspect test1
長い出力が出ますが今回注目するのは、Config
部分になります。
bool値で設定が有効/無効
を確認できます。
[
{
"Id": "8fda6020316546a8927f5b362fd2498d814ffe9a3c1eb317b8941505d6ee99da",
"Created": "2024-09-16T07:57:33.009301173Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "created",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 0,
"Error": "",
"StartedAt": "0001-01-01T00:00:00Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:1a799365aa63eed3c0ebb1c01aa5fd9d90320c46fe52938b03fb007d530d8b02",
"ResolvConfPath": "",
"HostnamePath": "",
"HostsPath": "",
"LogPath": "",
"Name": "/test1",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
25,
206
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/ddcd6fc0aa3aaa52830a57efa0191b5f20cc22005bc9dee2d09965501dc47025-init/diff:/var/lib/docker/overlay2/419e5e8ff6d09902349966ed5474fff60ef5c70973b4cf49f2b9968ca97fb4d1/diff",
"MergedDir": "/var/lib/docker/overlay2/ddcd6fc0aa3aaa52830a57efa0191b5f20cc22005bc9dee2d09965501dc47025/merged",
"UpperDir": "/var/lib/docker/overlay2/ddcd6fc0aa3aaa52830a57efa0191b5f20cc22005bc9dee2d09965501dc47025/diff",
"WorkDir": "/var/lib/docker/overlay2/ddcd6fc0aa3aaa52830a57efa0191b5f20cc22005bc9dee2d09965501dc47025/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "8fda60203165",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "24.04"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "",
"EndpointID": "",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
}
}
]
以下は、2つのコンテナのConfig部分
を抽出したものになります。
- test1 コンテナのConfig
{
"Hostname": "8fda60203165",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "24.04"
}
}
- test2 コンテナのConfig
{
"Hostname": "32e780ce201e",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "24.04"
}
}
オプションの-i
はOpenStdin
部分、オプションの-t
はTty
部分になります。
見比べるとtest1コンテナは両方false、test2コンテナは両方trueになっていることが確認できます。
このように、不具合や想定していない実行結果になったときに確認するのに適したコマンドになります。
使用していない(Exited or Created)状態のコンテナを削除するには、docker container rm {コンテナ名}
としていましたが、コンテナが大量にあるときにはとても面倒な作業になります。
なので、コマンド一発で使用していないコンテナすべてを削除するコマンドが存在します。
それが、docker container prune
になります。
このコマンドは実行すると、本当にいいですか?と聞いてくるので問題なければy
、取り消したければN
を押して実行してください
docker container prune
以下が前のinspectorコマンドの確認のために作成したコンテナを削除した場合の出力です。
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
32e780ce201e412b3562aa122d30029e05029091f54aaf2d48adca0eeac59346
8fda6020316546a8927f5b362fd2498d814ffe9a3c1eb317b8941505d6ee99da
Total reclaimed space: 0B
これで面倒な作業がまた一つ減るかと思います。
この記事では、Dockerを使う上でかなり使用頻度の高いコマンドを紹介しました。
かなり長くなってしまったので、テーマ別に関連しそうなコマンド事に記事を分けています。
ぜひほかの記事も御覧ください。
これ以外にもたくさんのコマンドがあるので、ぜひドキュメントを読んで便利なコマンドを見つけてみてください。