Dockerをゼロから理解する 構成・手順・レイヤー完全ガイド

Docker

「自分のパソコンでは動いたのに、本番環境では動かない」——そんな悩みを解消するために生まれたのがDockerです。この記事では、Dockerの基本概念から構成要素・作成手順・レイヤーの仕組みまでをゼロから丁寧に解説します。これからDockerを学び始めるエンジニアや、なんとなく使っていて仕組みをきちんと理解したい方に最適な内容です。


Dockerとは?まずは全体像を掴もう

Dockerとは、アプリケーションを「コンテナ」という軽量な実行環境にまとめて動かすためのプラットフォームです。名前の由来はコンテナを船で運ぶ港湾労働者(Docker)から来ており、アプリを「コンテナ」に詰めてどこでも同じ状態で運べるというコンセプトを表しています。

従来の仮想マシン(VM)と比べると、DockerコンテナはホストOSのカーネルを共有するため起動が速く、消費リソースが少ないのが最大の特徴です。

比較項目仮想マシン(VM)Docker
OSゲストOSが必要ホストOSのカーネルを共有
起動時間分単位秒単位
リソース消費大きい小さい
分離レベル強い(カーネルレベル)プロセスレベル



Dockerの構成要素

Dockerを理解するうえで欠かせない3つのコアコンセプトがあります。「イメージ・コンテナ・レジストリ」です。

  • Registry:Docker Hubなどのイメージ保存庫。docker pull でイメージを取得する
  • Image:読み取り専用のテンプレート。Dockerfileからビルドして作成する
  • Container:イメージを実行した状態。1つのイメージから複数起動できる

例え:イメージ=クッキーの型、コンテナ=焼き上がったクッキー、レジストリ=型のカタログ(Docker Hub)。ひとつの型から何個でも同じクッキーが焼けます。



クライアント・サーバーモデル

Dockerのアーキテクチャはクライアント・サーバーモデルを採用しています。端末で叩く docker コマンドがクライアント、実際の処理を担う dockerd(Dockerデーモン)がサーバーです。

図解のポイントをまとめると——

① あなたが打つコマンド(docker CLI)=クライアント
docker run nginx などのコマンドは、あくまで「指示書」を送るだけです。実際にコンテナを起動する処理はしません。

② dockerd(Dockerデーモン)=サーバー
バックグラウンドで常時動いているプロセスです。CLI からの指示を REST API 経由で受け取り、コンテナの起動・停止・イメージ管理・ネットワーク設定など、すべての実処理を担います

③ CLI と Daemon は同じPC上にある(普段は)
ローカル開発では同じマシン上で動いていますが、実はネットワーク越しに別マシンの Daemon に接続することも可能です(DOCKER_HOST 環境変数で切り替えられます)。これがクライアント・サーバー分離の恩恵です。

④ Docker Hub とのやり取りは必ず Daemon 経由
docker pull と打っても、CLI が直接 Docker Hub にアクセスするのではなく、Daemon が代わりに通信してイメージを取得します。



Dockerの作成手順(ステップバイステップ)

  1. Dockerのインストール:公式サイトからDocker Desktop(Mac/Windows)またはDocker Engine(Linux)をインストールします。インストール後、docker --version でバージョンが表示されれば成功です。
  2. Dockerfileの作成:コンテナの設計図となるテキストファイルです。「どのOSをベースにするか」「何をインストールするか」「何を起動するか」を記述します。
  3. Imageのビルド(docker build):Dockerfileを元にイメージを作成します。docker build -t myapp:1.0 . のようにタグを付けてビルドします。
  4. コンテナの起動(docker run):ビルドしたイメージからコンテナを起動します。-p でポートのマッピング、-d でバックグラウンド実行が指定できます。

以下はNode.jsアプリを例にしたDockerfileのサンプルです。

# ベースイメージの指定(Node.js 20 LTS)
FROM node:20-alpine

# 作業ディレクトリを設定
WORKDIR /app

# 依存関係ファイルをコピーしてインストール
COPY package*.json ./
RUN npm install --production

# アプリのソースをコピー
COPY . .

# コンテナが使用するポートを宣言
EXPOSE 3000

# コンテナ起動時に実行するコマンド
CMD ["node", "index.js"]

ビルドと起動のコマンドは以下の通りです。

# イメージをビルド(-t でタグ名指定、. はカレントディレクトリ)
$ docker build -t myapp:1.0 .

# コンテナを起動(-d バックグラウンド、-p ポートマッピング)
$ docker run -d -p 3000:3000 myapp:1.0

# 動いているコンテナを確認
$ docker ps

docker run は内部的に docker create(コンテナ作成)と docker start(コンテナ起動)を組み合わせた便利コマンドです。



Dockerのレイヤーとは

Dockerイメージは、積み重ねられた「レイヤー(層)」で構成されています。Dockerfileの各コマンド命令(FROM・RUN・COPY など)が、それぞれ1つのレイヤーを生成します。

ケーキで例えると、レイヤーはスポンジ生地の層です。一番下がベース(小麦粉+卵)、その上にクリーム、さらにフルーツ……と積み重なります。変更があった層より上だけを焼き直す(再ビルドする)イメージです。

レイヤー命令内容
最上位CMD / ENTRYPOINTコンテナ起動時の命令(読み書き可能なコンテナレイヤー)
COPY / ADDアプリのソースコードや設定ファイル
RUN(依存関係)npm install / apt-get install など
RUN(環境設定)WORKDIRの設定や環境変数など
最下位FROM(ベース)ubuntu, alpine, node など

レイヤーの最大のメリットは「キャッシュ」です。変更のないレイヤーは再利用されるため、2回目以降のビルドは劇的に速くなります。ベストプラクティスとして、変更頻度の低い命令(パッケージインストール)を先に書き、変更頻度の高い命令(ソースコードのコピー)を後に書くようにしましょう。

⚠️ レイヤー最適化のコツ:RUN 命令は可能な限り1つにまとめましょう。
例:RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*



ホストから見たDockerはプロセスである

Dockerコンテナは「独立した仮想サーバー」のように見えますが、ホストOS側から見ると実は「ただのプロセス」です。仮想マシン(VM)は専用のOSカーネルを持ちますが、Dockerコンテナはホストのカーネルをそのまま共有します。

「namespace」(名前空間)と「cgroup」(コントロールグループ)というLinuxの機能によって、プロセスが隔離されているように見えているだけです。

$ ps aux | grep docker

USER    PID   %CPU  %MEM  COMMAND
root    1234   0.1   0.5   node index.js   ← Container A の正体
root    5678   0.3   1.2   nginx: master   ← Container B の正体
root    9012   0.0   0.8   python app.py   ← Container C の正体
Linuxの仕組み役割
namespace(名前空間)PID・ネットワーク・ファイルシステム・ユーザーなどを隔離。コンテナ内から外が見えないようにする「壁」
cgroup(コントロールグループ)CPU・メモリ・I/Oなどのリソース使用量を制限する「枠」

この仕組みのおかげで、コンテナはVMと違ってホストのカーネルを共有でき、起動が秒単位(VMは分単位)で済むのです。



知っておくべきその他の重要知識

① Volumeとバインドマウント

コンテナは停止・削除するとデータが消えます。データを永続化するにはVolumeを使います。

# ボリュームを作成してコンテナにマウント
$ docker volume create mydata
$ docker run -v mydata:/data myapp:1.0

上記コマンドにより mydata(論理名) はホストOS上に作成されますが、場所は /home/yourname/mydata のような任意のパスではなく、Dockerが管理する専用ディレクトリ/var/lib/docker/volumes/mydata/_data)に自動で作られます。/data はコンテナ内に作成されます。そしてこの2つが橋でつながれた状態になります。


② Docker Compose(複数コンテナの管理)

Webサーバー・データベース・キャッシュなど、実際のアプリは複数のコンテナで構成されます。docker-compose.yml に定義を書けば、docker compose up 一発で全部起動できます。

services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

volumes:
  pgdata:


③ .dockerignoreでビルドを高速化

.gitignore と同様に、ビルドコンテキストから除外するファイルを指定します。

node_modules
.git
.env
*.log
dist
coverage


④ マルチステージビルド

ビルド環境と実行環境を分けることで、本番イメージを最小限のサイズに抑えられます。GoやJavaなど、コンパイルが必要な言語で特に効果的です。



参考リソース

カテゴリリソース名URL
公式ドキュメントDocker 公式ドキュメントhttps://docs.docker.com
入門チュートリアルDocker Getting Startedhttps://docs.docker.com/get-started
イメージ検索Docker Hubhttps://hub.docker.com
セキュリティDocker Security Best Practiceshttps://docs.docker.com/engine/security/
ComposeCompose ファイルリファレンスhttps://docs.docker.com/compose/compose-file/

コメント

タイトルとURLをコピーしました