0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#0123(2025/05/05)`requirements.in` を使ったアーキテクチャが異なる環境構築

Last updated at Posted at 2025-05-05

はじめに

Pythonプロジェクトでは、従来 requirements.txt のみを使って依存関係を管理しているケースが多いです。しかし、requirements.txt はトップレベル依存とサブ依存(再帰的に必要なライブラリ)が混在しており、バージョン固定や更新制御が難しいという課題があります。

本記事ではまず、requirements.in とは何か、なぜ導入するのかを解説し、その後に arm64環境とx86環境 双方で安定したビルドを行うための Dockerfile × pip-tools 構成をご紹介します。

requirements.in とは

  • トップレベル依存のみを記述するためのファイル。
  • 例: アプリが直接使う flaskrequests などを列挙。
  • サブ依存のバージョン固定やハッシュ管理は行わない。

requirements.in のサンプル

# requirements.in
flask>=2.0,<3.0        # Web フレームワーク
requests==2.28.1       # HTTP クライアント
pydantic               # バリデーションライブラリ
python-dotenv>=0.21.0  # 環境変数管理
  • トップレベル依存のみを記述するためのファイル。
  • 例: アプリが直接使う flaskrequests などを列挙。
  • サブ依存のバージョン固定やハッシュ管理は行わない。

メリット

  1. 可読性向上: 必要なライブラリだけが一覧化され、プロジェクトの依存構造が読みやすくなる。
  2. 再現性の強化: pip-compile コマンドで全依存を解決し、正確なバージョンを requirements.txt に出力できる。
  3. アップグレード管理: pip-compile -U で依存の一括アップデートが可能。

基本の流れ

# トップレベル依存を requirements.in に記述
echo "flask" > requirements.in
echo "requests" >> requirements.in

# 全依存を解決し、バージョン固定した requirements.txt を生成
pip-compile requirements.in

# ロックされた依存をインストール
pip-sync requirements.txt

1. アーキテクチャ対応の課題

近年、Apple M1/M2(arm64)やラズパイなどのarm64環境が普及しつつあります。一方で、従来のIntel/AMD(x86_64)環境も依然として広く使われています。これら両者で同じPythonアプリを再現性高く動かすには、依存パッケージのビルド・管理が大きな課題となります。

  • 依存ライブラリのバイナリ互換性: numpypillowなどにはプラットフォーム依存のWheelが存在し、バージョンによっては片方でのみビルドに失敗する場合があります。
  • 環境差異による不具合: 開発者のローカル環境(例:M1 Mac)とCI/CDランナー(例:x86_64)で挙動が異なることがあります。

これらを避けるために、ビルドタイミングでアーキテクチャを判別し、適切な依存セットをインストールできるようにします。


2. pip-toolsで依存関係を一元管理

pip-tools は、requirements.inrequirements.txt の2段階管理を可能にするツールです。

2.1 基本コマンド

# トップレベル依存を書く
echo "flask" > requirements.in

# 依存を解決しバージョン固定
pip-compile requirements.in

# 環境を同期(不要なパッケージを削除)
pip-sync requirements.txt
  • pip-compile: requirements.in に書かれたライブラリとその再帰的依存を解決し、バージョン付きで requirements.txt を生成
  • pip-sync: requirements.txt と完全に一致する環境に同期

2.2 アーキ対応ファイルの生成

# x86_64 用
pip-compile --output-file=requirements-x86.txt requirements.in

# arm64 用
pip-compile --output-file=requirements-arm64.txt requirements.in

これで、プラットフォームごとに最適化されたロックファイルを保持できます。


3. Dockerfileでプラットフォーム切り替え

TARGETARCHdocker buildxが渡すビルド変数)を利用して、アーキテクチャに応じた requirements-*.txt を選択します。

FROM python:3.10-slim

ARG TARGETARCH
ENV TARGETARCH=${TARGETARCH}
WORKDIR /app

# 共通の入力ファイル
COPY requirements.in .
# アーキ別のロックファイルを requirements.txt にリネーム
COPY requirements-${TARGETARCH}.txt requirements.txt

RUN pip install --upgrade pip \
    && pip install -r requirements.txt

COPY ./src /app
CMD ["python", "main.py"]

ビルド例

# x86_64 向け
docker buildx build --platform=linux/amd64 \
  --build-arg TARGETARCH=x86 \
  -t myapp:x86 .

# arm64 向け
docker buildx build --platform=linux/arm64 \
  --build-arg TARGETARCH=arm64 \
  -t myapp:arm64 .

4. CI/CD自動化のヒント

  • ワークフロー分岐: GitHub Actions などで matrix.platform: [linux/amd64, linux/arm64] を使い分け
  • ロックファイル更新: 両アーキ別に pip-compile を実行し、PRで一括レビュー
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        platform: [amd64, arm64]
    steps:
      - uses: actions/checkout@v3
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: 3.10
      - name: Generate lock
        run: |
          pip install pip-tools
          pip-compile --output-file=requirements-${{ matrix.platform }}.txt requirements.in

まとめ

  • requirements.in でトップレベル依存を整理し、pip-compile で再帰的にバージョンを固定
  • pip-sync でクリーンな環境を維持
  • docker buildxARG TARGETARCH によるプラットフォーム対応
  • CI/CD で自動化すれば、どのマシンでも同じビルド結果を得られる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?