Dockerの基本|コンテナとは何かを実務目線で理解する
Dockerのコンテナは、アプリを動かすのに必要な実行環境をまとめて持ち運べる箱です。実務で価値が出るのは、概念がきれいだからではありません。手元のPC、チームメンバーのPC、CI、検証サーバーで「同じものを同じ手順で動かしやすい」からです。
たとえば、ある案件で PHP 8.2 と MySQL 8 を使い、別案件では Python 3.12 と PostgreSQL 16 を使う場面があります。ローカルに全部を直接入れると衝突しやすく、再現も難しくなります。Dockerなら案件ごとに環境を分け、必要なときだけ起動できます。
- できること: 開発環境の再現、依存関係の分離、複数サービスの同時起動、CIでの同一手順化
- 向いている場面: Webアプリ開発、検証環境の共有、バージョン違いの共存、チーム開発の初期セットアップ
- 最初に押さえる点: コンテナはVMそのものではなく、アプリを隔離して動かす仕組み
- 実務で重要な点: イメージ、コンテナ、ボリューム、ポート公開の4つを区別すること
ここがポイント: Dockerを覚える目的は「コンテナを作ること」より、「環境差分で壊れない作業手順を持つこと」にあります。
Dockerとコンテナの違い
まず混同しやすい言葉を整理します。
- Docker: コンテナを作る、起動する、配布するためのプラットフォーム
- イメージ: コンテナの元になる実行テンプレート
- コンテナ: イメージから起動した実行中のプロセス環境
- Dockerfile: イメージの作り方を書く設計書
Docker公式ドキュメントでは、コンテナは「隔離されたプロセス」として説明されています。つまり、仮想マシンのようにOSを丸ごと増やすのではなく、ホストのカーネルを共有しながら、アプリごとにファイルシステムやネットワーク空間を分けて動かします。
VMとの違い
VMはOSごと分ける仕組みです。分離は強い一方で、起動コストやリソース消費が大きくなりがちです。
一方でコンテナは、アプリ実行に必要なものを軽量にまとめて動かします。だからローカル開発やCIでは特に扱いやすい。Webアプリ、API、DBを別々のコンテナで並べても、VMを何台も立てるより軽く回しやすいのが利点です。
実務で何が楽になるか
抽象論より、現場で効く点を見ると分かりやすいです。
- 新メンバーのセットアップを短くしやすい
- 「自分のPCでは動く」の差分を減らしやすい
- Node.jsやPythonなどのバージョン衝突を避けやすい
- DBやRedisを一時的に起動して、不要になれば止められる
- CIとローカルの実行手順を近づけやすい
前提環境と導入の考え方
2026年4月21日時点のDocker公式情報では、Docker Desktopは Mac、Windows、Linux 向けに提供されており、Docker Engine、Docker CLI、Docker Compose をまとめて扱えます。学習用やローカル開発なら、まずDocker Desktopから入るのが分かりやすい構成です。
LinuxサーバーやGUI不要の環境では、Docker Engineを個別に入れる構成もあります。ComposeもLinuxではプラグインとして導入できます。
まずどれを入れるべきか
- Windows / macOSでローカル開発したい: Docker Desktop
- Linuxデスクトップで素早く始めたい: Docker Desktop
- Linuxサーバーで常駐運用したい: Docker Engine中心で構成
- 複数コンテナをまとめて扱いたい:
docker composeを使う
まず1回動かす: 最小のコンテナ実行
最初は理屈より、1つ動かすほうが早いです。Docker公式のサンプルイメージを使うと、コンテナの起動、ポート公開、停止まで一気に確認できます。
docker run -d -p 8080:80 docker/welcome-to-docker
この1行でやっていることは次のとおりです。
docker run: イメージからコンテナを起動する-d: バックグラウンドで実行する-p 8080:80: ホストの8080番を、コンテナの80番に接続するdocker/welcome-to-docker: 起動元のイメージ名
起動後は、実行中のコンテナを確認します。
docker ps
出力例:
CONTAINER ID IMAGE PORTS NAMES
xxxxxx docker/welcome-to-docker 0.0.0.0:8080->80/tcp hopeful_demo
ブラウザで http://localhost:8080 を開くと、コンテナ内のWebサーバーにアクセスできます。ここで大事なのは、アプリはコンテナ内で動いていて、ブラウザはホスト側の8080番からそこへ入っているという理解です。
停止は次です。
docker stop hopeful_demo
名前の代わりにコンテナIDでも止められます。
イメージとDockerfileの関係
実務では「公開イメージをそのまま使う」だけでは足りません。自分のアプリを入れたイメージを作る場面が出てきます。その設計書がDockerfileです。
Docker公式では、Dockerfileはイメージを組み立てるための命令を並べたテキストファイルとして説明されています。
最小の例
静的HTMLを配るだけの最小例なら、次のように考えれば十分です。
Dockerfile
FROM nginx:alpine
COPY ./site /usr/share/nginx/html
site/index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Hello Docker</title>
</head>
<body>
<h1>Hello Docker</h1>
<p>Container works.</p>
</body>
</html>
ビルド:
docker build -t hello-web:1.0 .
実行:
docker run -d -p 8080:80 hello-web:1.0
この流れで覚えるべきことは3つです。
FROM: 土台になるイメージを選ぶCOPY: 手元のファイルをイメージへ入れるdocker buildでイメージを作り、docker runでコンテナとして起動する
ここを曖昧にすると、「buildしたのに反映されない」「runしただけでファイルが増えると思っていた」といった混乱が起きやすくなります。
Docker Composeはいつ使うか
アプリが1個のコンテナで完結するなら docker run でも十分です。ただ、実務ではフロントエンド、API、DB、キャッシュのように複数サービスが並びます。そのときは docker compose のほうが管理しやすいです。
たとえば、WebアプリとDBをまとめて扱うときはこう書けます。
services:
app:
build: .
ports:
- "8080:80"
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: example
起動:
docker compose up -d
停止と削除:
docker compose down
Composeの価値は、複数コンテナを1つの設定ファイルで持てることです。READMEに長い起動手順を書く代わりに、compose.yaml を置いて docker compose up で揃える。これがチーム開発で効きます。
実務での使いどころ
Dockerが便利なのは、開発者の気分を良くするためだけではありません。運用や引き継ぎまで含めて手順を安定させやすいからです。
1. ローカル開発環境を案件ごとに分ける
同じPCで複数案件を触ると、ランタイムやDBのバージョン衝突が起きます。Dockerなら案件単位で閉じ込めやすい。PHP案件のあとにPython案件を触っても、ローカルを汚しにくくなります。
2. CIで同じ環境を再現する
ローカルで使うイメージとCIで使うイメージが近いほど、テストの再現性は上がります。依存関係の取り込み方やOS差分で落ちるケースを減らしやすいです。
3. 補助サービスを必要なときだけ使う
- PostgreSQL n- MySQL
- Redis
- MailHog
- MinIO
この種の補助サービスは、常時インストールよりもコンテナ起動のほうが管理しやすい場面が多いです。検証後に消せるのも大きい。
よくある失敗と対処
Docker入門でつまずくのは、コマンドの難しさより「どこで何が動いているか」を見失うことです。
コンテナがすぐ終了する
原因になりやすいのは、メインプロセスが終わっていることです。コンテナは中で動く主処理が終わると停止します。
確認手順:
docker ps -aで停止済みも見るdocker logs <container>でエラーを見るCMDやENTRYPOINTの指定を見直す
localhost がつながらない
多くはポート公開の不足です。コンテナ内の80番は、そのままではホストから見えません。
-p 8080:80のようにポートを公開する- どのポートへ公開したか
docker psで確認する - アプリがコンテナ内で本当にそのポートを listen しているか確認する
データが消えた
コンテナを作り直すと、コンテナ内にだけ置いたデータは消えます。DBやアップロードファイルを残したいなら、ボリュームを使う設計が必要です。
変更が反映されない
原因は大きく2つです。
- イメージを作り直していない
- コンテナだけ再起動していて、古いイメージを使っている
更新時は docker build、その後に新しいイメージで docker run もしくは docker compose up --build を使う流れを意識すると崩れにくくなります。
秘密情報をイメージに入れてしまう
APIキーやDBパスワードをDockerfileへ直接書くのは避けるべきです。イメージを配布すると、中に入れた情報も一緒に扱われます。環境変数、Composeの設定、クラウド側のシークレット管理を使い分けたほうが安全です。
Dockerを使わないほうがいい場面もある
Dockerは便利ですが、常に最適ではありません。
- 単発の小さなCLI確認だけで、環境差分が問題にならない
- GUI中心のアプリで、コンテナ化の恩恵が薄い
- 学習対象がDockerそのものではなく、まず言語の文法だけ触りたい
- Windows固有、macOS固有の挙動をそのまま検証したい
「何でもDockerに入れる」より、環境再現が課題かどうかで判断したほうが実務ではうまくいきます。
代替手段との使い分け
Dockerを過大評価しないために、他の手段との違いも押さえておくと判断しやすくなります。
| 方法 | 向いている場面 | 弱い点 |
|---|---|---|
| ローカルへ直接インストール | 最小構成で素早く試すとき | 案件が増えると依存関係が衝突しやすい |
| 仮想マシン | OSごと隔離したいとき | 重くなりやすく、起動も遅め |
| Docker | アプリ単位で環境を揃えたいとき | ネットワーク、ボリューム、ビルドの理解が必要 |
最初の学び方はこの順で十分
入門段階で全部を覚える必要はありません。次の順で触ると、概念と実務がつながりやすいです。
docker runで既存イメージを動かすdocker psとdocker logsで状態を見るDockerfileを書いて自分のイメージを作るdocker composeで複数サービスをまとめる- ボリュームと環境変数を扱う
最後に見るべきポイントを絞るなら、次です。
- イメージは設計図、コンテナは実行体と分けて考える
- ポート公開しないとホストから見えない
- データを残すならボリュームが必要
- 複数サービスになったらComposeへ進む
- 秘密情報をDockerfileへ直書きしない
Dockerの基本を理解する目的は、コマンド暗記ではありません。案件を切り替えても壊れにくい開発手順を持てるかどうかです。次に学ぶなら、compose.yaml の書き方と、ボリューム・環境変数・ログ確認の3点から入ると、実務へつながりやすくなります。
