Docker とは

Docker は「コンテナ」という仕組みを使って、アプリケーションとその実行環境をまるごとパッケージングするツールです。「自分の PC では動くのにサーバーでは動かない」という問題を根本から解決します。

コンテナとは何か

「コンテナ」という言葉だけを聞くと難しそうに感じますが、実物にたとえるとシンプルな道具です。コンテナを一言で言うと、アプリと動作環境をひとまとめにした箱です。

たとえば「Python 3.12 + requests 2.32 + 特定の設定ファイル」という環境を、コンテナとして固めておけば、どのマシンに持っていっても同じ状態で動かせます。開発 PC でも、本番サーバーでも、同僚の PC でも。

Docker の4概念を日常に置き換えると、Dockerfile がレシピ、Image がそのレシピ通りに作って封をした冷凍食品、Container がレンジで温めて食卓に出した実物です。同じ冷凍食品(Image)から何個でも解凍(コンテナ起動)できます。そして——ここが重要——食べ終わった皿に書き込んだものは次回には残りません。コンテナ内のデータはデフォルトで消えます。この揮発性を知っておくことが、AI の Docker コードを読むときの最重要ポイントです。

# コンテナのイメージ
[コンテナ]
 ├── アプリのコード
 ├── Python 3.12
 ├── 必要なライブラリ
 └── OS の最小構成(Ubuntu など)
🎯 読み解きポイント:AI が Dockerfile を書いてきたとき、コンテナの「中身」を確認する

AI が生成するコードの中には Dockerfile が含まれることがあります。ファイルを受け取ったら、まず「このコンテナに何が入っているか」を確認しましょう。FROM 行がベースの OS(Ubuntu や Python の公式イメージなど)、RUN 行がインストールするソフトウェア、COPY 行が追加するコードやファイルです。上の構造図の「Python 3.12」「ライブラリ」「OS の最小構成」が、それぞれどの行に対応するかを追えると Dockerfile が読めるようになります。

仮想マシンとの違い

「仮想マシンと何が違うの?」とよく聞かれます。似ているようで、中身の仕組みはまったく別物です。

# 仮想マシン(VM)の構造
[ホスト OS] → [ハイパーバイザー] → [ゲスト OS 丸ごと] → [アプリ]
# OS 丸ごと動かすので重い(起動に数十秒〜数分)

# コンテナの構造
[ホスト OS のカーネル] → [コンテナ(OS の最小部分 + アプリ)]
# カーネルを共有するので軽い(起動は数秒以下)
コンテナと仮想マシンの比較
起動速度
コンテナ:数秒以下 / 仮想マシン:数十秒〜数分
リソース消費
コンテナ:軽い(OS を丸ごと持たない)/ 仮想マシン:重い
分離レベル
コンテナ:プロセス分離 / 仮想マシン:完全分離(よりセキュア)
用途
コンテナ:アプリの配布・開発環境統一 / 仮想マシン:OS レベルの違いが必要な場面

WSL で Docker を使う理由

Windows でエンジニアをしていると必ず一度は突き当たる疑問があります。「なぜ Windows でそのまま Docker を動かせないのか」。

Docker は Linux カーネルの機能を使って動作します。Windows には Linux カーネルがありません。そこで WSL 2 が登場します。

Windows
└── WSL 2(Linux カーネルが動く)
    └── Docker Engine(Linux カーネルの機能を使う)
        ├── コンテナ A(Web アプリ)
        ├── コンテナ B(データベース)
        └── コンテナ C(Redis)

WSL 2 があれば、Windows 上でも Linux ネイティブの Docker がほぼそのまま動きます。開発環境と本番の Linux サーバーとで、ほぼ同じ動作を期待できます。

Docker の主な概念

コンテナ・イメージ・Dockerfile・Compose——Docker を使いはじめるとこの4つの言葉が頻繁に出てきます。AI が生成したコードにこれらが混在していても混乱しないよう、それぞれの役割を整理しておきましょう。

覚えておく4つの用語
イメージ(Image)
コンテナの設計図。「Ubuntu 22.04 + Python 3.12 が入った状態」のスナップショット。Docker Hub から取得するか、Dockerfile から自分でビルドする
コンテナ(Container)
イメージを起動したもの。設計図(イメージ)から作った実物。同じイメージから何個でも起動できる
Dockerfile
イメージを作るための手順書。「Ubuntu を使って、Python を入れて、コードをコピーして…」という手順を記述する
Docker Compose
複数コンテナをまとめて管理するツール。Web サーバー・DB・キャッシュなど複数サービスを docker compose up 一発で起動できる
🎯 読み解きポイント:AI が渡してくるファイルが「Dockerfile」か「docker-compose.yml」かで役割が違う

AI に「Docker の設定を作って」と頼むと、2種類のファイルが返ってくることがあります。Dockerfile(拡張子なし)はイメージを作るための手順書です。docker-compose.yml は複数のコンテナを束ねて動かすための設定ファイルです。Dockerfile は「何を入れたコンテナか」を定義し、Compose は「そのコンテナをどう組み合わせて動かすか」を定義します。まず「どちらのファイルを渡されたか」を確認するのが、AI の Docker コードを読む第一歩です。

実際のDockerfileとdocker-compose.ymlを読んでみる

用語だけ覚えても、実物のファイルを前にすると急に難しく感じるものです。AIが生成しがちな最小構成のPythonアプリを例に、行ごとに何をしているかを確認してみましょう。

# Dockerfile
FROM python:3.12-slim      # ベースイメージ(軽量版Python 3.12)

WORKDIR /app                # コンテナ内の作業ディレクトリを指定

COPY requirements.txt .     # 依存ライブラリの一覧だけ先にコピー
RUN pip install -r requirements.txt

COPY . .                    # 残りのアプリのコードをコピー

CMD ["python", "app.py"]    # コンテナ起動時に実行するコマンド
🎯 読み解きポイント:requirements.txtだけ先にCOPYしているのには理由がある

アプリのコード全部を一度にCOPYせず、先にrequirements.txtだけをコピーしてpip installを実行しているのは、Dockerのビルドキャッシュを効かせるためです。アプリのコードだけを直しても依存ライブラリの一覧が変わっていなければ、次回ビルド時にpip installの手順がキャッシュから再利用され、ビルドが速くなります。AIが生成したDockerfileでこの並び順になっていたら、「速度を意識した書き方だな」と読み取れます。

# docker-compose.yml
services:
  web:
    build: .
    ports:
      - "8000:8000"       # ホスト側:コンテナ側
    volumes:
      - ./data:/app/data   # データを永続化する
    environment:
      - DEBUG=true
    depends_on:
      - db

  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:
docker-compose.ymlでよく見る項目
services
起動するコンテナの一覧。ここではwebとdbの2つ
ports
「ホスト側のポート:コンテナ側のポート」の対応。8000:8000なら手元のブラウザでlocalhost:8000にアクセスできる
volumes
コンテナの外(ホスト側)にデータを保存する設定。これがないとコンテナを消したときにデータも消える
depends_on
起動順序の指定。ここではwebより先にdbを起動しようとする

よくあるはまりポイント

概念を理解しても、最初に Docker を使いはじめると確実にぶつかる落とし穴があります。特に AI のコードをそのまま実行したときにハマりやすいポイントを先に知っておきましょう。

コンテナを削除するとデータが消える

AI に「このコンテナでデータを保存して」と頼んでコードを実行した後、コンテナを停止・削除すると、保存したはずのデータが消えていた——そういう経験をした人は多いと思います。コンテナはデフォルトで「使い捨て」の設計です。コンテナ内に書き込んだファイルは、そのコンテナが消えると一緒に消えます。

データを残したい場合は、ボリューム(volume) を使って、コンテナ外のディレクトリにデータを書き出す必要があります。

🎯 読み解きポイント:AI が書いた Compose ファイルに「volumes:」がなければデータが消える

AI が生成した docker-compose.yml を実行してデータベースを動かしたとき、volumes: の定義がないと、コンテナを再起動するたびにデータが初期化されます。docker compose down を実行したあと「データが消えた」と気づくのはこのためです。受け取った Compose ファイルに volumes: セクションがあるかを最初に確認する習慣をつけましょう。

ポートを公開し忘れてアクセスできない

コンテナは起動しているのに、ブラウザからlocalhostにアクセスしても何も表示されない——これもよくある事故です。原因の多くは、Dockerfileやdocker-compose.ymlにEXPOSEやportsの設定が抜けている、あるいは設定はあってもコンテナ側のポート番号とアプリが実際に待ち受けているポート番号がずれていることです。

実務では「コンテナは正常に起動しているのに繋がらない」という状況に出くわしたとき、docker ps でポートの対応関係(0.0.0.0:8000->8000/tcpのような表示)を確認するのが最初の一手になります。AIに設定を作ってもらったら、コンテナ側のポート番号とアプリの設定ファイル内の待受ポートが一致しているかも合わせて確認しましょう。