Chapter 06

2部: コンテナ起動時の基本の指定

ほげさん
ほげさん
2022.03.21に更新

コンテナの起動と停止の仕方を理解できたら、次は container run のオプションについて学びましょう。

このページでも特定の用途によって使い分けたりをしない基本的な操作について学びます。

このページで初登場するコマンドとオプション

コンテナを起動する - container run

オプション 意味 用途
-i
--interactive
コンテナの標準入力に接続する コンテナを対話操作する
-t
--tty
擬似ターミナルを割り当てる コンテナを対話操作する
-d
--detach
バックグラウンドで実行する ターミナルが固まるのを避ける
--rm 停止済コンテナを自動で削除する 起動時に停止済コンテナと
一意な情報が衝突するのを避ける
--name コンテナに名前をつける コンテナを指定しやすくする
--platform イメージのアーキテクチャを明示する M1 Mac で必要な場合がある

コンテナを対話操作する

【 2部: コンテナの基礎操作 】で使った Nginx のコンテナは起動すると nginx が起動しましたが、Ubuntu のコンテナは起動すると bash が操作できます。

bash のような対話操作を行う場合は、ホストマシンのターミナルからの入力を受け付けるための --interactive オプションと、コンテナの擬似的な出力先を作るための --tty のオプションが必要になります。

Host Machine
$ docker container run \
    --interactive      \
    --tty              \
    ubuntu:20.04

# 

# に切り替わったプロンプトは Ubuntu コンテナの bash です。

コンテナは仮想サーバではなく Docker により作られた Linux のいち Namespace ですが、Docker によりあたかも別 OS のように作られており、OS 情報などを確認することができます。

Container
# cat /etc/lsb-release

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"

bash などの対話操作を行うためにコンテナを起動する場合は --interactive オプションと --tty オプションをセットで指定する必要があるということを覚えておきましょう。

一通り操作してみたら、bash を終了してからコンテナを削除してしまいましょう。

Container
# exit

$ docker container rm <CONTAINER ID>

コンテナをバックグラウンドで起動する

--detach オプションを使うと、コンテナをバックグラウンドで実行することができます。

これを Nginx コンテナの nginx のような常駐プロセスを起動するときに指定すると、ターミナルがコンテナの出力で固まらなくなります。

Host Machine
$ docker container run \
    --detach           \
    --publish 8080:80  \
    nginx:1.21

606ccda5b16a0f6ebb8496e20a2abc1da40a48ab4f43aef8bc6d0117ce65fad1

$

フォアグラウンドで実行したときに見えた大量の出力はなくなり、CONTAINER ID を表示するのみとなります。

この状態でも当然コンテナ一覧の確認を行えばコンテナの存在は確認できますし、 http://localhost:8080 にアクセスすれば Nginx の Web サーバにアクセスできます。

コンテナ一覧の確認や停止や削除などの操作も、フォアグランドで起動したときと同様です。
バックグラウンドで起動している起動中コンテナを、忘れないうちに強制削除しておきましょう。

Host Machine
$ docker container rm \
    --force           \
    606ccda5b16a0f6ebb8496e20a2abc1da40a48ab4f43aef8bc6d0117ce65fad1

この本では基本的には --detach オプションを指定することにしますが、動くことが確認できていないコマンドを試行錯誤しながら組み立てる段階では指定しない方が動作確認がしやすいです。
状況に合わせて付け外ししてください。

また当然ですが、bash のような対話操作をする場合は付けません。

コンテナ停止時に自動で削除する

--rm オプションを使うと、コンテナが停止したときに自動で削除されるようになります。
停止済コンテナを再起動などで再活用するつもりがない場合は、このオプションをつけておくことで停止済コンテナが溜まり続ける状態を防ぐことができます。

Host Machine
$ docker container run \
    --rm               \
    --detach           \
    --publish 8080:80  \
    nginx:1.21

974b0b8a40d8d1a3c5b693720982c1a47ba948272e124da75c822f0ad0f4e875

$

コンテナ起動時に --rm オプションを指定したコンテナは、強制削除ではなくただの停止を実行しても、削除されていることが確認できます。

Host Machine
$ docker container stop \
    974b0b8a40d8d1a3c5b693720982c1a47ba948272e124da75c822f0ad0f4e875
    
$ docker container ls \
    --all
    
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES    

この本では停止済のコンテナを操作することはないため、--rm オプションは常に指定するものとします。

また、後述する --name オプションと合わせてよく使います。

コンテナに名前をつける

--name オプションを使うと、ランダムで毎回割り当てられるコンテナの名前を指定できるようになります。

Host Machine
$ docker container run \
    --name web-server  \
    --rm               \
    --detach           \
    --publish 8080:80  \
    nginx:1.21

1144303f9d718b35bf7a354f51872dde18bffbcdd8ca900a2f7efb5c9fe62d97

$

( 見切れてしまっていますが ) NAMESweb-server になっていることが確認できます。

Host Machine
$ docker container ls

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                  NAMES
1144303f9d71   nginx:1.21     "/docker-entrypoint.…"   35 seconds ago   Up 35 seconds   0.0.0.0:8080->80/tcp   web-server

この NAMES でもコンテナを指定することができるので、コンテナ停止などをするときに CONTAINER ID を調べる手間を省けます。

Host Machine
$ docker container stop \
    web-server

ひとつ注意ですが、コンテナ指定に使うということは NAMES は一意である必要があるため、同じコンテナ名でコンテナを複数起動することはできません。
このカウントには停止済コンテナも含まれるため、名前をつけたコンテナは停止ではなく削除をするようにしておいた方が不要なエラーが減るでしょう。

そのため --name オプションは --rm オプションと合わせて使うことが多いです。

この本では明瞭かつランダム性が排除できるため、--name オプションは常に指定します。

コンテナ起動時の挙動を変更する

オプションではありませんが、container run[command] は正しく理解する必要がある重要な引数なので、ここで確認します。

新コマンド
$ docker container run [option] <image> [command]

ここまでに利用した Nginx のコンテナは起動すると nginx が起動し、Ubuntu のコンテナは bash が起動しました。

これらの違いはイメージの違いによるもので、イメージにはコンテナを起動したときにどんなコマンドを実行するか があらかじめ書き込まれています。
この本ではそれを便宜上 デフォルト命令 と呼びます。

image

container run[command] を指定しなかった場合はイメージごとに決まっているデフォルト命令が実行されますが、[command] を指定するとデフォルト命令 ではなく 任意の命令を実行させることができます。
この本ではそれを便宜上 指定命令 と呼びます。

これにより Nginx コンテナで nginx を起動しり bash を起動したりできるようになります。

Nginx コンテナをデフォルト命令 ( nginx ) で起動する ( 例1 )

Host Machine
$ docker container run      \
    --name nginx-web-server \
    --rm                    \
    --detach                \
    nginx:1.21

Nginx コンテナを指定命令 ( bash ) で起動する ( 例2 )

Host Machine
$ docker container run \
    --name nginx-bash  \
    --rm               \
    --interactive      \
    --tty              \
    nginx:1.21         \
    bash

ここで大事になるのが イメージコンテナ の関係を正しく把握することです。

例2で Nginx のコンテナを bash 指定で起動しましたが、これは例1とは違う Nginx のコンテナの bash です。
イメージを OS や仮想サーバのようなものだと思っていると「イメージに命令して中の nginx を起動した」とか「イメージに SSH をして bash を使う」と捉えがちですが、全く違います。

image

container run をするたびに 新しいコンテナがイメージから作られている ことをよく理解しましょう。

image

例1の方のコンテナで bash を起動するには、【 2部: コンテナに接続する 】で説明する container exec を使います。

image

なんども繰り返しますが、なにどうする のかよく考えるようにすれば、この手の勘違いは起きずスムーズに理解することができます。

( 余談 ) コンテナの OS アーキテクチャを指定する

この本では細かいことは割愛しますが、OS のアーキテクチャを明示的に指定する必要がある場合は --platform オプションを使います。

たとえば Docker Hub の Ubuntu イメージを見てみると、OS/ARCH というところにいくつか候補があることがわかります。

image

一般に Intel or AMD CPU を使っている場合 ( = Windows と Intel の Mac ) は linux/amd64 を、ARM CPU を使っている場合 ( = M1 の Mac ) は linux/arm64/v8Docker が自動で 選びます。

この linux/amd64 もしくはそれに類するものはまず間違いなく存在しますが、linux/arm64/v8 は存在しないことが珍しくありません。

ARM CPU を利用しているが linux/arm64/v8 が存在しない場合に、強引に linux/amd64 のイメージを利用するために --platform オプションを使うことになります。

--platform=linux/amd64 は、Intel or AMD CPU の人にとっては未指定時と同じ結果になるため影響はありません。
また --platform=linux/arm64/v8 を明示する状況も多くありません。

この本では、必要な場合に限り --platform=linux/amd64 を指定するのみとします。
次の表を見て状況に応じて解釈し対応してください。

オプション 自分のマシン 結果
--platform=linux/amd64 Intel or AMD CPU 意味がない
気にしなくて良い
削っても良い
--platform=linux/amd64 ARM CPU 大事
そっくりそのまま指定する
--platform=linux/arm64/v8 Intel or AMD CPU まず目にしない
この本にはない
--platform=linux/arm64/v8 ARM CPU 意味がない
まず目にしない
この本にはない

余談ですが、自分のホストマシンと一致する OS/ARCH が存在しない場合の対処が --platform オプションだけで十分かは、イメージによりケースバイケースです。
OS アーキテクチャについて気になる方は以前公開したこの本を、

https://zenn.dev/suzuki_hoge/books/2021-07-m1-mac-4ede8ceb81e13aef10cf

M1 Mac での Docker 利用については同じく以前公開したこの本を、

https://zenn.dev/suzuki_hoge/books/2021-12-m1-docker-5ac3fe0b1c05de

それぞれご覧いただければと思います。

まとめ

簡潔にまとめます。

オプション この本での方針 実運用時の考え方
--interactive 対話操作をする場合は指定 常に指定しても害はない
--tty 対話操作をする場合は指定 常に指定しても害はない
--detach 対話操作をしない場合は指定 デバッグなどでは外した方が良いこともある
--rm 常に指定 停止済コンテナを活用するかで判断する
--name 常に指定 衝突さえ理解していれば指定して損はない
--platform 必要な場合のみ指定 Intel or AMD CPU なら検討不要、見ても無視可
ARM CPU ならケースバイケース

忘れてしまったときは立ち返ってみてください。

このページで作成したものの掃除

Host Machine
$ docker container rm --force \
    nginx-web-server

例2の bash は終了しておきましょう。

Container
# exit