Dockerを「軽量な仮想マシン」だと思ってる人、結構多い。でもこれは誤解で、Dockerの本質はプロセス分離だ。仮想マシンがハードウェアをエミュレートするのに対して、DockerはLinuxカーネルの機能(cgroup + namespace)を使ってプロセスを隔離してるだけ。
この違いがなぜ重要か。VMはOSごと起動するから起動に数十秒、数GBのメモリを食う。Dockerコンテナはプロセスを起動するだけだから、起動は1秒未満、メモリもほぼアプリ本体の分だけ。この軽さがコンテナ革命の本質だ。
Dockerの3大構成要素:
- Dockerfile — 「このベースイメージから出発して、これらをインストールして、このポートを開けて、このコマンドで起動」というレシピ。インフラの設計図がコードになる。
- イメージ — Dockerfileからビルドされた実行可能パッケージ。レイヤー構造で差分だけ保存するから、ストレージ効率が異常に良い。
- コンテナ — イメージの実行インスタンス。使い捨て前提。コンテナが死んでもイメージから何度でも作り直せる。
Dockerfileを書くコツ:
- レイヤーを減らす — RUNコマンドは`&&`で繋げて1レイヤーに。無駄なレイヤーが積み重なるとイメージが太る。
- .dockerignoreを使う — `node_modules`とか`.git`をビルドコンテキストから除外。転送が爆速になる。
- マルチステージビルド — ビルド用と実行用でイメージを分ける。Goアプリならビルドはgolangイメージ、実行はalpineで。最終イメージが激痩せする。
Dockerを理解するとは「イミュータブル・インフラストラクチャ(変更不可なインフラ)」の考え方を理解すること。サーバーを「育てる」時代から「製造する」時代へのパラダイムシフトだ。