はじめに
Docker上でPoetryの依存ファイルを使用した環境を構築したいと思い調査しました。
本記事はその手順の備忘録となります。
使用するプロジェクト
以下のプロジェクトを例に説明します。 詳細は割愛しますが、pythonでdashフレームワークを使用したwebアプリのプロジェクトになります。現状はpoetryコマンドで実行環境を構築できるようにしていますが、これをdocker環境でも構築できるようにします。
方針
作業ディレクトリにプロジェクトと同じフォルダ(dlSubscanStakingRewardsHistoryDash
)を構築します。
そして、Docker環境ではアプリケーションの実行で必要となる後述するソースコード類(パッケージ管理ファイルも含む)が格納されたフォルダ、および、ファイルをコピーして同期することにします。
フォルダ構成
ソースコードはapp
,ci
,test
フォルダに格納されています。
メインのプログラムはapp
フォルダ内のコードで、プロジェクト以下でpoetry run python app
を実行することでDash
フレームワークのWebアプリが起動します。
# 以下は一部記載を省略しています。 % tree -a -L 2 . ├── .DS_Store ├── .demofile ├── .git ├── .gitignore ├── .markdownlint.jsonc ├── .mypy_cache ├── .pre-commit-config.yaml ├── .ruff_cache ├── .venv ├── .vscode ├── Dockerfile ├── LICENSE ├── README.md ├── app │ ├── __init__.py │ ├── __main__.py │ ├── __pycache__ │ ├── assets │ ├── config.toml │ ├── config_manage.py │ ├── cryptact.py │ ├── dcc_manage.py │ ├── df_manage.py │ └── subscan.py ├── ci │ ├── run_git_tag_base_pyproject.py │ └── update_pyproject_version.py ├── docker-compose.yaml ├── poetry.lock ├── pyproject.toml ├── requirements-dev.txt ├── requirements.txt ├── scripts │ └── create_post-commit.sh └── tests ├── __init__.py └── test_cryptact.py
続けて方針に従いDockerfile
とdocker-compose.yaml
を作成します。
Dockerfile
# ベースとなるDockerイメージを指定 FROM python:3.10 # 作業ディレクトリを設定 WORKDIR / # APTパッケージインストール / パッケージアーカイブのキャッシュ削除 / パッケージリストのキャッシュ削除 # 日本語のロケールを指定 RUN apt-get update && \ apt-get -y --no-install-recommends install locales && \ localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ENV LANG ja_JP.UTF-8 ENV LANGUAGE ja_JP:ja ENV LC_ALL ja_JP.UTF-8 ENV TZ JST-9 # ターミナルエミュレーターにxtermを指定する ENV TERM xterm # Poetryのインストール ## https://python-poetry.org/docs/#installing-with-the-official-installer ### Linux, macOS, Windows (WSL) RUN curl -sSL https://install.python-poetry.org | python3 - # Poetryのパスをunix指定で設定 ## https://python-poetry.org/docs/#installing-with-the-official-installer ### Add Poetry to your PATH ENV PATH /root/.local/bin:$PATH # Poetryが仮想環境を生成しないようにする RUN poetry config virtualenvs.create false # 作業ディレクトリを/dlSubscanStakingRewardsHistoryDashに設定 WORKDIR /dlSubscanStakingRewardsHistoryDash # 依存関係のコピー COPY pyproject.toml poetry.lock ./ # 依存関係のインストール RUN poetry install # アプリケーションのコピー COPY ./app ./app COPY ./tests ./tests COPY ./ci ./ci COPY README.md .
補足: Dockerfile用のlinterについて
pre-commitではpre-commit hookとして以下のDockerfile linterが公開されています。
Dockerfileの構文や指定について指摘されるため、pre-commitを利用している場合は下記指定で使用できます。
実際に、Dockerfileはフックの結果を元に作成しています。個人的には有用だと感じました。
.pre-commit-config.yaml
# https://github.com/pryorda/dockerfilelint-precommit-hooks#usage - repo: https://github.com/pryorda/dockerfilelint-precommit-hooks rev: v0.1.0 hooks: - id: dockerfilelint stages: [commit]
docker-compose.yaml
# Docker Composeのバージョン指定 version: '3' services: # アプリケーションサービスの設定 app: # カレントディレクトリをベースにビルド build: . # コンテナの名前を指定 container_name: 'dlssrhd' # ターミナルの割り当てを有効にする tty: true # ボリュームのマウント設定 volumes: - ./app:/dlSubscanStakingRewardsHistoryDash/app - ./tests:/dlSubscanStakingRewardsHistoryDash/tests - ./ci:/dlSubscanStakingRewardsHistoryDash/ci - ./pyproject.toml:/dlSubscanStakingRewardsHistoryDash/pyproject.toml - ./poetry.lock:/dlSubscanStakingRewardsHistoryDash/poetry.lock - ./README.md:/dlSubscanStakingRewardsHistoryDash/README.md # ポートのマッピング ports: - 8050:8050 # アプリケーションの起動コマンド実行 command: ["poetry", "run", "python", "app"]
補足: docker compose ファイルが有効かどうかをチェックするpre-commit
pre-commitではpre-commit hookとして以下のdocker-pre-commitが公開されています。
docker-compose configコマンドを使用して、作成したdocker-compose.yamlについて環境変数の評価や、ファイルのインクルードなど、Composeファイルが正しく構成されているかどうかを確認するとができます。pre-commitを利用している場合は下記指定で使用できます。
実際に、docker-compose.yamlに適用し、指摘はありませんでしたが、docker-compose config
をpre-commitで実行できるので有用だと思います。
.pre-commit-config.yaml
# https://github.com/IamTheFij/docker-pre-commit#installation - repo: https://github.com/iamthefij/docker-pre-commit rev: v3.0.1 hooks: - id: docker-compose-check
Docker環境の構築
docker-compose up
でapp
サービスのdlssrhd
コンテナを起動する
処理の流れ
docker-compose up
コマンド実行:docker-compose up
コマンドを実行すると、Docker Composeは指定されたdocker-compose.yamlを読み込みます。
ベースとなるDockerイメージのダウンロード:
python:3.10
というベースイメージがなければ、このイメージをDocker Hubからダウンロードします。
Dockerfileのビルド:
- ダウンロードしたベースイメージを元に、指定されたDockerfileがビルドされます。
- ビルドの際には、各命令が順番に実行されます。
Poetryのインストール:
Poetryのパスの設定:
- インストールしたPoetryのパスを環境変数に追加します。
Poetryの仮想環境生成設定:
- Poetryが仮想環境を生成しないように設定します。
作業ディレクトリの変更:
- 以降の作業は、
/dlSubscanStakingRewardsHistoryDash
ディレクトリで行います。
- 以降の作業は、
依存関係のコピーとインストール:
pyproject.toml
とpoetry.lock
がコピーされ、Poetryを使用して依存関係がインストールされます。
アプリケーションのコピー:
./app
、./tests
、./ci
、README.md
がコピーされます。
ポートのバインドとコンテナの起動:
docker-compose.yaml
で指定されたポート8050
がホストマシンのポート8050
にバインドされ、dlssrhd
という名前のコンテナが起動されます。
Pseudo-TTYの割り当て:
tty: true
が指定されているため、コンテナ内で対話的なシェルを使用できるようになります。
docker-compose.yamlのcommandの指定:
docker-compose.yaml
でcommand: ["poetry", "run", "python", "app"]
の指定からデフォルトのコンテナ起動時のコマンドとして使用されます。
これにより、docker-compose up
コマンドによって、指定されたサービス(app
サービス)に基づいたコンテナが構築、起動され、アプリケーションが実行されます。
補足:CMD
とcommand
の使い分け
プロジェクトの運用方針にもよりますが、CMD
とcommand
の両方を使用する場合はdocker-compose.yaml
のcommand
が優先されるようなので、個人的にはcommand
でコマンド実行するのが良いと思います。
参考記事
CMDのみを使用する場合:
CMD ["poetry", "run", "python", "app"]
- コンテナが実行されるときに、何もコマンドが指定されなかった場合は
CMD
で指定されたコマンドが実行されます。
- コンテナが実行されるときに、何もコマンドが指定されなかった場合は
commandのみを使用する場合:
command: ["poetry", "run", "python", "app"]
docker-compose.yaml
のcommand
でコンテナの起動時のコマンドを上書きします。CMD
にコマンドの指定がある場合でも、docker-compose.yaml
のcommand
で指定したコマンドが優先されます。
CMDとcommandの両方を使用する場合:
CMD ["poetry", "run", "python", "app"]
command: ["poetry", "run", "python", "app"]
- この場合、
docker-compose.yaml
のcommand
が優先されます。
- この場合、
補足:コンテナの起動方法
参考記事
コンテナ一覧を表示
% docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5c41a6c6a8ca dlsubscanstakingrewardshistorydash-app "poetry run python a…" 5 hours ago Up 22 seconds 0.0.0.0:8050->8050/tcp dlssrhd
単一コンテナ起動: docker start "CONTAINER ID"
% docker start 5c41a6c6a8ca 5c41a6c6a8ca
複数コンテナ(アプリケーション)の起動: docker compose up
appサービスのdlssrhdコンテナを起動する
% docker compose up [+] Building 0.0s (0/0) docker:desktop-linux [+] Running 1/0 ✔ Container dlssrhd Created 0.0s Attaching to dlssrhd dlssrhd | Skipping virtualenv creation, as specified in config file. dlssrhd | Dash is running on http://0.0.0.0:8050/ dlssrhd | dlssrhd | * Serving Flask app '__main__' dlssrhd | * Debug mode: on # Ctrl+Cで停止 ^CGracefully stopping... (press Ctrl+C again to force) Aborting on container exit... [+] Stopping 1/1 ✔ Container dlssrhd Stopped 0.3s canceled # -d(デタッチドモード) でバックグラウンドでサービスを実行 % docker compose up -d [+] Building 0.0s (0/0) docker:desktop-linux [+] Running 1/1 ✔ Container dlssrhd Started
まとめ
実際のプロジェクトを例にPoetryを使用したDocker環境の構築方法について紹介しました。
環境構築について、プロジェクトではフォルダ構成を維持して、全てのファイルをコピーせず、必要なファイルをコピーしたかったので、実際に作成することで処理の流れを理解することができました。
Docker環境のインストールは必要ですが、実際にMacとWindows(WSL)でgitクローンしてdocker-compose up
コマンドを実行してwebアプリを起動できることを確認できました。
今後や他のプログラミング言語やDBと組み合わせたサービスについても、調査して作成してみたいと思います。
以上です。