- メタディスクリプション案
- URLスラッグ案
- Windows・Linux両対応のコード生成を例に、Dockerfile・Image・Containerの違いを理解する
- はじめに
- Dockerの役割をひとことで言うと
- まずは超シンプルなコード生成を作る
- Dockerfileとは何か
- Dockerfile・Image・Containerの関係
- Imageとは何か
- Containerとは何か
- Containerはフォルダなのか
- ImageとContainerの実体をひとつ深く理解する
- 実際に動かしてみる
- 生成されたファイルはどこに保存されるのか
- WindowsとLinuxの両方で使える理由
- 環境変数とAPIキーの理解にもつながる
- よくある誤解を最後に整理する
- まとめ
メタディスクリプション案
Dockerの役割を初心者向けにやさしく解説。WindowsとLinuxの両方で動くコード生成を例に、generate.py、Dockerfile、Image、Container、Volume、環境変数の違いと関係を整理します。
URLスラッグ案
/docker-role-code-generation-windows-linux-basics/
Dockerの役割を初心者向けに解説
Windows・Linux両対応のコード生成を例に、Dockerfile・Image・Containerの違いを理解する
はじめに
Docker を学び始めたとき、多くの人が同じところで引っかかります。
「Docker は何をしているのか」
「Image と Container は何が違うのか」
「Container はインスタンスなのか、場所なのか」
このあたりが曖昧なままだと、Docker Compose、環境変数、ボリュームマウント、API キーの受け渡しまで全部がモヤモヤして見えてきます。
この記事では、Windows と Linux のどちらでも動かしたい超シンプルなコード生成ツールを題材にして、Docker の役割を整理します。
特に、次の点が自然に理解できるようにまとめます。
- Docker はコード生成そのものではない
- Image と Container の実体は何か
- Container は「場所」なのか「インスタンス」なのか
- Docker が Windows と Linux の差をどう吸収するのか
Dockerの役割をひとことで言うと
Docker の役割は、アプリを同じ条件で動かせるようにすることです。
たとえば、Python でコード生成ツールを作ったとします。
そのとき Docker を使わないと、こんなことが起こりがちです。
- Windows では動くのに Linux では動かない
- Python のバージョンが違う
- 必要なライブラリが入っていない
- パスの書き方が OS ごとに違う
- 自分の PC では動くのに、他人の PC では動かない
Docker は、こうした違いを減らして、**「このアプリはこの環境で動かします」**という実行条件を箱ごとそろえてくれます。
つまり、Docker はコードを書く人でも生成する人でもなく、コードが安定して動く共通の実行環境を作る仕組みです。
まずは超シンプルなコード生成を作る
最初に、Docker の話をいったん横に置いて、単純な Python プログラムを見ます。
次の generate.py は、入力した関数名から Python コードを作るだけの最小例です。
generate.py
function_name = input("作りたい関数名を入れてください: ").strip()generated_code = f"""def {function_name}():
print("Hello from {function_name}")
"""print("\n--- 生成されたコード ---")
print(generated_code)with open("generated.py", "w", encoding="utf-8") as f:
f.write(generated_code)print("generated.py に保存しました。")
たとえば hello_app と入力すると、次のようなコードが出力されます。
def hello_app():
print("Hello from hello_app")
generate.py は コード生成を行うアプリ本体です。
Dockerfileとは何か
次に、その generate.py を Docker で動かすための設定を書きます。
Dockerfile
FROM python:3.12-slimWORKDIR /appCOPY generate.py /app/CMD ["python", "generate.py"]
これは次の意味です。
- Python 3.12 が入った軽量な土台を使う
- コンテナ内の作業場所を
/appにする generate.pyを/appにコピーする- コンテナ起動時に
python generate.pyを実行する
ここで重要なのは、Dockerfile は実行環境そのものではなく、実行環境を作るための設計書だということです。
Dockerfile・Image・Containerの関係
Docker の基本の流れは次の 1 行でかなり整理できます。
Dockerfile → build → Image → run → Container
この順番です。
- Dockerfile を書く
docker buildで Image を作るdocker runで Container を起動する
この 3 つを混同しないことが、Docker 理解の第一歩です。
Imageとは何か
Image は、Container を作るための完成済みテンプレートです。
たとえると、
- Dockerfile = 設計図
- Image = 設計図どおりに作られたモデル
- Container = そのモデルから実際に起動した実物
です。
ここでよくある疑問が、
「Image の実体はファイルなのか」
というものです。
結論から言うと、単純な 1 個のファイルではありません。
Dockerfile はテキストファイルですが、Image は Docker 内部に保存される
- ファイルシステムのレイヤー
- 設定情報
- メタデータ
の集合です。
つまり Image は、「この環境はこういう中身です」という完成済みの静的テンプレートです。
動いてはいませんが、いつでも Container を起動できる準備ができた状態です。
Containerとは何か
Container は、Image から実際に起動された実行中の環境です。
ここで多くの人が感じる疑問がこれです。
Container はインスタンスなのか。
それとも場所なのか。
答えは、インスタンスと考えてよい。ただし、単なるオブジェクトのインスタンスより少し広い意味を持つです。
Container は、
- Image をもとに起動される
- 独立したファイルシステムを持つ
- 独立した環境変数を持つ
- 独立したプロセスとして動く
ので、Image の実行インスタンスとして理解するのが自然です。
一方で、「場所」と表現されることがあるのは、その中に /app のような作業ディレクトリがあり、ファイルやプロセスが隔離されて見えるからです。
つまり初心者向けには、
Container = 小さな独立した実行部屋
と覚えるとわかりやすいです。
少し正確に言うなら、
Container = Image をもとに起動された隔離済みの実行インスタンス
です。
Containerはフォルダなのか
これも非常によくある勘違いです。
Container はフォルダそのものではありません。
ただし、Container の中にはフォルダ構造があります。
たとえば今回の Dockerfile には、こうあります。
WORKDIR /app
このため、Container の中には /app という作業場所ができます。
また、COPY generate.py /app/ によって generate.py もそこに入ります。
この見え方のせいで、Container 全体がフォルダのように思えます。
しかし Container の本体はもっと広いもので、
- Image の読み取り専用レイヤー
- Container 専用の書き込みレイヤー
- 起動中のプロセス
- ネットワーク設定
- 環境変数
を含んだ実行環境です。
なので、フォルダを含むが、Container 自体はフォルダではないという理解が正確です。
ImageとContainerの実体をひとつ深く理解する
ここを少しだけ具体的にすると、Docker が一気に見えやすくなります。
Image の実体
Image は Docker の内部に保存される読み取り専用のレイヤー集合です。
たとえば今回なら、そこには次のようなものが含まれます。
- Python 3.12 の実行環境
- 必要最小限の Linux ベース
/app/generate.py- 起動コマンド情報
Image は「完成済み」ですが、まだ動いていません。
Container の実体
Container は、その Image の上に書き込み可能な層を 1 枚追加して起動されたものです。
その中で実際に
python generate.pyが動き- 入力を受け取り
generated.pyを書き出し- プロセスとして存在する
という状態になります。
つまり、
- Image = 静的なひな形
- Container = 動的に動いている実体
です。
実際に動かしてみる
まずは Image を作ります。
docker build -t simple-codegen .
これは、カレントフォルダの Dockerfile をもとに simple-codegen という名前の Image を作るコマンドです。
次に Container を起動します。
docker run -it simple-codegen
すると、Image から 1 つの Container が起動し、その中で generate.py が実行されます。
つまり、この時点でやっていることは、
generate.pyを直接動かしているのではなくgenerate.pyが入った Image から Container を起動し- その Container の中で
generate.pyを走らせている
という構造です。
生成されたファイルはどこに保存されるのか
この例では、generate.py が generated.py を出力します。
では、そのファイルはどこにできるのでしょうか。
何も設定しなければ、Container の中です。
つまり、ホスト側の Windows や Linux のフォルダに、必ずしもそのまま見えるわけではありません。
そこで使うのが Volume マウント です。
Linux / macOS
docker run -it -v $(pwd):/app simple-codegen
Windows PowerShell
docker run -it -v ${PWD}:/app simple-codegen
これで、ホスト側の現在フォルダと、Container 内の /app がつながります。
すると、Container 内で作った generated.py がホスト側にも見えるようになります。
この仕組みを見ると、Container は単なるフォルダではなく、ホストとは別の実行環境でありながら、必要な部分だけ共有できる仕組みだとわかります。
WindowsとLinuxの両方で使える理由
Docker が便利なのは、ホスト OS が違っても、Container の中をかなり同じ状態にそろえられることです。
たとえば今回の例では、
- Windows 上の Docker
- Linux 上の Docker
のどちらで動かしても、Container の中は
- Python 3.12
/appgenerate.py
という同じ構成になります。
もちろんボリューム指定の細かい書き方など、外側には OS 差が少し残ります。
ただ、アプリ本体が動く核心部分を共通化できるのが Docker の大きな価値です。
つまり Docker は、Windows 用と Linux 用で別々に苦労する部分を減らして、アプリの本質に集中しやすくする仕組みです。
環境変数とAPIキーの理解にもつながる
Docker を使って LLM ベースのコード生成を動かすとき、よく OPENAI_API_KEY を使います。
このときも考え方は同じです。
Docker は API キーを勝手に探し回る魔法の仕組みではありません。
Docker は、ホスト側で用意した環境変数を Container に渡すだけです。
たとえば Compose では、次のように書きます。
services:
app:
build: .
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
これは、ホスト側の OPENAI_API_KEY を Container 側にも渡す、という意味です。
ここでも Docker の役割は変わりません。
アプリ本体を作ることではなく、アプリが必要とする実行条件をそろえて受け渡すことです。
よくある誤解を最後に整理する
Docker を学び始めたばかりの段階では、次のような誤解が起こりやすいです。
Docker がコード生成している
違います。
コード生成しているのは generate.py のようなアプリ本体です。
Dockerfile がそのまま動く
違います。
Dockerfile は設計書で、まず Image に build されます。
Image はただのファイル
違います。
Docker 内部に保存されるレイヤーや設定情報の集合です。
Container はフォルダ
違います。
フォルダ構造を含む実行環境です。
Container は単なる場所
半分だけ正しいです。
作業場所はありますが、本質は 起動中の隔離された実行インスタンス です。
まとめ
Docker の役割は、コード生成ロジックそのものを担うことではなく、そのロジックを同じ条件で安定して動かすことです。
今回の例では、役割分担は次のとおりです。
generate.py
コード生成を行うアプリ本体- Dockerfile
そのアプリをどういう環境で動かすかを定義する設計書 - Image
設計書から作られた、静的な実行テンプレート - Container
Image をもとに起動された、動的な実行環境
この 4 つが整理できると、Docker Compose、Volume、環境変数、API キー受け渡しまで一気につながって見えてきます。
最短で覚えるなら、次の 4 行で十分です。
generate.pyはアプリ本体- Dockerfile は設計書
- Image は実行テンプレート
- Container は起動中の実行インスタンス
これが腹落ちすると、Docker はかなり扱いやすくなります。

コメント