【Python】Poetryでパッケージ管理 on Docker Container
DockerでPython開発する時、パッケージ管理はpip install -r requirement.txt
で行なっていましたが、
requirement.txtのみではパッケージ同士の依存関係まで管理できないことが問題でした。
そこで、Poetryを使ってみることにしました。
使用技術
- Python 3.7.3 - Docker 19.03.1 - poetry 0.12.17
ディレクトリ構成です。 今回は、Djangoプロジェクトをappというコンテナに、DBをdbというコンテナで管理することにしました。
poetry.lockとpyproject.tomlをどこに入れるか迷いましたが、Pythonのコードを管理しているapp配下に。
環境関連は全てdocker以下に!ということでdocker/appに入れてみたのですが、新しいパッケージを導入したいと思うたびに
appからdockerに移動しないといけないのが面倒だと気づいてしまいました汗
Dockerコンテナに入って開発する際にworkdirがapp以下になるだろうということで、 app以下にこの2つを置いてpoetryの操作をしやすいようにしました。
ディレクトリ構成
├── app │ ├── poetry.lock │ ├── project │ │ ├── config │ │ │ ├── __init__.py │ │ │ ├── manage.py │ │ │ ├── settings │ │ │ │ ├── __init__.py │ │ │ │ └── base.py │ │ │ ├── urls.py │ │ │ └── wsgi.py │ │ ├── manage.py │ │ ├── sample_app │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── apps.py │ │ │ ├── migrations │ │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ ├── urls.py │ │ │ └── views.py │ │ └── tests │ │ └── __init__.py │ └── pyproject.toml ├── docker │ ├── app │ │ ├── Dockerfile │ │ └── start-server.sh │ ├── etc │ │ └── gunicorn.conf │ ├── db │ │ └── Dockerfile │ └── var │ └── log │ └── gunicorn └── docker-compose.yaml
PythonコンテナのDockerfileです。
poetryのインストールのみにとどめ、
poetry install
やアプリケーションサーバーの立ち上げは
独自にシェルスクリプトを作成して、そちらに実行させることにしました。
Dockerfile
FROM python:latest ENV PYTHONUNBUFFERED 1 LABEL maintainer "sample_name <hogehoge@example.com>" RUN pip install --upgrade pip RUN pip install poetry
シェルスクリプトの中身をみましょう。
Dockerコンテナを立ち上げる際に下記のコマンドが実行されるようにしました。 serverも立ち上がるようにし、コンテナが立ち上がった後にlocalhost:8080にアクセスするとDjangoで作成した画面が見れ流ようにしました。
本番環境と開発環境で別コマンドが実行されるようにします。
#!/bin/bash cd /home/app # /home/app下にpoetry.lockとpyproject.tomlがあるのでインストールします。 poetry install cd project # poetry run [実行したいコマンド]でpipenvで作成される仮想環境でコマンドを実行します。 if [ "${DJANGO_ENV}" = 'production' ]; then # 本番環境 poetry run python manage.py migrate --settings config.settings poetry run python manage.py collectstatic --noinput poetry run gunicorn config.wsgi:application -c /home/docker/etc/gunicorn.conf -b :8080 else # 開発環境 poetry run python manage.py migrate poetry run python manage.py runserver 0.0.0.0:8000 fi
docker-compose.yaml
version: "3" services: app: build: context: ./docker/app dockerfile: Dockerfile env_file: .env environment: - POSTGRESQL_HOST=db - POSTGRESQL_PORT=5432 volumes: - ./app:/home/app - ./docker/app:/home/docker - ./docker/etc/gunicorn.conf:/etc/gunicorn.conf - ./docker/var/log/gunicorn:/var/log/gunicorn working_dir: /home/app entrypoint: "/bin/sh" command: "/home/docker/start-server.sh" ports: - "8080:8080" tty: true depends_on: - db db: build: context: ./docker/postgres dockerfile: Dockerfile env_file: .env ports: - 5432:5432 volumes: - ./docker/db/pgsql-data:/var/lib/postgresql/data
つづいて、操作方法について。
なんかしらPythonの操作したい
まずコンテナに入ります。
docker-compose exec app bash
poetryの仮想環境下で操作する必要があるので、
まずpoetry shell
でpoetryが作成する仮想環境に入ってからコマンドを実行
poetry shell [実行したいコマンド]
またはこちらで。 poetry runを頭につけると、poetryの仮想環境に入った状態でコマンドが実行される動きになります。
poetry run [実行したいコマンド]
新しくパッケージを導入したい
docker-compose exec app bash
# poetryにてインストール
poetry add [パッケージ名]
パッケージのバージョンをあげたい
docker-compose exec app bash
# 全部のパッケージをアップデートしたい時 poetry update # 特定のパッケージのみアップデートしたい時 poetry update [パッケージ名]
リポジトリはこちら。
おまけ。Pipenv編リポジトリ
(やることはあまり変わらなかった)