必要最低限のrequirements.txtを作成する

シチュエーション

Pythonでつくったサーバーアプリを環境へのデプロイするために、依存モジュールのバージョンを固定したrequirements.txtを作りたいけど、開発環境のPython環境がだいぶ使い古しで、試しに導入した不要なモジュールもあるので、単純にpip freezeしちゃうと余計なモジュールが大量に混ざってしまう…なんてときの対処法。

手順

Dockerできれいな仮想環境を作る

とりあえず、pyenvでPythonをインストールできる最低限の環境を作ります。導入するモジュールによっては追加が要るかも。

以下のようなDockerfileを作る。とりあえずUbuntu14ベースで作ってますが、他のディストロならもうちょっとシンプルになるかも。

FROM ubuntu:14.04

ARG http_proxy
ARG https_proxy

ENV http_proxy=${http_proxy:-} \
    https_proxy=${https_proxy:-}

RUN apt-get update && apt-get install -y \
    build-essential python git curl zlibc zlib1g-dev \
    libssl-dev libreadline-dev libbz2-dev libsqlite3-dev \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /root

RUN git clone https://github.com/yyuu/pyenv.git .pyenv
ENV PATH /root/.pyenv/bin:$PATH
RUN echo 'eval "$(pyenv init -)"' >> .bashrc

CMD ["/bin/bash", "-i"]

これを適当なディレクトリに置いてdocker buildします。

$ cd clean_pyenv # 上記Dockerfileがおいてあるディレクトリに移動
# 直接インターネットが見られる環境の場合
$ docker build -t clean_pyenv ./
# プロキシが必要な場合
$ docker build --build-arg http_proxy=$http_proxy --build-arg https_proxy=$https_proxy -t clean_pyenv ./

仮想環境内で、pyenvを使ってターゲットバージョンのPython環境を作る

上記で作ったDockerイメージにはpyenvがインストール済みなので、これを使って必要な環境を作っていきます。 コンテナを起動してログイン、pyenv installで目的のバージョンをインストールして切り替えます。

$ docker run -it --rm clean_pyenv
$ pyenv install 2.7.13
$ pyenv global 2.7.13

アプリから直接参照しているモジュールのリストを用意してpip install -rした後、pip freezeする

例として、アプリから直接参照している外部モジュールがboto3 1.4.4だけだとします。 (モジュールがたくさんあるようであれば、列挙したテキストファイルを別のターミナルからdocker cpで送り込んであげればよいです。モジュールバージョンが最新でよければ、バージョン番号は省略でもOK)

$ echo boto3==1.4.4 > reqirements_part.txt
$ pip install -r reqirements_part.txt
$ pip freeze > requirements.txt

これで、依存モジュールも含むrequirements.txtが生成されるはずです。

途中間違えたら、コンテナからログアウトして終了してしまえば、pyenvだけのきれいな状態からやり直すことができます。もちろんDockerイメージは再利用可能。