Pythonで開発を進めていると、いつの間にか環境構築が複雑になり「どのパッケージを入れたのか分からない」という状態になりがちです。
requirements.txtは、そんな状況を防ぎ、「同じ環境を一瞬で再現できる」ようにするための重要なファイルです。
本記事では、requirements.txtの基本から、最短で作成する手順、実務で役立つベストプラクティスまでを、図解とサンプルコード付きで丁寧に解説します。
requirements.txtとは何か
requirements.txtの役割とメリット

requirements.txtは、Pythonプロジェクトで必要な外部パッケージとそのバージョンを一覧にしたテキストファイルです。
ファイル名は慣習としてrequirements.txtが使われ、プロジェクトのルートディレクトリに置かれます。
このファイルの役割は、主に次のように整理できます。
- プロジェクトが依存しているパッケージを明示し、誰でも同じ環境を再現できるようにする
- 開発環境、テスト環境、本番環境で、ライブラリのバージョン差による不具合を防ぐ
- 時間が経っても「当時動いていた環境」を再現しやすくする
つまり、requirements.txtは「環境構成の仕様書」兼「再現レシピ」のような存在です。
開発現場では、次のようなメリットがあります。
- 新しく参加したメンバーが
pip install -r requirements.txtだけで環境構築できる - CIツールや本番サーバーで、同じパッケージ構成を自動的にセットアップできる
- 不意のライブラリアップデートで、動いていたコードが突然動かなくなるリスクを減らせる
pipとの関係と基本的な仕組み

Pythonにはpipと呼ばれる標準的なパッケージ管理ツールがあります。
requirements.txtは、このpipが理解できる形式でパッケージの一覧と条件を書いたファイルです。
基本的な流れはとてもシンプルです。
- 開発者がrequirements.txtに、必要なパッケージ名とバージョン条件を書く
- 別の環境で
pip install -r requirements.txtを実行する - pipがrequirements.txtを読み取り、PyPIなどのリポジトリから該当パッケージをインストールする
内部的には、pipがrequirements.txtを1行ずつ読み、「パッケージ名」「バージョン条件」「オプション」を解釈してインストールを行います。
したがって、requirements.txtの書き方を理解することは、そのままpipの挙動を理解することにつながります。
requirements.txtの基本的な書き方
パッケージ名とバージョン指定の基本
requirements.txtの最もシンプルな書き方は、1行に1パッケージを記述する形式です。
最小限の例
requests
numpy
pandas
このように、バージョンを指定しないことも可能です。
ただし、実務ではバージョンを固定または条件付きで指定することがほとんどです。
バージョンを明示する記述
requests==2.31.0
numpy==1.26.4
pandas==2.2.2
この記述は「指定したバージョンそのものをインストールする」という意味になります。
後の章で詳しく説明しますが、本番環境ではバージョン固定(==)が推奨されるケースが多いです。
バージョン指定子(==, >=, <=, ~=)の使い分け

requirements.txtでは、バージョンを細かく制御するために「バージョン指定子」と呼ばれる記号を使います。
代表的なものを表にまとめます。
| 指定子 | 例 | 意味の概要 |
|---|---|---|
| == | requests==2.31.0 | バージョン2.31.0に完全固定 |
| >= | numpy>=1.24 | 1.24以上の任意のバージョン |
| <= | numpy<=1.26 | 1.26以下の任意のバージョン |
| >, < | pandas>2.0 | 2.0より大きい(または小さい)バージョン |
| ~= | django~=4.2 | 4.2以上、5.0未満の範囲(互換性を意識した指定) |
== 完全固定の使いどころ
「本番で動いている環境を1年後にも再現したい」ようなケースでは、==で固定するのが安全です。
Django==4.2.11
gunicorn==22.0.0
psycopg2-binary==2.9.9
こうしておくと、時間が経ってライブラリ側が大きく変わっても、同じ組み合わせでインストールできます。
>=, <=, >, < 柔軟な指定
ライブラリ開発者や、ある程度のバージョン更新を許容したい場合には、範囲指定が有効です。
numpy>=1.24,<2.0
pandas>=2.0,<3.0
このように上下限を組み合わせると「互換性を維持しつつ、マイナーバージョンは上げてもよい」という運用がしやすくなります。
~= 互換性を意識した指定
~=は「互換性のある範囲で最新を許可する」という意味合いを持つ指定子です。
fastapi~=0.115.0 # 0.115.xの範囲でOK、0.116はNG
fastapi~=0.115.0と書くと、内部的にはfastapi>=0.115.0,==0.115.*と同等になります。
すなわち、メジャーバージョンやマイナーバージョンが変わる大きな更新を避けつつ、パッチレベルの更新だけを許可することができます。
コメントと環境依存パッケージの記述
コメントの書き方
requirements.txtでは#で始まる行はコメントとして扱われます。
インストール対象からは無視されるため、メモ書きや用途の説明を付けることができます。
# Webアプリケーション関連
Django==4.2.11
gunicorn==22.0.0 # WSGI HTTPサーバー
# データベース関連
psycopg2-binary==2.9.9
特にチーム開発では、なぜそのバージョンにしているのかをコメントで残しておくと、後から見た人が理解しやすくなります。
環境依存パッケージ(プラットフォームマーカー)
Pythonでは、OSなどの環境によって異なるパッケージをインストールしたい場合に、環境マーカーと呼ばれる条件式を使えます。
# Windowsだけで必要なパッケージ
pywin32==306; platform_system == "Windows"
# Linuxだけで必要なパッケージ
uvloop==0.21.0; sys_platform == "linux"
;の右側に書かれた条件式は「その条件が真のときだけ、この行を有効にする」という意味になります。
これにより、1つのrequirements.txtで複数OSに対応することが可能です。
requirements.txtの最短作成ステップ
pip freezeを使ったrequirements.txt自動生成

現在の環境にインストールされているパッケージから、requirements.txtを最短で作る方法がpip freezeです。
これは「今の環境をそのまま凍結してファイルに書き出す」イメージです。
コマンド例
pip freeze > requirements.txt
このコマンドを実行すると、現在有効なPython環境(できれば仮想環境)にインストールされているパッケージの一覧が、パッケージ名==バージョンの形式でrequirements.txtに書き出されます。
例えば、簡単な環境での実行例をC言語風の疑似表示で確認してみます。
# 仮想環境でパッケージをいくつかインストール
pip install requests==2.31.0
pip install numpy==1.26.4
# 現在の環境をrequirements.txtとして出力
pip freeze > requirements.txt
生成されるrequirements.txtの中身の例を示します。
numpy==1.26.4
requests==2.31.0
urllib3==2.2.3
certifi==2024.8.30
charset-normalizer==3.4.0
idna==3.10
ここで、requestsのようなライブラリは内部的に他のライブラリ(urllib3など)に依存しているため、依存関係まで含めてすべて列挙される点に注意が必要です。
既存プロジェクトからrequirements.txtを作成する手順

既に動いているPythonプロジェクトに対して、「後からrequirements.txtを整備したい」というケースはよくあります。
その場合のシンプルな手順を示します。
1. 仮想環境を作成する
まずはプロジェクト専用の仮想環境を用意します。
# プロジェクトディレクトリで仮想環境を作成
python -m venv .venv
# 仮想環境を有効化 (Windows PowerShell)
.venv\Scripts\Activate.ps1
# 仮想環境を有効化 (macOS / Linux)
source .venv/bin/activate
2. プロジェクトが使っているパッケージをインストールする
コード中のimport文やドキュメントを見ながら、必要なパッケージを仮想環境にインストールしていきます。
pip install requests numpy pandas
3. pip freezeでrequirements.txtを出力する
すべてインストールし終えたら、先ほどと同じようにpip freezeを実行します。
pip freeze > requirements.txt
4. 不要なパッケージを整理する
pip freezeの結果には、仮想環境に入れた補助的なツール(blackやpytestなど)も含まれます。
本番で不要なものは、後から手動で削除するか、開発用のrequirementsファイルに分割するのが望ましいです。
この分割方法は後ほど詳しく説明します。
新規プロジェクトでのrequirements.txt作成フロー

新規プロジェクトの場合、最初からrequirements.txtを意識した運用をしておくと、後で楽になります。
1. プロジェクトと仮想環境を準備
mkdir myproject
cd myproject
python -m venv .venv
source .venv/bin/activate # Windowsなら適宜変更
2. パッケージを入れるたびにrequirements.txtを更新
最もシンプルな運用は、パッケージをインストールしたタイミングで、そのパッケージをrequirements.txtにも追記しておく方法です。
pip install requests
この後で、requirements.txtに行を追加します。
# requirements.txt
requests==2.31.0
バージョン番号はpip showで確認できます。
pip show requests
Name: requests
Version: 2.31.0
Summary: Python HTTP for Humans.
...
3. 開発後半やリリース前にfreezeで固定する
ある程度開発が進み、環境が落ち着いてきた段階でpip freezeを使って、実際に使っているバージョンでrequirements.txtを固めると安全です。
pip freeze > requirements.txt
この時、開発専用ツールを別ファイルに分けたい場合は、後述の「開発環境ごとのrequirements分割」を参考に整理していきます。
Python開発におけるベストプラクティス
開発環境ごとのrequirements分割(dev, prod, test)

1つのrequirements.txtにすべてを書くことも可能ですが、実務では用途ごとにファイルを分割するパターンがよく使われます。
典型的な構成例
requirements/base.txt
共通で使うライブラリ(実行に必要なもの)を記述requirements/dev.txt
baseに加えて、開発専用のツール(フォーマッタ、デバッガなど)を記述requirements/test.txt
baseに加えて、テスト専用のライブラリ(pytestなど)を記述requirements/prod.txt
baseに加えて、本番でのみ必要なパッケージ(WSGIサーバーなど)を記述
ファイル間の参照
pipには-rオプションがあります。
これを使うと、あるrequirementsファイルの中から、別のrequirementsファイルを読み込むことができます。
たとえば、requirements/dev.txtを次のように書きます。
# requirements/dev.txt
-r base.txt
black==24.8.0
isort==5.13.2
pytest==8.3.3
この場合、pip install -r requirements/dev.txtを実行すると、base.txtに書かれたパッケージもまとめてインストールされます。
requirements.txtと仮想環境(venv, pipenv)の組み合わせ方

requirements.txtは、仮想環境とセットで運用してこそ真価を発揮します。
仮想環境を使わずにグローバル環境にインストールしてしまうと、プロジェクト間でパッケージが混ざり合い、バージョン衝突などの問題が発生しやすくなります。
venvとの組み合わせ
標準モジュールvenvを使った一般的な流れは次の通りです。
# 仮想環境を作成
python -m venv .venv
# 仮想環境を有効化
source .venv/bin/activate # Windowsは .venv\Scripts\Activate.ps1
# requirementsから一括インストール
pip install -r requirements.txt
仮想環境ごとにrequirements.txtを切り替えるのではなく、用途やブランチによって仮想環境を分け、その中にrequirementsを反映させるイメージを持つと整理しやすくなります。
Pipenvやpoetryとの関係
Pipenvやpoetryのようなツールを使う場合、Pipfileやpyproject.tomlがrequirements.txtの役割を一部肩代わりしますが、依然として
- CI環境で一括インストールする
- Dockerイメージ内でパッケージ構成を固定する
といった用途ではrequirements.txtがよく使われます。
多くのツールは「ロックファイル」からrequirements.txtを生成する機能を提供しているため、運用ポリシーに応じて使い分けると良いです。
セキュリティと互換性を意識したバージョン管理

requirements.txtのバージョン指定は、セキュリティと互換性のバランスを取るための重要なポイントです。
セキュリティ面の注意
- 古いバージョンのまま放置すると、既知の脆弱性が放置される可能性がある
- 脆弱性情報は、ライブラリのリリースノートや、GitHubのセキュリティアラートなどで公開される
そのため、少なくとも定期的に依存パッケージを見直し、パッチレベルの更新(例: 1.2.3 → 1.2.4)は適用することが推奨されます。
互換性(動作保証)の観点
一方で、常に最新バージョンを許可すると、API変更などによりアプリケーションが突然動かなくなるリスクもあります。
これを防ぐために、
- requirements.txtでは
==で完全固定する - 開発用の別ブランチや別環境でバージョンを更新し、テストが通ることを確認してから本番のrequirements.txtを更新する
といった運用がよく行われます。
実務的なバージョン管理例
本番用:
# requirements/prod.txt
Django==4.2.11
psycopg2-binary==2.9.9
gunicorn==22.0.0
検証用(アップデートテスト用):
# requirements/prod-next.txt
Django~=4.2.0 # 4.2系の最新を許容
psycopg2-binary~=2.9
gunicorn~=22.0
検証環境でprod-next.txtを使い、自動テストや動作確認をしたうえで、問題がなければprod.txtを更新する、といった2段階運用が現実的です。
requirements.txtの運用と更新のコツ

requirements.txtは一度作って終わりではなく、時間とともに育てていくファイルです。
運用を楽にするためのコツをいくつか紹介します。
1. 更新の単位を小さく保つ
多くのライブラリを一度に更新すると、どの変更が不具合の原因か分かりにくくなります。
可能であれば少数のライブラリごとに更新し、その都度テストを走らせるとトラブルシューティングが容易になります。
2. 更新時は必ずテストを実行する
requirements.txtを変更したら、ユニットテストや統合テストを実行し、影響範囲を確認します。
CIツール(GitHub Actionsなど)と連携させて、requirements.txtの変更時に自動テストを必ず走らせる設定にしておくと安心です。
3. 手動編集と自動生成を混ぜない
運用方法としては、大きく以下の2パターンがあります。
- 人間が直接requirements.txtを書く
小規模プロジェクトや、依存関係が少ない場合に向いています。 - 別の「入力ファイル」から、ツールでrequirements.txtを生成する
pip-toolsなどに代表される運用方式です。
| パターン | メリット | デメリット |
|---|---|---|
| 直接編集 | シンプルで学習コストが低い | 依存関係の管理がやや手作業になる |
| ツールで自動生成 | 依存関係の解決や更新が自動化できる | ツールの理解と導入が必要になる |
どちらの方式を採用するにせよ、「手動編集するファイル」と「自動生成されるファイル」をきちんと分けることが大切です。
自動生成したrequirements.txtを手で編集し始めると、再生成のたびに変更が失われてしまいます。
4. 小さなサンプルスクリプトで確認する
依存関係を整理した後、本当にインストールできるかを確認するために、小さなPythonスクリプトでimportテストをするのも有効です。
# check_requirements.py
# requirements.txtに書いたパッケージが正しくインポートできるかをチェックする簡易スクリプト
import importlib
# 確認したいパッケージ名のリスト
packages = [
"requests",
"numpy",
"pandas",
]
def check_import(pkg_name: str) -> bool:
"""指定したパッケージがインポートできるか確認する関数です。"""
try:
importlib.import_module(pkg_name)
print(f"[OK] {pkg_name} はインポートできました。")
return True
except ImportError:
print(f"[NG] {pkg_name} はインポートできません。")
return False
def main() -> None:
"""全パッケージについてインポート確認を実施します。"""
all_ok = True
for pkg in packages:
if not check_import(pkg):
all_ok = False
if all_ok:
print("すべてのパッケージが正常にインポートできました。")
else:
print("インポートに失敗したパッケージがあります。requirements.txtを確認してください。")
if __name__ == "__main__":
main()
[OK] requests はインポートできました。
[OK] numpy はインポートできました。
[OK] pandas はインポートできました。
すべてのパッケージが正常にインポートできました。
このような簡易チェックを用意しておくと、環境構築に問題がないかを素早く確認できます。
まとめ
requirements.txtは、Python開発における環境構築の「設計図」かつ「再現レシピ」です。
パッケージ名とバージョン指定の基本を押さえ、pip freezeを使った最短生成や、開発・本番・テスト向けの分割運用を取り入れることで、環境差異によるトラブルを大きく減らせます。
また、仮想環境との組み合わせや、セキュリティ・互換性を意識したバージョン管理を行うことで、時間が経っても安定して動くプロジェクト運用が可能になります。
まずは小さなプロジェクトでrequirements.txtを作成し、紹介したベストプラクティスを少しずつ取り入れてみてください。
