Python | テスト・設計・品質:コンテナ構築

Python Python
スポンサーリンク

コンテナ構築って何?一言でいうと「動く箱を作るための“レシピづくり+焼き上げ”」

ここでいう「コンテナ構築」は、ほぼ「Docker コンテナを作ること」と考えてOKです。

レシピを書くフェーズ(Dockerfile を書く)
レシピからイメージを焼くフェーズ(docker build)
イメージから箱を起動するフェーズ(docker run)

この一連の流れをちゃんと理解して、自分でコントロールできるようになることが「コンテナ構築ができる」という状態です。

Python 目線で言うと、

どんな Python を使うか
どんなライブラリを入れるか
どのコードをどこに置くか
どうやって起動するか

を全部 Dockerfile に書いて、「どこでも同じように動く箱」を作る作業です。


まずは最小のコンテナ構築フローをイメージで掴む

1ファイルのPythonスクリプトから始める

シンプルな app.py を用意します。

def main() -> None:
    print("Hello from container!")

if __name__ == "__main__":
    main()
Python

ローカルではこう動かします。

python app.py

これを「コンテナとして動かす」ために、Dockerfile を書きます。

最小のDockerfileを書く

FROM python:3.12-slim

WORKDIR /app

COPY app.py .

CMD ["python", "app.py"]
Dockerfile

ここでやっていることを噛み砕きます。

FROM
「このコンテナの土台は Python 3.12 の軽量イメージを使うよ」という宣言。

WORKDIR
「このコンテナの中での作業ディレクトリは /app にするよ」という指定。

COPY
「ローカルの app.py をコンテナ内の /app にコピーするよ」という指示。

CMD
「コンテナが起動したら python app.py を実行してね」という起動コマンド。

これが「レシピ(Dockerfile)」です。

イメージをビルドしてコンテナを起動する

レシピからイメージを焼きます。

docker build -t my-container-app .

-t はイメージに名前を付けるオプションです。

焼き上がったイメージからコンテナを起動します。

docker run --rm my-container-app

コンソールに

Hello from container!

と出れば、あなたはもう「コンテナを構築して動かした」ことになります。


コンテナ構築で特に大事なポイントを深掘りする

ポイント1:ベースイメージの選び方(FROM)

Python コンテナ構築で最初に悩むのが「どのベースイメージを使うか」です。

よく使うのは python:3.12-slim のような「公式Pythonイメージの軽量版」です。

python:3.12
フルセット。便利だが少し重い。

python:3.12-slim
余計なものを削った軽量版。実運用ではこちらが好まれやすい。

ベースイメージを決める、というのは、

どのOSベースで
どのPythonバージョンで

動かすかを固定する、ということです。

これを Dockerfile の一行で決められるのが、コンテナ構築の強みです。

ポイント2:依存ライブラリのインストールをどう書くか

現実のプロジェクトでは、app.py だけでなく、ライブラリも必要になります。

例えば、requests を使うスクリプトがあるとします。

import requests

def main() -> None:
    r = requests.get("https://example.com")
    print(r.status_code)

if __name__ == "__main__":
    main()
Python

この場合、Dockerfile に「requests をインストールする」ステップが必要です。

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install -U pip && pip install -r requirements.txt

COPY app.py .

CMD ["python", "app.py"]
Dockerfile

requirements.txt は例えばこうです。

requests==2.32.3

ここで重要なのは、

依存のインストールを Dockerfile に明示的に書く
バージョンも固定しておく

ということです。

これにより、「このコンテナの中では必ずこのバージョンの requests が入っている」という状態を作れます。

ポイント3:ビルドキャッシュを意識した書き方

少しレベルを上げると、「ビルドが速くなる書き方」も大事になってきます。

Docker は、上から順に命令を実行し、途中までの結果をキャッシュします。

依存インストールの前にコードを全部コピーしてしまうと、
コードが1行変わるたびに依存インストールからやり直しになります。

なので、よくあるパターンはこうです。

FROM python:3.12-slim

WORKDIR /app

COPY pyproject.toml .

RUN pip install -U pip && pip install .[dev]

COPY src/ src/
COPY tests/ tests/

CMD ["pytest"]
Dockerfile

「依存に関係するファイル(pyproject.toml や requirements.txt)だけ先にコピーしてインストール」
「そのあとでコードをコピー」

という順番にすることで、
コードが変わっても依存インストールのキャッシュが効きやすくなります。

これは、コンテナ構築を日常的に回すときに効いてくる重要ポイントです。


テスト・品質とコンテナ構築のつながり

コンテナの中でテストを回す設計にする

コンテナ構築を「テスト前提」で考えると、こういう発想になります。

このイメージをビルドして
このイメージの中で pytest を実行して
それが通ったイメージだけを本番に使う

つまり、「テスト済みの箱だけを本番に持っていく」という設計です。

さっきの Dockerfile の CMD を pytest にしておけば、

CMD ["pytest"]
Dockerfile

docker run したときにテストが走ります。

CI でも同じイメージを使えば、

ローカル
CI
本番前チェック

のすべてで「同じコンテナ構築結果」を使い回せます。

コンテナ構築を前提にすると「環境依存のバグ」を減らせる

コンテナ構築をちゃんとやると、

Python のバージョン
OS の違い
ライブラリのインストール漏れ

といった「環境の揺れ」がほぼ消えます。

これは品質に直結します。

「自分のマシンでは動くのに、本番では動かない」
「CI では落ちるのに、ローカルでは再現しない」

みたいなストレスが、かなり減ります。


もう一歩踏み込んだ例:Webアプリのコンテナ構築

FastAPIアプリをコンテナに閉じ込めるイメージ

例えば、src/myapp/main.py に FastAPI アプリがあるとします。

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root() -> dict[str, str]:
    return {"message": "Hello from container"}
Python

これを Uvicorn で起動する Dockerfile は、こんな感じになります。

FROM python:3.12-slim

WORKDIR /app

COPY pyproject.toml .
RUN pip install -U pip && pip install .[server]

COPY src/ src/

CMD ["uvicorn", "myapp.main:app", "--host", "0.0.0.0", "--port", "8000"]
Dockerfile

このイメージをビルドして、

docker build -t my-fastapi-app .
docker run --rm -p 8000:8000 my-fastapi-app

ブラウザで http://localhost:8000 にアクセスすると、
コンテナの中で動いている FastAPI に届きます。

ここまで来ると、

「Webアプリをコンテナとして構築して、どこでも同じように動かす」

という感覚がかなりはっきり掴めるはずです。


初心者がコンテナ構築を身につけるための現実的なステップ

ステップ1:1ファイルのPythonスクリプトをコンテナ化する

app.py と最小の Dockerfile で、

docker build
docker run

を一度通してみる。

ここで「イメージ」と「コンテナ」の感覚を体に入れる。

ステップ2:依存ライブラリ付きの小さなプロジェクトをコンテナ化する

requirements.txtpyproject.toml を使って、
ライブラリをインストールするステップを Dockerfile に書いてみる。

ここで、「環境ごとにライブラリを入れ直さなくていい」感覚が分かってくる。

ステップ3:テストをコンテナの中で回すDockerfileを書いてみる

CMD を pytest にして、
「このイメージを動かすとテストが走る」状態を作ってみる。

ここまで行くと、コンテナ構築が「品質の土台」になっているのが実感できるはずです。


まとめ(コンテナ構築は「動く箱を設計して焼き上げる技術」)

初心者目線で整理すると、コンテナ構築はこういうものです。

Dockerfile というレシピに「どのPython・どのライブラリ・どのコード・どの起動コマンドか」を書き、docker build でイメージを作り、docker run でコンテナとして動かす一連の流れを自分で組み立てられるようになること。
ベースイメージの選び方、依存インストールの書き方、ビルドキャッシュを意識した順番などを押さえると、日常的に素早く・安定して「同じ環境の箱」を量産できるようになり、テスト・CI/CD・本番運用まで一気につながる。
最初は1ファイルのスクリプトから始めて、少しずつ依存付き・テスト付き・Webアプリと段階を上げていくと、「コンテナ構築」がただの流行り言葉ではなく、自分の武器として使える感覚になっていく。

タイトルとURLをコピーしました