この用語をシェア
概要
Dockerは、コンテナ技術を使用したアプリケーション実行環境の仮想化ツールです。アプリケーションとその依存関係(ライブラリ、ランタイム、設定ファイルなど)を軽量で可搬性の高い「コンテナ」というパッケージにまとめ、開発者のノートPCでもテスト環境でも本番サーバーでも、同じように動かせるようにします。もともとは2013年にdotCloud社(後のDocker社)がオープンソースプロジェクトとして公開したもので、「Build, Ship, Run」というコンセプトのもと、コンテナ技術そのものを一般の開発者に広く普及させた立役者として知られています。
Dockerが解決しようとした課題は、いわゆる「自分の環境では動くのに、本番では動かない」という問題です。OSのバージョン、ミドルウェアのバージョン、環境変数の違いなどによってアプリケーションの挙動が変わってしまう状況に対し、Dockerはアプリケーションと実行環境をまるごとイメージ化することで、環境差異を吸収します。この特性から、現在ではローカル開発環境の統一、CI/CDパイプラインでのビルド・テスト実行、マイクロサービスアーキテクチャにおけるサービス単位でのデプロイなど、開発から運用まで幅広い場面でデファクトスタンダードのツールとして使われています。
仕組み・詳細解説
Dockerが「仮想マシンより軽量」と言われる理由は、OS全体を仮想化するのではなく、Linuxカーネルが持つ機能を利用してプロセス単位で実行環境を隔離しているためです。ここでは、その内部構造を4つの観点から解説します。
1. クライアント/デーモン/コンテナランタイムの3層構造
Dockerは単一のプログラムではなく、複数のコンポーネントが連携して動作します。開発者が入力するdockerコマンド(Docker CLI)はクライアントに過ぎず、実際の処理は常駐プロセスであるdockerd(Docker Engineのデーモン)に委譲されます。さらにdockerdは、コンテナの起動・停止・ライフサイクル管理をcontainerdに、実際にLinuxカーネルへnamespaceやcgroupsの設定を行いプロセスを起動する部分をruncという低レベルランタイムに委ねています。containerdとruncはDocker社が中心となってCNCF(Cloud Native Computing Foundation)に寄贈したプロジェクトであり、Kubernetesの多くのディストリビューションでも共通のコンテナランタイムとして採用されています。
2. イメージのレイヤー構造とUnionファイルシステム
Dockerイメージは1つの巨大なファイルではなく、Dockerfileの命令1行(正確にはRUN・COPY・ADDなど一部の命令)ごとに生成される「レイヤー」の積み重ねで構成されています。これらのレイヤーはOverlayFSなどのUnion系ファイルシステムによって1つのファイルツリーに見えるように重ね合わせられ、コンテナ起動時にはその上に書き込み可能な薄いレイヤーが追加されます(コンテナを削除すればこの書き込みレイヤーだけが消えます)。この仕組みにより、ベースイメージ(例:node:18-alpine)が共通していれば、複数のイメージやコンテナ間でレイヤーをディスク上で共有でき、ビルドの高速化とストレージ使用量の削減を両立できます。Dockerfileの記述順序を工夫し、変更頻度が低い命令(依存関係のインストールなど)を先に、変更頻度が高い命令(アプリケーションコードのコピーなど)を後に書くのは、このレイヤーキャッシュを最大限に活用するための定石です。
3. 名前空間(Namespaces)とcgroupsによる隔離
コンテナが「独立したマシンのように見える」のは、Linuxカーネルのnamespace機能によって、プロセスID(PID namespace)、ネットワーク(Network namespace)、マウントポイント(Mount namespace)、ホスト名(UTS namespace)などがホストや他のコンテナから隔離されているためです。一方で、CPUやメモリなどのリソース使用量の上限を設定するのはcgroups(control groups)という別のカーネル機能で、docker run --memory 512m --cpus 1のようなオプションでコンテナごとの上限を指定できます。仮想マシンがハイパーバイザー上にゲストOSごとカーネルを持つのに対し、コンテナはホストのカーネルを共有するため、起動が数秒以内と高速で、メモリ消費量も小さく抑えられます。
4. ネットワークとボリューム
Dockerはデフォルトでbridgeという仮想ネットワークを作成し、同一ホスト上のコンテナ同士を内部IPで通信させつつ、外部にはポートマッピング(-pオプション)で必要な範囲だけ公開します。コンテナは削除されると内部のファイルも消えてしまうため、データベースのデータなど永続化したい情報はボリューム(Volume)としてコンテナの外(ホスト側やDockerが管理する領域)に保存します。「コンテナはステートレスに使い、状態はボリュームに逃がす」という設計原則は、Dockerを実運用に乗せる上での基本方針です。
基本概念
- コンテナ: アプリケーションと依存関係を含む軽量な実行環境。namespaceとcgroupsによってホストOSやほかのコンテナから隔離されて動作するプロセス群
- イメージ: コンテナの雛形となる読み取り専用のテンプレート。レイヤーの積み重ねで構成され、Docker Hubなどのレジストリで配布される
- Dockerfile: イメージを構築するための設定ファイル。ベースイメージの指定から、依存関係のインストール、実行コマンドまでを手順として記述する
- レジストリ: イメージを保存・共有する場所(Docker Hub、GitHub Container Registry、Amazon ECRなど)
- Docker Engine: dockerd(デーモン)、REST API、CLIから構成される、Dockerのコア実行環境そのもの
- Docker Desktop: macOS/Windows向けにDocker Engine一式をGUI付きでまとめたアプリケーション。個人利用や小規模事業者は無償だが、大企業(従業員250名以上または年間収益1000万米ドル超が目安とされる)では有償サブスクリプションが必要
基本的なDockerコマンド
# イメージの操作
docker images # イメージ一覧
docker pull nginx # イメージをダウンロード
docker build -t myapp . # Dockerfileからイメージを構築
# コンテナの操作
docker run -p 8080:80 nginx # コンテナを実行
docker ps # 実行中のコンテナ一覧
docker stop コンテナID # コンテナを停止
docker rm コンテナID # コンテナを削除
# 便利なコマンド
docker exec -it コンテナID bash # コンテナ内でbashを実行
docker logs コンテナID # コンテナのログを表示
docker logs -f コンテナID # ログをリアルタイムで追跡
# 後片付け・調査系コマンド
docker system prune -a # 未使用のイメージ・コンテナ・キャッシュを一括削除
docker volume ls # ボリューム一覧
docker network ls # ネットワーク一覧
docker inspect コンテナID # コンテナの詳細設定をJSONで表示
なお、以前はdocker-compose(ハイフン区切り、Python製の独立コマンド)がComposeの実行方法でしたが、現在はdocker compose(スペース区切り、Go製のCLIプラグイン)が標準です。旧コマンドはCompose V1として既にメンテナンスが終了しており、新規に環境を構築する場合はdocker compose表記を使うのが実務上の定石です。
Dockerfileの例
まずは基本形として、Node.jsアプリケーションをそのままコンテナ化する例です。
# Node.js アプリケーション(シングルステージ)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
実務では、ビルド時にしか使わないツール(コンパイラやdevDependencies)を本番イメージに残さないよう、マルチステージビルドを使うのが定石です。ビルド用ステージと実行用ステージを分けることで、最終的なイメージサイズを大幅に小さくでき、攻撃対象領域(アタックサーフェス)の縮小にもつながります。
# マルチステージビルドの例
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER node
CMD ["node", "dist/index.js"]
あわせて、.dockerignoreファイルでnode_modulesや.git、ログファイルなどをビルドコンテキストから除外しておくと、イメージのビルド時間短縮と不要なファイルの混入防止に役立ちます。また上記の例のように、コンテナ内のプロセスをroot以外のUSERで実行することは、セキュリティのベストプラクティスとして広く推奨されています。
Docker Composeの例
Webアプリとデータベースのように複数のコンテナを組み合わせて動かす場合、docker runを何度も手打ちするのは現実的ではありません。Docker Composeを使えば、YAMLファイル1枚に構成をまとめて宣言的に管理でき、docker compose up一発で全サービスを起動できます。ローカル開発環境の再現性を高める手段として、実務で最もよく使われるDocker関連機能の一つです。
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
- NODE_ENV=production
db:
image: postgres:13
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
メリット
- 環境の一貫性: 開発、テスト、本番環境で同じ実行環境を再現でき、「自分の環境では動く」問題を減らせる
- 軽量性: ホストOSのカーネルを共有するため、仮想マシンより起動が速くリソース消費も小さい
- 可搬性: OCI準拠のイメージであれば、クラウドやオンプレミスを問わずどこでも同じように動作する
- スケーラビリティ: コンテナ単位で必要に応じて簡単にスケールアウトでき、Kubernetes等のオーケストレーションと相性が良い
- 効率的なリソース利用: 1台のホストに多数のコンテナを高密度に配置でき、サーバーリソースを無駄なく使える
- エコシステムの充実: Docker Hubを中心に公式イメージが豊富に公開されており、ミドルウェアの検証環境を短時間で用意できる
デメリット・注意点
- Linuxカーネル依存によるオーバーヘッド: macOSやWindowsではLinuxカーネルを直接共有できないため、Docker Desktopは内部的に軽量な仮想マシン(Hyper-V、WSL2、Apple仮想化フレームワークなど)を経由します。Linuxネイティブ環境と比べるとファイルI/O性能などで差が出ることがあります
- イメージの脆弱性管理が必要: 便利な公式イメージでも、内部のOSパッケージやライブラリに既知の脆弱性(CVE)を含んでいることがあるため、定期的なイメージの更新とスキャンが欠かせません
- ステートフルなデータの扱いが煩雑: コンテナ自体は使い捨てが前提のため、データベースなど状態を持つアプリケーションはボリューム設計やバックアップ運用を別途しっかり考える必要があります
- 複数ホストにまたがる運用は守備範囲外: Docker単体(およびDocker Compose)は基本的に1台のホスト内での利用が前提であり、複数サーバーにまたがる自動スケーリングや障害時の再配置には、Kubernetesなど別のオーケストレーションツールが必要になります
- Docker Desktopのライセンス条件: 大企業(従業員数や年間収益が一定規模を超える組織が目安とされる)がDocker Desktopを利用する場合、有償のサブスクリプション契約が必要です。Docker Engine自体(Linuxサーバー上で直接動かす場合)は引き続きオープンソースとして提供されています
混同されやすい用語・類似技術との違い
Dockerを学ぶ際に混同しやすい周辺用語・技術との違いを整理します。
仮想マシン(VM)との違い
| 観点 | Docker(コンテナ) | 仮想マシン(VM) |
|---|---|---|
| 隔離の単位 | プロセス(namespace・cgroupsで隔離) | ハードウェアごとゲストOSを起動 |
| カーネル | ホストOSのカーネルを共有 | ゲストOSごとに独自のカーネルを持つ |
| 起動時間 | 数秒程度 | 数十秒〜数分程度 |
| 隔離の強度 | カーネルを共有する分、VMよりは弱い | ハイパーバイザーによる強固な隔離 |
セキュリティ要件が非常に厳しいマルチテナント環境などでは、コンテナとVMを組み合わせた「軽量VM」型のランタイム(AWS Firecracker等)を採用するケースもあります。
Podman・containerdとの違い
PodmanはRed Hatが主導するDocker互換のコンテナエンジンで、常駐デーモンを持たない「デーモンレス」設計が特徴です。CLIコマンドの多くがdockerコマンドと共通の書式(podman runなど)で使えるため、Dockerからの移行がしやすい代替ツールとして紹介されることがあります。一方containerdは前述の通りDocker Engine内部でも使われているコンテナランタイムそのものであり、Kubernetesのノード上でも単体で利用されています。「Podman・containerdはDockerの完全な代わりになるのか」という問いに対しては、CLIレベルの互換性は高いものの、Docker Desktopが提供するGUIやDocker Hubとの統合など周辺エコシステムには差があるため、移行前の検証が推奨されます。
Kubernetesとの違い・役割分担
「DockerとKubernetesはどちらを使えばいいのか」という質問をよく受けますが、両者は競合するものではなく役割が異なります。Dockerはコンテナを「作る・動かす」ためのツールであり、Kubernetesは多数のコンテナを複数のサーバー(ノード)にまたがって「どこに配置し、いくつ複製し、障害時にどう再起動するか」を管理するオーケストレーションツールです。小規模な開発環境や単一サーバーでの運用ならDocker(およびDocker Compose)だけで十分なことも多く、可用性やスケーラビリティが求められる本番環境ではKubernetesと組み合わせるのが一般的です。なお、KubernetesはDocker Engineを直接のコンテナランタイムとして使う方式(dockershim)を2022年リリースのv1.24で廃止しており、現在はcontainerdなどCRI(Container Runtime Interface)準拠のランタイムを利用します。
Docker ComposeとDocker Swarm・Kubernetesとの違い
Docker Composeは基本的に1台のホスト上で複数コンテナの起動順序や設定をまとめるためのツールです。これに対し、Docker Swarm(Docker Engineに組み込まれたクラスタリング機能)やKubernetesは、複数ホストにまたがるクラスタを前提としたオーケストレーション基盤で、ノード障害時の自動復旧やローリングアップデートなどの機能を備えます。実務では「ローカル開発・小規模環境はCompose、本番の大規模運用はKubernetes」という住み分けが一般的です。
実務でのポイント(ワークフローへの組み込み方)
- CI/CDパイプラインへの組み込み: GitHub ActionsやJenkinsなどのCIツールでDockerイメージのビルド・テスト・レジストリへのプッシュを自動化し、そのままステージング・本番環境にデプロイする構成が一般的です。ビルドとテストを毎回同じコンテナ環境内で実行することで、CI環境と本番環境の差異による不具合を減らせます
- イメージのタグ戦略:
latestタグだけに頼ると、どのコードでビルドしたイメージかが追跡しづらくなります。Gitのコミットハッシュやセマンティックバージョン(例:myapp:1.4.2)でタグ付けし、ロールバックしやすい状態を保つのが定石です - レジストリの使い分け: 公開イメージの取得にはDocker Hubを使いつつ、社内・プロダクト固有のイメージはGitHub Container Registry(ghcr.io)、Amazon ECR、GitLab Container Registryなど、CI/CD基盤やクラウド環境に合わせたプライベートレジストリで管理するのが実務的です
- ローカル開発環境の統一: Docker Composeでアプリケーション本体・データベース・キャッシュ(Redis等)をまとめて定義しておけば、新しくチームに参加したメンバーも
docker compose upだけで同じ開発環境を再現でき、オンボーディングコストを下げられます - テストへの活用: 結合テストで実際のデータベースやメッセージキューをDockerコンテナとして一時的に起動する「Testcontainers」のような手法は、モックに頼らないテストの信頼性向上によく使われます
- イメージの軽量化・セキュリティ対策: Alpine LinuxベースやDistroless系のベースイメージを採用し、マルチステージビルドと組み合わせることで、イメージサイズと脆弱性の混入リスクを同時に下げられます
2025〜2026年の最新動向
- Compose V1の終了とV2への一本化: 従来のPython製スタンドアロンコマンド
docker-compose(Compose V1)は既にメンテナンス終了となっており、Go製でDocker CLIに統合されたdocker compose(Compose V2)が標準になっています。古いドキュメントやスクリプトを参照する際は表記の違いに注意が必要です - Docker Scoutによる脆弱性・SBOM管理の強化: イメージ内のパッケージ構成を可視化し、既知の脆弱性やソフトウェア部品表(SBOM)をチェックする「Docker Scout」がDocker Desktop・Docker Hubに統合され、開発フローの早い段階でセキュリティ課題を検知する取り組みが進んでいます
- Docker Build Cloudによるビルドの高速化: イメージのビルド処理をクラウド側の共有ビルダーにオフロードし、CI環境やローカル環境をまたいでビルドキャッシュを再利用できる「Docker Build Cloud」が提供されており、大規模なマルチステージビルドの高速化手段として利用が広がっています
- AI関連機能の取り込み: Docker Desktopには生成AIを使った操作支援(Ask Gordonなど)や、ローカル環境でLLMを手軽に実行・配布するための機能(Docker Model Runner)といった、AI活用を意識した機能追加が進められています。従来のコンテナ資産(イメージビルド、レジストリ配布の仕組み)をAIモデルの配布・実行にも応用しようという方向性が特徴です
- セキュリティ・サプライチェーン対策の強化: ソフトウェアサプライチェーン攻撃への関心の高まりを受け、イメージの署名・検証(Sigstore/cosignとの連携等)や、非rootユーザーでのコンテナ実行(rootlessモード)を前提としたベストプラクティスの浸透が進んでいます
- Docker Hubの利用制限の継続: 匿名ユーザーや無料プランに対するイメージのpull回数制限(レートリミット)は継続して運用されており、CI環境などで大量にpullする場合は認証済みアカウントの利用やミラーレジストリの活用が実務上の対策として定着しています
関連技術・関連用語
- Kubernetes: 複数ホストにまたがるコンテナの配置・スケーリング・自動復旧を担うオーケストレーションツール
- Docker Compose: 単一ホスト上で複数コンテナの構成をYAMLで宣言的に管理する仕組み
- Docker Swarm: Docker Engineに組み込まれたシンプルなクラスタリング・オーケストレーション機能
- Podman: Red Hatが開発する、デーモンレス設計のDocker互換コンテナエンジン
- containerd / runc: Docker Engine内部でも使われる、CNCFがホストするコンテナランタイム
- CI/CD: Dockerイメージのビルド・テスト・デプロイを自動化するパイプラインの考え方
- GitHub Actions: Dockerイメージのビルドやレジストリへのプッシュを自動化する際によく組み合わされるCIツール
- Git: Dockerfileやdocker-compose.ymlをアプリケーションコードと一緒にバージョン管理するための基盤
外部リンク・参考資料
- Docker 公式サイト - 製品情報、Docker Desktop・Docker Scout・Docker Build Cloudなどの最新情報
- Docker 公式ドキュメント - Dockerfileリファレンス、Compose仕様、CLIコマンド一覧などの一次情報
- Docker Hub - 公式・コミュニティ製のコンテナイメージを検索・取得できるレジストリ
- Open Container Initiative(OCI) - コンテナイメージやランタイムの業界標準仕様を策定する団体。Dockerイメージの可搬性の基礎となっている仕様
よくある質問(FAQ)
Q. Dockerとは何ですか
Dockerはコンテナ技術を使用したアプリケーション実行環境の仮想化ツールで、アプリケーションとその依存関係を軽量で可搬性の高いコンテナにパッケージ化します。namespaceとcgroupsというLinuxカーネルの機能を利用してプロセス単位で環境を隔離しており、仮想マシンよりも軽量・高速に動作するのが特徴です。
Q. Dockerと仮想マシン(VM)は何が違いますか
仮想マシンはハイパーバイザー上にゲストOSごとカーネルを持って動作するのに対し、Dockerのコンテナはホストのカーネルを共有し、プロセス単位で隔離します。そのため起動時間やリソース消費量の面でコンテナのほうが軽量ですが、隔離の強度そのものは仮想マシンのほうが高いとされます。
Q. DockerとKubernetesはどちらを使えばいいですか
両者は役割が異なります。Dockerはコンテナを作成・実行するためのツールで、Kubernetesは複数サーバーにまたがるコンテナの配置やスケーリング、障害復旧を担うオーケストレーションツールです。単一サーバーでの開発・小規模運用であればDocker(Docker Compose)だけで完結することが多く、可用性やスケーラビリティが求められる本番環境ではKubernetesと組み合わせるのが一般的です。
Q. Docker ComposeやPodmanとの違いは何ですか
Docker Composeは単一ホスト上で複数コンテナの構成をYAMLで管理する仕組みで、Dockerに含まれる機能の一つです。一方Podmanは、常駐デーモンを持たない設計のDocker互換コンテナエンジンで、Red Hatが開発を主導する別プロダクトです。CLIの書式は似ていますが、Docker Desktopが提供するGUIやエコシステムとは差があるため、移行の際は事前の動作検証が推奨されます。
Q. 本番環境でDockerを使う際に気をつけることは何ですか
ベースイメージを定期的に更新して既知の脆弱性(CVE)を放置しないこと、コンテナをroot以外のユーザーで実行すること、データベースなど状態を持つデータはボリュームで永続化し、コンテナ自体は使い捨て前提で設計することが基本です。複数サーバーにまたがる可用性や自動復旧が必要な場合は、Docker単体ではなくKubernetesなどのオーケストレーションツールと組み合わせます。
Q. 2025〜2026年のDockerの最新動向は
旧来のPython製docker-compose(Compose V1)は終了し、Docker CLIに統合されたdocker compose(Compose V2)への一本化が進んでいます。加えて、脆弱性・SBOM管理を行う「Docker Scout」、ビルドをクラウドにオフロードする「Docker Build Cloud」、ローカルLLM実行など生成AI活用を意識した機能追加など、セキュリティとAI統合の両面で進化が続いています。
