Docker入門

コンテナの仕組みから実用的な使い方まで、図解とMermaidダイアグラムを交えて分かりやすく学びます。

学習をスタートする

ロードマップ

1

Dockerの基本概念とアーキテクチャ

Dockerは、アプリケーションを開発・デプロイ・実行するためのオープンソースのプラットフォームです。 「コンテナ」と呼ばれる独立した環境を利用することで、開発環境と本番環境の差異をなくし、どこでも同じように動作させることができます。 第1章では、Dockerがどのような仕組みで動いているのか、その「アーキテクチャ(構造)」を図解で分かりやすく解説します。 1. Dockerの全体像(3大要素) Dockerのアーキテクチャは、主に以下の3つの役割に分かれています。 1. Client(クライアント) * 私たちがターミナルで入力する docker コマンド(CLI)です。ユーザーからの指示をDocker Daemonに送信します。 2. Host(ホスト / Docker Daemon) * 実際にコンテナやイメージを管理し、実行するサーバーです。裏で動いている本体(Daemon)や、ダウンロードされたイメージ、実行中のコンテナがここに存在します。 3. Registry(レジストリ) * Dockerイメージを保管・配布する場所です。デフォルトでは公式の「Docker Hub」が使われます。 2. アーキテクチャの相互関係(図解) これら3つの要素がどのように連携して動くのか、Mermaidダイアグラムで表すと以下のようになります。 コマンドが実行されたときの流れ * docker pull を実行したとき: 1. Client から Host (Docker Daemon) へ「イメージが欲しい」というリクエストが飛びます。 2. Daemon はローカルにイメージがない場合、Registry (Docker Hub) へアクセスしてイメージをダウンロード(プル)し、Host 内に保存します。 * docker run を実行したとき: 1. Client から Daemon へ「コンテナを起動して」と指示します。 2. Daemon は指定されたイメージを元に、Host 上で隔離された実行環境(コンテナ)を作成し、起動します。 3. なぜDockerを使うと「どこでも動く」のか? 従来の仮想マシン(VM)は、ハードウェアを仮想化し、その上で丸ごと「ゲストOS」を動かしていました。そのため、起動が遅く、動作も重いという課題がありました。 一方、Dockerは ホストOSのカーネル(OSの心臓部)を共有 し、プロセスを隔離する技術(NamespacesやCgroupsなど)を使用します。これにより、OSを丸ごと起動する必要がなくなり、非常に軽量かつ高速に動作させることができます。 次のチャプターでは、よく混同される「イメージ」と「コンテナ」の違いについて、さらに深掘りして学びましょう!

2

イメージとコンテナの違い

Dockerを使い始めるときに、最初に混乱しやすいのが「イメージ (Image)」と「コンテナ (Container)」の違いです。 この2つは密接に関係していますが、役割がまったく異なります。第2章では、イメージとコンテナの違いをオブジェクト指向プログラミングの概念やレイヤー構造の図解を用いて分かりやすく解説します。 1. 例え話で理解する 一番分かりやすい例えは、オブジェクト指向プログラミングにおける 「クラス」と「インスタンス」、あるいは 「設計図」と「ビル(実物)」 の関係です。 概念 Dockerイメージ Dockerコンテナ 例え 設計図 / レシピ / クラス 完成したビル / 料理 / インスタンス 状態 静的(ファイルの実体) 動的(実行プロセス) 変更 読み取り専用(Read-Only) 書き込み可能(Read-Write) 関係性 1つのイメージから... 複数のコンテナを何個でも起動できる 設計図(イメージ)があれば、それをもとに全く同じビル(コンテナ)を何個でも建てることができます。あるビルに傷がついたり壊れたりしても、設計図自体が壊れることはありません。 2. レイヤー構造(UFS)による図解 Dockerの大きな特徴は、ファイルシステムが「レイヤー(層)」のように積み重なっている点です。これを「Union File System (UFS)」と呼びます。 イメージとコンテナがどのようにレイヤーを共有しているかを視覚化した図が以下です。 レイヤー共有のメリット 1. ディスク容量の節約 * 同じベースOSイメージ(例: ubuntu:latest)を元にした10個のコンテナを起動しても、ベースOS部分(L1)はディスク上に1つしか存在せず、すべてのコンテナで共有されます。 2. 高速な起動 * 新しくコンテナを起動するとき、Dockerは下位レイヤー(L1〜L3)をそのまま読み取り、一番上に非常に薄い「書き込み可能レイヤー(RW)」を1枚追加するだけです。そのため、ミリ秒単位で一瞬でコンテナが起動します。 3. コンテナが消えるとデータはどうなる? コンテナ内でファイルを作成したり変更したりすると、データは一番上の「書き込み可能レイヤー(RW)」に保存されます。 しかし、コンテナを破棄(削除)すると、この書き込み可能レイヤーも一緒に消滅します。 つまり、データベースのデータやユーザーのアップロード画像など、永続化したいデータはすべて消えてしまいます。 データを消さないために、Dockerでは「ボリューム(Volume)」と呼ばれるホストOS側のディレクトリをコンテナ内にマウント(接続)する仕組みが用意されています。 まとめ * Dockerイメージ:アプリケーションの実行に必要なベースOS、ライブラリ、コードがまとめられた、読み取り専用の「設計図」 * Dockerコンテナ:イメージの上に「書き込み可能レイヤー」を乗せて起動した、独立した「実行環境」 これでイメージとコンテナの違いはバッチリです!

3

Dockerfileの書き方とマルチステージビルド

コンテナイメージを自分で作成(ビルド)するには、Dockerfile(ドッカーファイル) と呼ばれる設定ファイルを使用します。 第3章では、Dockerfileの基本的な書き方から、イメージの容量を劇的に削減するテクニックである「マルチステージビルド」までを図解で分かりやすく学びます。 1. Dockerfileの基本命令 Dockerfileは、コンテナの「設計図」です。テキストファイルに上から順にコマンドを記述していくことで、独自のイメージを自動構築できます。 代表的な命令には以下のようなものがあります。 命令 役割 例 FROM ベースとなるイメージを指定(必須) FROM node:20-alpine WORKDIR コンテナ内の作業ディレクトリを設定 WORKDIR /app COPY ホスト(PC)のファイルをコンテナ内にコピー COPY package.json . RUN イメージ構築時(ビルド時)にコマンドを実行 RUN npm install CMD コンテナ起動時にデフォルトで実行するコマンド CMD ["npm", "start"] EXPOSE コンテナが開放するポート番号(ドキュメント用) EXPOSE 3000 2. イメージレイヤーとビルドキャッシュの仕組み Dockerfileの各命令(特に RUN、COPY、ADD)は、実行されるたびに 「イメージレイヤー」 と呼ばれる読み取り専用の層を作成します。 Dockerはビルドを高速化するため、「変更がないレイヤーは前回のキャッシュを再利用する」 という仕組みを持っています。 キャッシュを活かすDockerfileの書き方 例えば、ソースコードを変更するたびに npm install が走り直すとビルドが遅くなります。そのため、依存関係の定義ファイルだけを先にコピーしてインストールします。 3. マルチステージビルド(Multi-stage Build)とは? アプリケーションをビルドする際、コンパイルや依存ファイルのインストールには多くのツール(コンパイラ、npmパッケージなど)が必要ですが、本番環境で実行する段階では不要なファイル がたくさんあります。 マルチステージビルド は、一つのDockerfile内に複数の FROM を記述し、「ビルド用の一時コンテナ」から「本番用の軽量コンテナ」へ最小限の成果物だけをコピーする 技術です。 これにより、イメージサイズを小さく保ち、セキュリティリスク(余分なライブラリに含まれる脆弱性)を減らすことができます。 マルチステージビルドの仕組み(図解) 具体的なDockerfileの例(Next.jsなどの静的ビルド配信) この方法を使うと、本番イメージには Node.js や node_modules などが含まれず、Nginxと生成された静的ファイル(数MB〜数十MB程度)だけになるため、非常に軽量になります。 まとめ * Dockerfile はコンテナの構築手順を記述した設計図。 * 変更頻度の低い命令(パッケージインストールなど)を上に書くことで、ビルドキャッシュ を効率よく使える。 * マルチステージビルド を使うと、開発ツールを排除した「本番に必要な最小限のファイル」だけでイメージを作れるため、軽量かつ安全になる。 次は、複数のコンテナを組み合わせて動かす「Docker Compose」について学びましょう!

4

Docker Composeによる複数コンテナの管理

実際のWebシステム開発では、Webサーバー、アプリケーション(API)、データベースなど、複数のコンテナを協調させて動かすことがほとんどです。 これらを docker run コマンドで1つずつ立ち上げて接続するのは非常に大変です。そこで登場するのが、複数のコンテナをまとめて定義・管理できるツール Docker Compose(ドッカーコンポーズ) です。 第4章では、Docker Composeの使い方と、重要な概念である「ネットワーク」と「ボリューム」について解説します。 1. Docker Composeとは? Docker Composeは、docker-compose.yml というYAMLファイルにコンテナの構成を記述し、1つのコマンドでまとめて起動・停止できるツールです。 * 一発起動: docker compose up -d で、設定されたすべてのコンテナが立ち上がります。 * 一発停止: docker compose down で、コンテナやネットワークを綺麗に一括削除できます。 2. 構成図(Webアプリ + DBの連携) Docker Composeは、デフォルトでサービスごとに共通の仮想ネットワークを自動作成します。これにより、コンテナ同士の名前解決(サービス名でのアクセス)が可能になります。 3. docker-compose.yml の基本例 以下は、Node.jsのWebアプリとPostgreSQLデータベースを連携させる標準的な設定ファイルです。 4. データの永続化(Volumes)の重要性 コンテナは基本的に 「使い捨て(エフェメラル)」 な設計になっています。コンテナを削除すると、その内部で作成されたファイルやデータベースのデータはすべて消えてしまいます。 データを永続化するためには、ホストPCのストレージ領域をコンテナにマウント(紐付け)する Volumes(ボリューム) という仕組みを利用します。 マウントの種類 1. Named Volumes (名前付きボリューム)(推奨) * Dockerが管理する領域内に専用のストレージエリアを作成し、コンテナにマウントします。データベースのデータ保存などに最適です。 * 例: - db-data:/var/lib/postgresql/data 2. Bind Mounts (バインドマウント) * ホストPC上の特定のフォルダ(例:自分のプロジェクトフォルダ)を直接コンテナ内にマウントします。開発中にソースコードを書き換えて、コンテナ内に即座に反映(ホットリロード)させたい場合に使われます。 * 例: - .:/app 5. よく使うコマンド集 Docker Composeを使うときは、プロジェクトのルート(docker-compose.yml がある場所)でコマンドを実行します。 コマンド 役割 docker compose up -d 設定ファイルに基づいてコンテナをビルド・作成し、バックグラウンドで起動する docker compose down コンテナ、ネットワークを停止し、削除する(データボリュームは残る) docker compose ps 現在動いているサービスのコンテナ一覧を表示する docker compose logs -f コンテナの出力ログをリアルタイムで監視(フォロー)する docker compose exec [service] [cmd] 起動中のコンテナ内でコマンドを実行する(例: docker compose exec db psql) まとめ * Docker Compose は、docker-compose.yml を使って複数コンテナの構成を一元管理するツール。 * 自動生成される 共通ネットワーク により、コンテナ間でサービス名を使った通信ができる。 * コンテナ削除でデータが消えないようにするため、Volumes を使用してデータを永続化する。 これで、Dockerの基本概念から複数コンテナの管理までの入門ロードマップは完了です!コンテナ技術を活用して、より快適な開発環境を構築していきましょう。

5

マルチステージビルドとコンテナセキュリティ

本番環境でDockerを利用するにあたり、作成したコンテナイメージの「サイズ」と「セキュリティ」は極めて重要な要素です。不要なファイルや開発用SDKがイメージに含まれていると、イメージの読み込み(プル)が遅くなるだけでなく、セキュリティホール(脆弱性)の温床になってしまいます。 第5章では、イメージの極小化と安全なコンテナ設計について学びます。 1. マルチステージビルド (Multi-stage Builds) 通常、プログラムのビルドにはコンパイラやパッケージマネージャーが必要ですが、実行時にはビルド済みの成果物(コンパイルされたバイナリや最小限の dist ファイル)だけがあれば十分です。 マルチステージビルドは、1つの Dockerfile 内で複数の FROM 命令を使用して、ビルド環境と実行環境を切り離す技術です。 Dockerfileの実装例 以下は、ReactなどのSPAをビルドし、Nginxで配信するマルチステージビルドの例です。 このアプローチにより、本番用のコンテナイメージには node 本体や node_modules は一切含まれず、高速かつ超軽量な nginx イメージのみが出力されます。 2. ベースイメージの選定 (Alpine / Distroless) コンテナイメージを軽量化・安全にするためのもう一つの鍵は、ベースイメージの選定です。 1. Alpine Linux (-alpine): * 標準的なLinuxイメージ(Debian等)が数百MBあるのに対し、Alpineはわずか5MB程度です。軽量パッケージマネージャー(apk)を搭載しており、最も一般的です。 2. Distroless (Google): * パッケージマネージャーやシェル(/bin/sh など)すら含まない、プログラム実行に必要最小限の依存ライブラリだけを含む超セキュアなイメージです。シェルがないため、コンテナ内に侵入された場合でも攻撃の手段をほとんど与えません。 3. 非ルート(Non-root)ユーザーでのコンテナ実行 デフォルトでは、コンテナ内のプロセスは root ユーザー権限で動作します。万が一、コンテナ内のアプリケーションに脆弱性があり乗っ取られた場合、ホストOS(物理サーバー)まで被害が及ぶ「コンテナエスケープ」のリスクが高まります。 安全のため、Dockerfile内で一般ユーザーを作成し、その権限で実行するように指定します。 非ルートユーザーで動作させることで、仮に侵入されたとしてもシステム全体の権限奪取を防ぐ強力なセキュリティ境界が形成されます。