【Docker】Docker初心者がコンテナ技術に触れて覚えたこと②

2020年12月5日

こんにちは、キクです。

僕は先日、Dockerの基礎に関する記事を書きました。
Docker学習を始めたばかりの僕が苦戦した部分で同じように苦戦している人に少しでも共有できることがあるのではないかと思ったのがきっかけです。

そして今回も前回に引き続き『Dockerの基礎』に関する内容を書いていこうと思います。

「初心者だからこそ発信できる内容があるのではないか?」

そんな思いで本記事も書いていきますので、少しの間お付き合いいただければと思います☺️

前回の記事では以下のような内容に触れました。

  • Dockerの基礎的な登場人物
  • コンテナの作成について

そして本記事では以下3点についてお話ししていきます。

  • コンテナからの入退室について
  • Dockerイメージの作成・更新について
  • Dockerファイルの内容とコンテナの関係について

それでは、よろしくお願いします。

コンテナからの入退室について

前回の記事ではコンテナを「Dockerイメージから作成されるホストOSとは異なる環境」とお話ししました。
今回は一度「ホストOSをマンション」「コンテナをマンション内の1戸」と想像してみることにしましょう。
厳密には違うのですが、本テーマにおいてはイメージしやすいかなと思っております(笑)

コンテナからの入退室方法には以下のようにいくつかパターンがあります。

コンテナからの主な入退出方法

・exitで退出
・detachで退出
・execで入室
・attachで入室

それぞれ「マンションの話」に例えて進めてみようと思います。

exit:ブレーカーを落として家を出る

コンテナから退室する方法の1つとしてexitコマンドを使った方法があります。
この退室方法はコンテナ内で以下のコマンドを実行するだけです。

$ exit

退室したらホストOS側で以下のコマンドを実行してコンテナ一覧を表示してみましょう。

$ docker ps -a

すると以下ような結果が表示されます。
各値は環境により異なります。

CONTAINER ID        IMAGE             COMMAND     CREATED             STATUS                       PORTS      NAMES
be18a17aabc3        e5dd56342096      "bash"      29 hours ago        Exited (0) 4 seconds ago               test_contena

ここで注目したいのはSTATUS列です。
Exited」と表示されており、コンテナが停止していることが分かります。
これは家のブレーカが落ちている状態に似ています。
ブレーカーが落ちている家では、家電なども使えないのでほとんど何もできませんよね。
このように停止状態のコンテナに再度入室したい場合には先にブレーカーを上げてあげる必要があります

ブレーカーを上げる(コンテナを起動する)ためには以下のコマンドを実行します。

■コンテナの起動

$ docker start <コンテナ名またはコンテナID>

■コンテナの再起動

$ docker restart <コンテナ名またはコンテナID>

起動したコンテナに入室するためにはexecコマンド」を使用します。
このコマンドはコンテナが起動した状態でないと使えないので、先に起動または再起動を実施してブレーカーを入れておきましょう。

■コンテナへの入室

$ docker exec -it <コンテナ名またはコンテナID> bash

detach:ブレーカーを上げたまま家を出る

次にdetachという方法を用いた退室について。
これもコンテナから退室する方法の1つですが、exitとは大きく違う部分があります。
それは「ブレーカーを上げたまま家を出る」ということです。

それではまずdetachの方法をお話しします。
exitが「exitコマンド」の実行だったので、detachも「detachコマンド」の実行すればいいのかなと思いますよね。

・・・でも違うんです。

detachをするにはctrl + p + qというショートカットキーを入力してあげることで実行できます。
まさかのショートカットキーです(笑)

detachをしたらexitと同じようにコンテナの一覧を表示してみましょう。

$ docker ps -a

すると今度はこんな結果が表示されます。
同じく各値は環境により異なります。

CONTAINER ID        IMAGE             COMMAND     CREATED              STATUS              PORTS      NAMES
be18a17aabc3        e5dd56342096      "bash"      29 hours ago         Up 6 minutes                   test_contena

先ほどは「Exited」だったSTATUSが今回は「Up」と表示されていますね。
それゆえに「ブレーカを上げたまま」と表現していました。

detachしたコンテナへの入室方法は2パターンあります。
1つは、先ほどと同様に「execコマンド」で入室する方法。

$ docker exec -it <コンテナ名またはコンテナID> bash

もう1つはattachコマンド」を用いた方法。

$ docker attach <コンテナ名またはコンテナID>

execコマンド」では起動中のコンテナに入室できるんでしたね。
上記の通り、detachで退室した場合にはSTATUSUp(起動)状態ですので、すぐに入室できます。

またdetachの特性としては、コンテナ内のプロセスをそのままの状態で退室するというものがあります。
これはマンションの例で表すのが難しいですが、「テレビをつけたまま」とかその辺りが近いですかね・・・(笑)

しかしexecコマンド」で再入室した場合にはこれらのプロセスがある部屋とは別の部屋に入ることになります。
同じコンテナではあるんですけど、プロセスが起動している(テレビがついている)部屋とは違う部屋。
パラレル空間みたいなものですかね・・・。
ややこしいですね。

一方でattachコマンド」の場合は、detachの際に稼働していたプロセスのある部屋に入室することができます。
例えばtopコマンドを実行した状態でdetachしたのであれば、attachした時点でtopコマンドが実行されている画面が映るという具合です。
「テレビをつけたままの家に戻れる」ということです。

Dockerイメージの作成・更新について

コンテナを作成するために必要なものは「Dockerイメージ」でしたね。

それではDockerイメージはどのように作成すればいいのでしょうか?
Dockerイメージの作成は以下のパターンが存在します。

Dockerイメージの作成方法

・Dockerファイルから作成する
・コンテナをDockerイメージとして保存して作成する

Dockerファイルから作成する

Dockerイメージを作成するために必要になる言わば設計書になるもののことをDockerファイルといいます。
この「Dockerファイル」の実体はテキストファイルです。
そしてDockerファイルを「buildコマンド」によりビルドすることでDokceイメージが作成されます。

$ docker build -t <イメージ名>:<タグ名> .

上記コマンドの場合、ホストOSのカレントディレクトリ上にあるDockerファイルを用いてイメージ名/タグ名付きでDockerイメージを作成できます。
カレントディレクトリ:今現在操作をしているディレクトリ(フォルダ)のこと

Dockerファイルにどのようなことが書いてあるかについては後ほどお話しします。

コンテナをDockerイメージとして保存して作成する

Dockerイメージを作成するもう1つの方法。
それはコンテナから新しくDockerイメージを作成するという方法です。

作成するためには以下のようにcommitコマンド」を実行します。

$ docker commit <コンテナ名またはコンテナID> <新しいDockerイメージ名>

何か変更を加えたコンテナをDockerイメージとして保存しておくことができます。
そうして作成されたDockerイメージからは「何か変更を加えた」という状態に初めからなっているコンテナが作成できるということになります。

Windowsとかだと何かテキストファイルを編集して保存するときに「名前を付けて保存」ってありますよね?
コンテナからの作成はその「名前を付けて保存」のイメージに近いかなと思います。

先述の「Dockerファイルからの作成」との違いは、コンテナ内でどのような編集・更新が行われたかが不明瞭ということです。

後述しますがDockerファイルの中身では「コンテナの中をこんな状態にする」というような記載がされています。
そのためDockerファイルを見ることでそこから作成されるコンテナの中身を把握することができます。

しかし「commitコマンド」を使ったコンテナからDockerイメージを作成する方法ではDockerファイルにまではコンテナ内での変更内容が反映されるわけではないので中身が把握できません。
「名前を付けて保存」の場合を考えてみてもファイルを開くまではどのような変更がされているか分かりませんよね。
それと似ていてコンテナに入室して確認するまで中身の把握ができないです。

そのため、実際にDockerを使用していく上ではDockerファイルに変更内容を追記していく形が多いみたいです。

Dockerファイルの内容とコンテナの関係について

既に少し触れましたがDockerファイルとコンテナは、Dockerファイルを見ればコンテナがどういう構成なのか把握することができるという関係性です。

それでは散々先延ばしにしてきたDockerファイルの中身について見ていきましょう。
Dockerファイルの中身は以下のような内容が記載されています。
これは本当に基礎的な部分しか記載していないので、実際にはもっと多くのことを記載していきます。

Dockerファイルの中身(一部)

・FROM centos:latest
・RUN touch testfile

1行目の「FROM cemtos:latest」というのは「centosというイメージ名(リポジトリ名)」の「latestというタグ名」のDockerイメージをベースにするという意味になります。
2行目の「RUN touch testfile」というのは、1行目のベースから作成したコンテナ内で実行するコマンドの指定になります。

今回の場合は「コンテナ内でtestfileという空ファイルを作成するよ」ということになります。
これらを記載したDockerファイルからDockerイメージを作成(build)して、そこからコンテナを作成(run)すると、そのコンテナのOSCentOSであり、testfileが作成された状態になります。

もし3行目として「RUN touch testfile2」と記載したDockerファイルから作成したDockerイメージからコンテナを作成すれば「testfile」に加えて「testfile2」も作成された状態のコンテナが出来上がるということになります。

コンテナへの変更を可視化するために

少しまとめみたいな内容になりますが、複数人で同じ開発環境を使って開発を進めたいようなときにDockerはとても便利ですよね。
それぞれがDockerイメージをリポジトリからpull(あるいはrun)してコンテナを作成すれば、あっという間に環境が整います。

そしてゴリゴリとコンテナ内で作業をしていき、Dockreイメージにも反映してみんなと共有しながら開発を進めていけます。
そんなときDockerイメージにはどのように反映すれば良いのか。

commitしてDockerイメージを更新すればいいの?
Dockerファイルに変更内容を追記すればいいの?

例えば、コンテナ内でtestfile4というファイルを作った状態を保存したいとき。
「commitコマンド」でDockerイメージを新しく作成してしまうと「testfile4を作った」という情報はコンテナの中でしか分かりません。

そのため変更内容をDockerイメージに反映したいのであれば、Dockerファイルの4行目に「RUN touch testfile4」と追記してDockerイメージを再作成しましょう。
今回の話では登場しませんでしたが、「Dockerイメージレイヤー」というものとの関係でDockerファイルを更新する際には最終行に追記していくことが望ましいです。

Dockerファイルを見ればコンテナがどういう構成なのか把握することができる」
この関係性を守るためにはDockerファイルへ追記していくのが良さそうですね。

おわりに

いかがでしたでしょうか。

今回の記事では「コンテナへの入退室方法」や「コンテナを作成するDockerイメージを作成するDockerファイルのこと」についてお話ししました。
そして前回の記事も含めるとDockerを使い始める上で知っておきたい全体像をなんとなくでも把握できる内容になったかなと思います。
今回はあくまでもDockerの全体像をイメージできるようになることに重きを置いたので、細かなところまでは触れられませんでした。
そのため今後何か作業で分からなくなったらその都度調べることになってしまいます。

しかし全体像を「イメージできている」のと「イメージできていない」のとでは調べた内容への理解力は大きく違ってくると思います。
前回の記事と本記事がそんな「イメージできる」ためのお役に立てていれば幸いです。

僕はDockerという存在は知っていながらも使ってこなかった人間です。
しかし今回の学習を通してDockerに対するモヤモヤがだいぶ解消されました。
今後何かを学習するときに環境構築が必要ならば、積極的にDockerを利用していきたいと思います。
そしてみなさんにも今回の内容を思い出しながらDockerを使ってもらえればと思います。

ではでは!

  • LINE
  • -Docker
    -,