「Linux の仮想マシンを入れて、環境をまったく同じにしてみて」
入社3か月目、オフィスの空気はどこか落ち着かなかった。唯一の先輩は別プロジェクトへの異動が決まり、引き継ぎどころか自分の荷物をまとめるので手いっぱいだったし、チーム長は実際の開発現場から長く離れていて、最新技術の流れにはかなり疎かった。
ある日、チーム長が私を呼んだ。 「先輩がいなくなったら、サーバーを見られるのは君しかいない。サーバーが落ちても一人で復旧できるようにならないといけない。今使っている開発用ノートPC、Windows に Linux を仮想マシン(VM)として入れて、本番サーバーと同じ環境を作ってみて」
その日から私の泥沼が始まった。VMware を入れ、Ubuntu の ISO ファイルを落としてインストールするだけで半日かかった。社内 wiki をあさりながら Java、Node.js、PostgreSQL を入れた。「新しいほうがいいだろう」と思って Java 17 を入れたら、レガシーコードは Java 8 前提で、ビルドすら通らないことが分かった。結局アンインストールして入れ直しだ。コードを1行直すたびに mvn build を回し、jar ファイルを VM に持っていって実行する作業は、まさに苦行だった。
そんなある時、ふと疑問が浮かんだ。 「待って、この前本番サーバーにデプロイしたときって、docker service update を1行打っただけで終わってなかったっけ?」
自分のローカル仮想マシンはこんなにも重く、設定することも山ほどあるのに、本番サーバーにいるあの「Docker」とは一体何者で、どうしてコマンド一発で更新できるのだろう?

重い解決策: 仮想マシン (Virtual Machine)
チーム長に言われた方法、つまり Windows の上に Linux をもう一つ入れる方法こそが「仮想マシン(VM)」だ。これは物理コンピュータ、Host の上に「仮想の家」、つまり Guest OS を丸ごと建てるようなものだ。
- 方式: 一台のコンピュータで OS を何個も動かす。(Windows の上に Linux、さらにその上にまた Linux…)
- 問題: 家を建てるには、柱も壁もトイレ(カーネル)も、全部一から建てなければならない。
- アプリを一つ動かすためだけに、何 GB もある OS を丸ごとインストールしなければならない。
- 起動するだけで日が暮れる。(私のノートPCが遅くなった理由だ)
- リソースの使い方が非効率だ。(何もしていなくても、OS を維持するだけでメモリを食う)
結局、VM は「環境の分離」という点では確実だが、開発やデプロイのたびにやり取りするには、あまりにも重くて遅かった。
軽い革命: Docker
そこで登場したのが「Docker」、つまり「コンテナ(Container)」技術だ。Docker は VM のように家を丸ごと建てない。代わりに「テント」を張る。
- 方式: すでに建っている家(Host OS – Linux)の庭(カーネル)を共有する。張るのは隔離されたテント(Container)だけだ。
- 特徴:
- OS(カーネル)を共有する: テントの中に重い OS はない。入っているのは自分のアプリとライブラリだけだ。
- 軽い: 容量はメガバイト(MB)単位だ。
- 速い: 起動? そんなものはない。プロセスを一つ立ち上げるのと同じ速さ(ミリ秒)で立ち上がる。
私が本番サーバーで打った update コマンドは、重い OS を入れ直していたわけではない。ただ「古いテントをたたんで、新しいコードが入ったテントを張り直していた」だけなのだ。だから一瞬で終わるしかなかった。

[Code Verification] Docker は本当に軽いのか?
口先だけで軽いと言うのではなく、実際に確かめてみよう。Linux、Ubuntu 環境を動かすとしたとき、VM と Docker の差ははっきりしている。
- VM で Ubuntu を実行: ISO ファイルのダウンロード(2GB) -> インストール(20分) -> 起動(1分)。
- Docker で Ubuntu を実行:
# Dockerコマンドでubuntuを実行(イメージがなければダウンロードも自動)
$ docker run -it ubuntu:latest /bin/bash
結果:
- ダウンロード: 約30MB(Ubuntu の核心部分だけを抜き出した、外側だけのイメージ)
- 実行時間: 約0.5秒
Enter を押した瞬間、私はもう Ubuntu 環境の中にいる。これが可能なのは、Docker コンテナが本物の OS ではないからだ。つまり「Host OS、自分のコンピュータ、のカーネルを借りながら、あたかも別の OS のように振る舞う隔離空間」にすぎない。
実務アドバイス: Docker を使う本当の理由
実務で Docker を導入してから、私の仕事のやり方は完全に変わった。
- 「環境構築してください」がなくなった: 以前は新入社員が来ると、「Java をインストールして、環境変数を設定して、DB を入れて…」と、A4 で10枚もある文書を渡していた。今はこう言うだけだ。「Docker を入れて、
docker-compose upを打ってください」 - バージョン地獄からの脱出: A プロジェクトは Java 8、B プロジェクトは Java 17 を使わなければならないとしたら? ローカルに両方入れると衝突して、環境がこじれてしまう。Docker を使えば、A コンテナには Java 8、B コンテナには Java 17 を入れて同時に立ち上げても、まったく問題がない。完全に「隔離(Isolation)」されているからだ。
おわりに: 実行ファイルではなく「環境」を届ける
Docker の登場によって、開発のパラダイムは変わった。私たちはもうソースコード、.java、だけをサーバーに送らない。そのコードが動くための OS 設定、ライブラリ、環境変数まで含めて「イメージ(Image)」として固め、丸ごと届けるようになった。
では、この魔法のような「Docker イメージ」は一体どうやって作られるのだろう? ただの圧縮ファイルなのだろうか? 驚くべきことに、Docker イメージは「ケーキ」のように複数のレイヤー(Layer)で積み重なっているらしい。
次回は、Docker の効率性の秘密である「イメージとレイヤー構造」について掘り下げてみよう。


