1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Docker]Dockerの使い方を理解する

Last updated at Posted at 2023-12-31

はじめに

HappinessChainというプログラミングスクールで学習しています。
今回は Docker について学んだ内容を纏めました。

前提条件

  • Docker Desktop をインストールしている事

Docker はもともと Linux 環境で設計されており、Linux 上で最も効率的に動作しますが、Docker Desktop のおかげで、Windows や macOS でも Docker を利用できます。
Docker Desktop はWindows や macOS 上に Linux の仮想環境を作成し、その中で Docker を実行します。この仮想環境はユーザーには見えませんが、Docker を実行するための基盤として機能します。

注意事項

  • この記事では旧Dockerコマンドを採用しています。
  • Windows でコマンド検証は行なっておりません。
  • Linux のコマンドについては解説していません。

Docker

Docker とは

Docker とはプログラムやアプリケーションを「コンテナ」と呼ばれる特殊な箱の中で実行するためのツールです。冒頭でも説明しましたが、DockerはLinux環境で設計されており、Linuxに元々あるコンテナ技術を使いやすく改良したものです。
コンテナはホストから隔離されており、それぞれ独立した環境で動作します。

Docker を使うメリット

1. イメージの共有
Docker ではアプリケーションとその開発環境が含まれるイメージを他の人と簡単に共有できます。
共有されたイメージを使用して、受け取った人は同じイメージからコンテナを生成し、すぐに一貫した開発環境で作業を開始できます。

2. 簡単な環境構築
Dockerfile(開発環境を定義したファイル)を使用することで、環境構築が簡単になります。 Dockerfile は必要な環境設定を記述することで、一貫した環境を自動的に作成します。

3. 軽量性
仮想マシンというのは通常ゲスト OS(仮想のオペレーティングシステム)を使ってアプリケーションを動かす方法です。しかしDocker(コンテナ型仮想化) ではこのゲスト OS が必要ありません。Docker はホスト OS の Linux カーネル(コンピュータの中心的な部分)を共有することで、非常に早く起動できます。

ただし、macOS や Windows を使っている場合は少し違います。
macOS では「HyperKit」または「Virtualization Framework」、Windows では「Hyper-V」または「WSL2」という特別な仮想化技術を使ってLinux を仮想環境で動かし、その上で Docker を実行します。
これは事実上、ゲスト OS を使用していることになります。
ですがこのゲスト OS はとても軽量で効率的に作られているので、他の仮想マシンに比べその存在をほとんど感じることはありません。

Docker イメージからコンテナを起動する

Docker イメージとは?

Docker イメージとはコンテナを起動するのに必要な設定ファイルを纏めたものです。
Docker イメージの取得には

  1. Dockerfile から作成する
  2. DockerHub から取得する
  3. Docker コンテナから作成する

の方法があり、本記事では ① と ② について説明します。
(② は後述、③ は滅多に使う事がないので割愛します)

DockerHub からイメージを取得する

DockerHub とは Dockerイメージをクラウド上で管理するホスティングサービスです。

Docker の操作はターミナルから行います。
以下のコマンドで hello-world イメージを取得します。
($はターミナルでの操作を表しており入力不要です)

$ docker pull hello-world

上のコマンドは以下のコマンドと同義であり、リポジトリ名(hello-world)以外を省略しています。

$ docker pull docker.io/library/hello-world:latest

ログにPull completeが表示されていれば取得成功です。
478afc919002の数字は異なっていても問題ありません。

result
latest: Pulling from library/hello-world
478afc919002: Pull complete

ホスト上にあるDockerイメージは docker images コマンドで確認できます。

$ docker images

REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
hello-world    latest    ee301c921b8a   8 months ago   9.14kB

ちゃんと取得できていますね。それぞれのヘッダーの意味は次のようになります。

  • REPOSITORY
    • イメージのリポジトリ名を表します。1 つのリポジトリに複数のタグが存在します。
  • TAG
    • リポジトリ内の特定のイメージを識別するためのラベルです。同じイメージの異なるバージョンや状態は、異なるタグを通じて識別されます。例えばイメージの新しいバージョン(3.0)がリリースされた時に、それは3.0のタグと最新のバージョンを意味するlatestのタグが付けられます。
  • IMAGE ID
    • イメージを一意に識別するための ID(ハッシュ値)です。イメージ内容に基づいてIDが生成され、イメージの内容が同じであれば同じ IMAGE ID になります。
  • CREATED
    • イメージが作成(ビルド)された日時を表します。pull した日時では無いので注意です。
  • SIZE
    • イメージのサイズを表します。

リポジトリの詳細を見たい場合は DockerHub でリポジトリ名(今回の場合だと hello-world)を検索します。

コンテナを起動する

Dockerイメージからコンテナを作成し起動するにはdocker runコマンドを使用します。
このコマンドは、イメージから新しいコンテナを作成するdocker createコマンドと、そのコンテナを起動するdocker startコマンドの機能を組み合わせたものです。

先程取得したhello-worldイメージからコンテナを作成し起動してみましょう。

$ docker run hello-world

ターミナルにHello from Dockerが表示されれば成功です。

result
Hello from Docker!
      ・
      ・
      ・

実はdocker runで指定したイメージがホスト上になければ、Docker が自動で DockerHub からイメージを取得します。確認のためdocker runに ubuntu のイメージを指定してみましょう。

$ docker run ubuntu

ログを確認すると Pull complete の文字が表示されているので、イメージが自動で取得されていることが分かります。

result
005e2837585d: Pull complete

まとめ

  • Docker イメージはコンテナを起動するのに必要な設定ファイルを纏めたもの
  • DockerHub は Docker イメージをクラウド上で管理するホスティングサービス
  • docker pull <image>で DockerHub からイメージを取得する
  • docker run <image>でイメージからコンテナを起動する
  • docker runは自動で DockerHub からイメージを取得する

Dockerfile からイメージを作成する

Dockerfile とは?

Dockerfile は Dockerイメージの設計図のようなもので、コードに基づいてどのような Dockerイメージであるかを定義したファイルです。

Dockerfileを使うと何が嬉しいのか?

コードで管理できる

Dockerイメージの内部構造は通常見えませんが、Dockerfile を使うことで、コンテナの構成をコードで明確に管理できます。
これにより同じ Dockerfile から再現可能なイメージが作成できます。

標準化された環境構築

Dockerfile を使用することで、アプリケーションが必要とする依存関係や環境設定を含む標準化された環境を作成できます。
例えば Ruby アプリケーションの場合、ホスト上にあるGemfileGemfile.lockをコンテナにコピーすることにより、開発、テスト、本番環境で同じバージョンの依存関係を保持できます。

バージョン管理

Dockerfile はテキストファイルなので、GitHub で管理する事が出来ます。
これにより変更履歴の追跡やバージョンのロールバックが容易に行えます。

Dockerfile を作成する

実際に Dockerfile を作成してみましょう。

今回はデスクトップにdocker_practiceディレクトリを作成してその中に Dockerfiletest2 の 2 つのファイルを用意しました。

tree
docker_practice
│
├── Dockerfile
└── test2

Dockerfileを作成する際、最初に記述するのはベースイメージの指定です。
FROM インストラクションを用いて、使用するイメージのリポジトリとタグを指定します。
タグを省略した場合、デフォルトで latest タグが適用されます。

Dockerfile
FROM ubuntu:latest

この記述によりubuntu の最新イメージがベースとして設定され、ここから続くコマンドはこのベースイメージに対して適用されます。

次にコンテナの中に test1ファイルを作成するためのコマンドを記述します。
Linux のコマンドを使用するにはRUNインストラクションを使用します。
RUNはビルド時(Dockerfile からイメージを作成する時)に実行されます。

Dockerfile
RUN touch test1

続いてローカルに作成した test2 をCOPYインストラクションを使ってコンテナにコピーします。コンテナにnew_dirディレクトリは作成していませんが、無ければ自動で作成してくれます。

Dockerfile
COPY test2 /new_dir/test2

最後にCMDインストラクションでイメージのデフォルトコマンドを指定します。
デフォルトコマンドとはイメージからコンテナを起動する際に、実行されるコマンドです。

次のコマンドではデフォルトコマンドにbashを指定しています。

Dockerfile
CMD ["bash"]

実はFROMに指定した ubuntu のデフォルトコマンドにbashが設定されているため、ここで改めてbashを設定する必要は実際にはありません。

これで Dockerfile の完成です。全体のコードを掲載しておきます。

Dockerfile
FROM ubuntu:latest
RUN touch test1
COPY test2 /new_dir/test2
CMD ["bash"]

Dockerfile をビルドする

作成したDockerfileからイメージをビルドするためには、docker build コマンドでbuild-contextを指定します。
build-contextはビルドに必要なファイルとディレクトリを内包したもので、以下のコマンドではカレントディレクトリ(.)がそれに当たります。
-t オプションでイメージ名を設定でき、タグを省略するとデフォルトで latest タグが適用されます。

$ docker build -t my-ubuntu .

次のようなログが表示されれば成功です。

result
writing image sha256:c7165ae2a1e7a0f1cf...

ビルドに必要なファイル・ディレクトリがbuild-contextに含まれるため、作成したDockerfileからCOPYコマンド(COPY test2 /new_dir/test2)を削除すると、test2ファイルはbuild-contextに含まれなくなります。これにより不要なファイルをDockerイメージに含めずに済み、ビルドプロセスの効率化を行えます。

コンテナの中身を確認する

docker runで起動したコンテナはデフォルトコマンドを実行後、自動的に停止(Exit)します。
-itオプションで、bash を対話的(インタラクティブ)モードで起動し、コンテナ内で bash を操作する事ができます。

それではdocker run -itでコンテナ内に入りましょう。

$ docker run -it my-ubuntu

root@~#と表示されればコンテナ内のアクセスに成功しています。
ここでlsコマンドを使ってファイルの確認を行ってみます。

bash
# ls

bin   dev  home  media  new_dir  proc  run   srv  test1  usr
boot  etc  lib   mnt    opt      root  sbin  sys  tmp    var

Dockerfile で定義した test1 と new_dir が作成されている事が分かります。
もちろん new_dir の中に test2 も作成されています。

コンテナは隔離しているのでlsで表示されたファイルシステムはホスト上から見る事は出来ません。

イメージを DockerHub に push する

Docker イメージを誰かに配布するには様々なアプローチが考えられますが、ここでは DockerHub にイメージを push して第三者にイメージを共有する方法を示します。

イメージを push するにはイメージ名をusername/repositoryの形式に変更する必要があります。イメージ名の変更にはdocker tagコマンドを使用します。

docker tag <SOURCE_IMAGE> <TARGET_IMAGE>

今回の場合ですと次のようになります。usernameは自分の username に置き換えて下さい。

$ docker tag my-ubuntu username/my-ubuntu

docker pushコマンドで名前を変更したイメージ名を push します。

$ docker push username/my-ubuntu

特にエラーが出なければ、DockerHub のマイページに push したイメージのリポジトリが作成されていると思います。

まとめ

  • Dockerfile を使うメリット
    • コンテナの構成をコードで明確に管理できる
    • 標準化された環境を簡単に構築できる
  • Dockerfile インストラクション
    • FROM : ベースのイメージを指定する
    • RUN : ビルド時に実行する Linux のコマンドを指定する
    • COPY : コンテナにコピーしたいファイルやディレクトリを指定する
    • CMD : Docker イメージのデフォルトコマンドを指定する
  • build
    • docker build .でDockerfileをビルドする
    • Dockerイメージに必要なファイルやディレクトリはbuild-contextに内包され、Dockerデーモンに送信される
  • push
    • イメージをpushするにはusername/imageの形式にイメージ名を変更する
    • docker tag <SOURCE_IMAGE> <TARGET_IMAGE>でイメージ名を変更する
    • docker push <image>でDockerHubにイメージをpushする

Dockerイメージの構造

レイヤーの構成

Docker イメージは、複数のレイヤー(層)によって構成されています。これらのレイヤーはイメージを形成するさまざまなファイルや設定の集合です。

Docker イメージは次の 2 種類のレイヤーによって成り立っています。

読み取り専用レイヤー
Docker イメージを構成するレイヤーは基本的に読み取り専用です。これらはイメージが持つソフトウェアやライブラリ、アプリケーションのコードなどを含んでいます。

編集可能レイヤー
コンテナを起動すると、読み取り専用レイヤーの上に編集可能なレイヤーが追加されます。コンテナ内で行われる変更(ファイルの作成や変更など)は、この編集可能レイヤーに保存されます。


このレイヤー構造により次の効果をもたらします。

ストレージの節約
同じイメージから作成された複数のコンテナは、同じ読み取り専用レイヤーを共有しますが、編集可能レイヤーはそれぞれ別々に持ちます。これにより同じベースイメージの複数のコンテナを、ストレージを節約しながら運用できます。

環境のリセット
編集可能レイヤーを破棄することで、コンテナの変更を元に戻し、イメージの初期状態にリセットすることができます。


今回Dockerfile でFROM ubuntuを指定しましたが、これにより ubuntu がイメージのベースレイヤーとして設定されます。これは新しいイメージの基礎となる部分です。
DockerHub にイメージを push する際、ベースレイヤー(ubuntu)は既に DockerHub 上に存在するため、その他の新しいレイヤーだけが push されます。これによりアップロードの時間とストレージの使用量が節約されます。

まとめ

  • Dockerイメージは複数のレイヤー(層)構造
  • レイヤーには読み取り専用と編集可能レイヤーがある
  • レイヤー構造によりDockerイメージの配布と管理をより効率的にする

Docker の仕組み

Docker の構成

Docker は、以下の 3 つの主要なコンポーネントで構成されています。

  1. Docker クライアント
  2. Docker デーモン
  3. Docker レジストリ

Dockerのアーキテクチャ

画像引用元:Docker-docs-ja

Docker クライアント

Docker クライアントは、ユーザーが Docker の操作を行うためのインターフェースです。ユーザーが入力したコマンドを Docker デーモンに送信し、実際の処理を依頼します。

Docker デーモン

Docker デーモンは、Docker クライアントからのコマンドを受け取り、Docker のオブジェクト(例えばイメージやコンテナ)の作成や管理を行います。このデーモンは Docker ホスト上で動作し、イメージやコンテナなどの Docker オブジェクトをホスト内で管理します。

Docker レジストリ

Docker レジストリは Docker イメージの保存・共有を行う場所です。一般的な公開レジストリには Docker Hub がありますが、よりセキュリティが必要な場合はプライベートレジストリ(例:GitLab)を利用します。docker pulldocker pushのデフォルトの接続先は DockerHub です。

これらのコンポーネントがdocker runコマンドを実行した際に、どの様に動作しているのか解説します。

  1. コマンドの入力(Docker クライアント)
    ユーザーはコマンドラインやターミナルを通してdocker runコマンドを入力します。

  2. コマンドの転送(Docker クライアント → Docker デーモン)
    入力したdocker runコマンドは Docker クライアントによって処理され、Docker デーモンに転送されます。

  3. イメージの取得(Docker デーモン)
    Docker デーモンはdocker runコマンドによって指定されたイメージをまずは Docker ホスト上にあるか確認します。存在しない場合、Docker レジストリにアクセスしてイメージを取得します。

  4. コンテナの作成と起動(Docker デーモン)
    Docker デーモンはイメージから新しいコンテナを起動し、デフォルトコマンドを実行します。

  5. ユーザーへのフィードバック(Docker デーモン → Docker クライアント)
    コマンドの実行結果(ログやエラー)を Docker クライアントに返却し、ユーザーに表示します。

まとめ

  • DockerクライアントはユーザーとDockerデーモンの仲介役
  • DockerデーモンはDockerクライアントの命令に従いDockerオブジェクトの作成や管理を行う
  • DockerレジストリはDockerイメージの保存・共有を行う場所

おわりに

基礎的な内容をなぞるだけの記事になってしまいました。また知識が深まったらもっと深い部分まで記事で伝えれるようにリベンジしたいと思います。

参考文献

Docker-docs-ja
Dockerって何? って聞かれたときの解説、の解説
Dockerイメージの理解を目指すチュートリアル

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?