宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
「コンテナって仮想マシンと何が違うの?」「Dockerが話題になっているけど、自分のPCに入れても大丈夫なの?」
コンテナという言葉はよく耳にするのに、どうもしっくり来ない。仮想マシンとの違いを聞いてもピンとこない。そんな方が多いのではないでしょうか。

この記事では、コンテナと仮想マシンの根本的な違いから、Dockerが実現する軽量・高速な仕組み、DockerfileやDocker Composeを使った実践的な活用方法まで解説します。「コンテナ docker」を調べている完全初心者の方でも、読み終わった後には「なぜエンジニアがDockerを使うのか」が腑に落ちるように構成しています。

この記事のポイント

・コンテナはOSカーネルを共有する軽量な実行環境で、VMより数十倍速く起動する
・Dockerはコンテナを手軽に使うためのツール群(CLI・デーモン・イメージ管理)
・Dockerfileで環境を「コード化」すれば、誰でも同じ環境を再現できる
・Docker Composeを使えば複数コンテナをyaml1ファイルで一括管理できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

コンテナとは何か?仮想化の「新しい形」を理解する

コンテナを一言で言うと、「アプリケーションとその実行に必要なものをひとまとめにした、軽量な実行環境」です。

少し具体的に言いましょう。あなたがWebアプリを動かすためには、Pythonのバージョン、各種ライブラリ、設定ファイルなど、様々な依存関係が必要です。これが開発するPCと本番サーバーで少しでも違うと、「手元では動いたのに本番で動かない」という悪夢が起きます。

コンテナはこの問題を解決するために生まれました。アプリケーション本体と、それが動くために必要なライブラリや設定をひとつのパッケージ(イメージ)にまとめ、どの環境でも同じように動かせるようにするのがコンテナの本質です。

コンテナ技術の基盤はLinuxカーネルの機能、具体的には「namespaces(名前空間)」と「cgroups(コントロールグループ)」にあります。namespacesはプロセス・ネットワーク・ファイルシステムなどを独立した空間に隔離する仕組みで、cgroupsはCPUやメモリなどのリソース使用量を制限する仕組みです。これら2つのカーネル機能を組み合わせることで、ホストOSのカーネルを共有しながら、互いに干渉しない独立した実行環境を作り出しています。

Dockerはこのカーネル機能を人間が扱いやすくするためのツール群です。コンテナ技術そのものはDockerより以前から存在しましたが、Dockerが登場したことでコンテナの作成・配布・実行が劇的に簡単になりました。

仮想マシン(VM)とコンテナの根本的な違い

コンテナを理解するために、仮想マシン(VM)と比較してみましょう。

仮想マシン(VM)の仕組み
仮想マシンはVMwareやVirtualBox、KVMといったハイパーバイザーの上で動きます。物理マシン(ホスト)の上にハイパーバイザーが乗り、その上に複数のゲストOSが動きます。各VMはカーネルを含む完全なOSを持ちます。

つまり、「物理マシン→ハイパーバイザー→ゲストOS(カーネル込み)→アプリ」という4層構造です。

コンテナの仕組み
コンテナはホストOSのカーネルを共有します。「物理マシン→ホストOS(カーネル)→コンテナエンジン(Docker)→コンテナ(アプリ+ライブラリのみ)」という構造で、ゲストOSのカーネル層が丸ごと不要になります。

この違いが生み出すメリットは大きいです。

比較項目 仮想マシン(VM) コンテナ
起動時間 数分(OSブートが必要) 数秒以内
サイズ 数GB(OSイメージ含む) 数MB~数百MB
リソース消費 大きい(全OSのオーバーヘッド) 小さい(カーネル共有)
隔離レベル 強い(完全なOS分離) 中程度(カーネル共有)
ポータビリティ やや低い(OS依存がある) 高い(どこでも同じイメージ)
用途 異なるOS環境が必要な場面 アプリの軽量・高速なデプロイ

セキュリティ面では、VMのほうがカーネルレベルで完全に分離されているため隔離度は高いです。しかしコンテナのほうが起動が速く、リソース効率が高く、同じホストで多数のコンテナを動かせるため、マイクロサービスやCI/CDパイプラインでは圧倒的にコンテナが選ばれています。

VMとコンテナは競合するものではなく、むしろ組み合わせて使うのが現場の常識です。「VMでホスト環境を作り、その上でDockerコンテナを動かす」という構成は非常に一般的です。

Dockerが実現する軽量・高速コンテナの仕組み

DockerがコンテナをどうやってLinuxカーネル機能の上に実現しているか、その核心部分を解説します。

1. レイヤー構造(ユニオンファイルシステム)

Dockerのイメージは「レイヤー」の積み重ねで構成されています。たとえばPythonアプリのイメージなら、以下のようなレイヤー構造になります。

・ベースレイヤー:Ubuntu 24.04のファイルシステム
・レイヤー2:Pythonのインストール
・レイヤー3:アプリの依存ライブラリのインストール
・レイヤー4:アプリケーションコードのコピー

各レイヤーは差分のみを保持しており、同じベースイメージを使う複数のコンテナはそのレイヤーを共有します。これにより、ディスク容量の節約と、ダウンロード時の転送量削減が実現されます。

実際にDockerがどのようなレイヤー構成になっているか確認してみましょう。

# イメージのレイヤー構成を確認する(RHEL9 / Ubuntu24.04 で動作確認済み) docker history nginx:latest # 出力例(一部): # IMAGE CREATED CREATED BY SIZE # abc123def456 2 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemo… 0B # 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B # 2 weeks ago /bin/sh -c set -x && groupadd --system --gi… 112MB

2. コンテナのライフサイクル

Dockerコンテナは「イメージ(静的な設計図)」から「コンテナ(動的な実行インスタンス)」を作成するという概念が基本です。

イメージは読み取り専用で変更できません。コンテナを起動すると、イメージの上に薄い書き込み可能レイヤーが追加され、コンテナが生成したファイルはそこに書き込まれます。コンテナを削除すると、その書き込みレイヤーも消えます。データを永続化したい場合は「ボリューム」という仕組みを使います。

# nginxコンテナを起動してみる docker run -d --name my-nginx -p 8080:80 nginx:latest # 動作確認 docker ps # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # a1b2c3d4e5f6 nginx:latest "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp my-nginx # ブラウザまたはcurlでアクセス確認 curl http://localhost:8080 # ...(nginxのデフォルトページが返ってくる)

3. コンテナのネットワーク分離

各コンテナはデフォルトで独自のネットワーク名前空間を持ちます。コンテナ間の通信や外部へのアクセスは、Dockerが管理するブリッジネットワーク経由で行われます。

# Dockerのネットワーク一覧を確認する docker network ls # NETWORK ID NAME DRIVER SCOPE # b1c2d3e4f5g6 bridge bridge local # h7i8j9k0l1m2 host host local # n3o4p5q6r7s8 none null local

Dockerを使うメリット:なぜエンジニアに選ばれるのか

Dockerが現場のエンジニアに支持される理由を整理します。

1. 「自分のPCでは動く問題」を根絶できる

開発チームで最も頭を悩ませる問題が「自分のPCでは動くけど、本番では動かない」というものです。これはPythonのバージョン、インストール済みパッケージ、環境変数の違いなど、環境の差異が原因です。

Dockerのイメージに実行環境をまるごと含めることで、「同じイメージを使えば、どのマシンでも同じ動作をする」ことが保証されます。開発環境・ステージング環境・本番環境の差異が根本から解消されます。

2. 依存関係の衝突を避けられる

1台のサーバーでPython 3.8を使うアプリとPython 3.12を使うアプリを動かしたい場合、通常は競合が起きます。コンテナならそれぞれ別のコンテナとして独立させられるため、依存関係の衝突が発生しません。

3. デプロイが速くシンプルになる

VMベースのデプロイと比べると、コンテナベースのデプロイは大幅にシンプルです。新バージョンのリリースは「新しいイメージをビルドして、古いコンテナと差し替える」だけで完了します。ロールバックも「前のバージョンのイメージからコンテナを起動する」だけです。

4. CI/CDパイプラインとの相性が抜群

GitHub ActionsやGitLab CI、Jenkins等のCI/CDツールとDockerの組み合わせは現場の標準構成です。「コードをプッシュ→Dockerイメージをビルド→テストを実行→本番環境にデプロイ」というパイプラインを、コンテナを使えばきわめて再現性高く構築できます。

5. マイクロサービスの土台になる

大きなモノリシックなアプリを、機能ごとに独立した小さなサービス(マイクロサービス)に分割するアーキテクチャが普及しています。各マイクロサービスを独立したコンテナで動かすことで、スケールや更新を個別に行えるようになります。KubernetesなどのコンテナオーケストレーションツールはDockerイメージを前提として設計されています。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、コンテナの概念を理解したら、実際に手を動かすのが一番の近道です。Dockerのインストールから実践的な活用方法まで体系的に学ぶには、Docker実践講座(linuxmaster.jp)をご活用ください。現役エンジニアが教える、現場で使える技術を習得できます。

Docker Hubとイメージ:コンテナの「設計図」を理解する

Dockerを使う上で避けて通れないのがDocker Hubとイメージの概念です。

イメージとは何か
Dockerイメージは、コンテナを作成するための読み取り専用のテンプレートです。OSのファイルシステム、インストールするパッケージ、設定ファイル、実行するコマンドなどの情報がレイヤー構造で格納されています。イメージはコンテナの「設計図」です。

Docker Hubとは
Docker Hub(hub.docker.com)は、Dockerイメージを公開・共有するためのレジストリサービスです。GitHubがコードを共有するプラットフォームであるのと同様に、Docker HubはDockerイメージを共有するプラットフォームです。

nginx、MySQL、PostgreSQL、Redis、Node.js、Pythonなどの主要なソフトウェアの公式イメージが公開されており、これらを使うことで環境構築の手間が大幅に削減されます。

# Docker Hubからイメージを検索する docker search nginx # イメージをPull(ダウンロード)する docker pull nginx:latest docker pull nginx:1.27 # バージョン指定 # ローカルに保存されたイメージ一覧を表示する docker images # REPOSITORY TAG IMAGE ID CREATED SIZE # nginx latest a1b2c3d4e5f6 2 weeks ago 191MB # nginx 1.27 g7h8i9j0k1l2 4 weeks ago 188MB

タグについて
イメージ名の「:」以降がタグで、バージョンやバリアントを指定します。タグを省略すると「:latest」が使われますが、本番環境では必ず特定のバージョンタグを指定するのがベストプラクティスです。「latestを使ったら予期しないバージョンアップでアプリが壊れた」というトラブルは現場でよくあります。

# 本番でのタグ指定(バージョン固定)の例 docker pull nginx:1.27.0-alpine # タグのバリエーション(サイズの違い) # nginx:latest → フルサイズ(Debian系)。デフォルト # nginx:alpine → 超軽量版(Alpine Linux)。セキュリティ面でも推奨されることが多い

Dockerfileとは:自分だけのイメージを作る仕組み

Docker Hubにある既存イメージをそのまま使うだけでなく、自分のアプリ専用のイメージを作りたい場合はDockerfileを使います。

Dockerfileは、イメージの「作り方の手順書」をコードで書いたテキストファイルです。

1. Dockerfileの基本構文

# Dockerfileの基本例(PythonのWebアプリ) # ベースイメージを指定する(バージョン固定推奨) FROM python:3.12-slim # 作業ディレクトリを設定する WORKDIR /app # 依存関係ファイルをコピーしてインストールする COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # アプリのソースコードをコピーする COPY . . # コンテナが公開するポートを宣言する(ドキュメント目的) EXPOSE 8000 # コンテナ起動時に実行するコマンドを指定する CMD ["python", "app.py"]

2. イメージのビルドと確認

Dockerfileを書いたら、`docker build` コマンドでイメージをビルドします。

# Dockerfileからイメージをビルドする # -t: イメージ名とタグを指定する # .: Dockerfileが置いてあるディレクトリ(現在のディレクトリ) docker build -t my-python-app:1.0 . # ビルドしたイメージでコンテナを起動する docker run -d --name my-app -p 8000:8000 my-python-app:1.0 # ビルドの成否確認 docker images | grep my-python-app # my-python-app 1.0 x1y2z3a4b5c6 10 seconds ago 234MB

3. マルチステージビルドで本番イメージを最適化する

本番用イメージのサイズを最小化するために「マルチステージビルド」が有効です。ビルド時にしか使わないツール(コンパイラ等)を本番イメージに含めずに済みます。

# マルチステージビルドの例(Go言語のアプリ) # ステージ1: ビルド環境 FROM golang:1.22 AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o /app/server . # ステージ2: 実行環境(ビルドツールを含まない最小構成) FROM gcr.io/distroless/base-debian12 COPY --from=builder /app/server /server EXPOSE 8080 CMD ["/server"] # → ビルドステージはbuilderで行い、実行ステージには成果物のバイナリだけコピーする # → 最終イメージのサイズが数MBになる(golang:1.22 の約900MB から大幅削減)

4. Dockerfileのベストプラクティス

COPYの順序を最適化する:変更頻度の低いファイル(requirements.txt等)を先にCOPYすることでキャッシュを活用し、ビルド時間を短縮できます
RUNは1行にまとめる:`RUN apt-get update && apt-get install -y xxx && rm -rf /var/lib/apt/lists/*` のように、関連する処理を1つのRUN命令にまとめるとレイヤー数が減りイメージが小さくなります
.dockerignoreを使う:`.gitignore` と同様に、イメージに含めたくないファイル(`.git`、`node_modules`等)を除外します
rootユーザーで動かさない:セキュリティのため、`USER` 命令で一般ユーザーを作成してからアプリを実行する設計にしましょう

Docker Composeで複数コンテナを一括管理する

実際のWebアプリは複数のコンテナから構成されることがほとんどです。たとえばPythonのWebアプリ、PostgreSQLデータベース、Redisキャッシュという3つのコンテナを連携させる構成は非常に一般的です。

これら複数のコンテナを個別に `docker run` で管理すると、コマンドが複雑になり管理が煩雑になります。Docker Composeはこの課題を解決するツールです。

1. docker-compose.ymlの基本構造

Docker Composeは `docker-compose.yml`(またはcompose.yaml)というyamlファイルに複数コンテナの構成を定義します。

# docker-compose.yml(PythonアプリとPostgreSQLとRedisの構成例) services: web: build: . ports: - "8000:8000" environment: - DATABASE_URL=postgresql://user:password@db:5432/mydb - REDIS_URL=redis://redis:6379/0 depends_on: - db - redis db: image: postgres:16 volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=password - POSTGRES_DB=mydb redis: image: redis:7-alpine volumes: postgres_data:

2. Docker Composeの主要コマンド

# 全コンテナをバックグラウンドで起動する docker compose up -d # 起動中のコンテナの状態を確認する docker compose ps # NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS # myapp-web-1 myapp-web "python app.py" web 2 minutes ago Up 2 minutes 0.0.0.0:8000->8000/tcp # myapp-db-1 postgres:16 "docker-entrypoint.s…" db 2 minutes ago Up 2 minutes 5432/tcp # myapp-redis-1 redis:7-alpine "docker-entrypoint.s…" redis 2 minutes ago Up 2 minutes 6379/tcp # 全コンテナのログを確認する docker compose logs # 特定コンテナのログを確認する(リアルタイム表示) docker compose logs -f web # webコンテナに入ってシェルを実行する docker compose exec web bash # 全コンテナを停止・削除する(ボリュームは残る) docker compose down # ボリュームごと全削除する(データが消えるので本番は注意) docker compose down -v

3. depends_onと起動順序の制御

`depends_on` を指定することで、コンテナの起動順序を制御できます。ただしデフォルトの `depends_on` は「コンテナが起動したこと」を待つだけで、「データベースが接続受付を開始したこと」は保証しません。本番環境では `healthcheck` と組み合わせた `condition: service_healthy` を使いましょう。

# healthcheckを使った起動順序の厳密な制御 services: web: build: . depends_on: db: condition: service_healthy db: image: postgres:16 healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d mydb"] interval: 10s timeout: 5s retries: 5

コンテナ技術の現場活用と次のステップ

コンテナとDockerの基礎を理解したところで、現場での活用シーンと学習の次のステップを整理します。

1. 現場でのDockerの使われ方

ローカル開発環境の統一:チーム全員が同じdocker-compose.ymlを使うことで、「Aさんのマシンでは動くがBさんでは動かない」問題が解消されます
CI/CDパイプライン:GitHub ActionsやGitLab CIでDockerイメージをビルドし、テストを実行して、コンテナレジストリにプッシュするパイプラインが標準構成です
マイクロサービスの実行基盤:Kubernetes上でDockerイメージをデプロイするのが大規模システムの主流です
データベース・ミドルウェアの検証環境:PostgreSQL、MySQL、Redisなどを本番環境に影響なく手軽に試せます

2. Dockerの次に学ぶべき技術

Dockerを使いこなせるようになったら、以下のステップで学習を深めていくのがLinux現場エンジニアとしての王道ルートです。

Docker Swarm:Docker標準のクラスタリング機能。小~中規模のコンテナ管理に適しています
Kubernetes(K8s):大規模なコンテナオーケストレーションの業界標準。本番環境での自動スケーリング・自己修復・ローリングデプロイを実現します
コンテナレジストリ(プライベート):Amazon ECR、GitLab Container Registry等を使って、自社専用のプライベートイメージ管理を行います
コンテナセキュリティ:Trivy等のスキャンツールでイメージの脆弱性を検出し、非rootユーザー実行・read-onlyファイルシステム等を適用します

Linuxコマンドの基礎とDockerの組み合わせは、現代のサーバーエンジニアにとって必須スキルセットです。ポート確認にはLinux ポート確認の全コマンドが役立ちます。Dockerコンテナのログ調査ではLinuxのジャーナルやdocker logs、システムリソースの確認ではdocker statsコマンドを日常的に使います。

3. 本記事のまとめ

コンテナとDockerの全体像をまとめます。

概念・技術 概要・ポイント
コンテナ アプリ+ライブラリをひとまとめにした軽量な実行環境。OSカーネルを共有する
VMとの違い VMはゲストOSカーネルを持ち重い。コンテナはカーネル共有で軽量・高速起動
Dockerの役割 コンテナの作成・実行・配布を簡単にするツール群(CLI・デーモン・Hub)
Docker Hub 公式・コミュニティイメージを公開・共有するレジストリサービス
Dockerfile イメージの作り方をコードで書いた手順書。環境の「コード化」を実現する
Docker Compose 複数コンテナをyaml1ファイルで定義・一括管理するツール

コンテナは「難しい技術」ではなく「環境の差異をなくすための実用的な仕組み」です。Linuxの基礎知識があれば、Dockerを使い始めるまでのハードルは決して高くありません。

Linux ポート確認の全コマンド
Linux DNS 設定の基本

Dockerをゼロから体系的に学びたい方は、Docker実践講座(linuxmaster.jp)をご覧ください。現役エンジニアが現場目線で教えるDockerの基礎から実践活用まで、ハンズオン形式で習得できます。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。


  • この記事の属するカテゴリ:Dockerへ戻る