Visual Studio Code Dev Containers で作るチーム開発しやすい Python 開発環境

今まで Python で個人開発をよくやっていて自分なりの開発環境ベストプラクティスみたいなのがあった。
その環境をチーム開発のプロジェクトに適用したらメンバーの環境によってローカル開発環境構築でつまずくということがあった。
Dev Containers を利用することでより少ない前提条件、環境に依存せずにローカル開発環境を作れそうだったので調査の備忘録。
課題
- Python のバージョン管理どうする?
- Python パッケージ管理何使う?
- Linter/Formatter 何使う?
- IDE の設定

目指すべきもの
より少ない前提条件の元、開発を開始できる状態を目指す。
git clone したらエディタ/IDE 開いたら開発できるぐらいになると嬉しい。
今回は vscode と Dev Containers インストールだけ前提条件として加える。

要件整理
より少ない前提条件の元、開発を開始できる状態とはどういう状態なのか整理する。
- より少ない前提条件
- Mac と vscode があれば誰でも数アクションで同じ開発環境ができるぐらいの条件
- Windows はチームメンバーにいないので考慮しない
- PyCharm やその他エディタを使いたい人もいるけど今回は vscode に限定する
- Python のバージョン管理
- poetry でパッケージ管理
- 素の pip(requirements.txt)はバージョン管理しづらいのでパッケージ管理ツールを導入したい
- pipenv でもいいけど個人的には linter/formatter ルールも管理できる poetry が好み
- poetry コマンドでライブラリを追加、更新できる
- 他の人が追加、更新した pyproject.toml, poetry.lock からライブラリを取り込める
- IDE で一般的なことができる
- ライブラリや自身のコードを参照できる(サジェスト、オートコンプリート、コードジャンプなど)
- linter/formatter が保存により機能する
- pylint
- flake8
- black
- isort
- mypy
- Pylance
- vscode の UI から pytest でテスト実行したり、結果確認したりできる
- デバッグ実行できる
- .ipynb ファイルを実行できる
- Notebook はデバッグ、サンドボックスに便利

Dev Containers とは
vscode の microsoft が提供する拡張機能。
vscode の開発環境をローカルコンテナ上に実行できる。
ローカル環境に依存しない、ローカル環境をあまり汚さない、低レイヤまで設定ファイルに落とし込むことができるなどのメリットがある。

Dev Container の設定方法
Dev Container はプロジェクトルートディレクトリに .devcontainer/devcontainer.json
ファイルを作成することでコンテナ起動&コンテナへの接続が可能となる。
設定ファイルに指定する項目一覧は以下にある。
中でも重要な設定は以下の通り。
.image
)
コンテナイメージ(ベースとなるコンテナイメージを指定する。
Docker Hub やその他レジストリにあるコンテナイメージを利用してもいいし、
microsoft が提供する Dev Container 用イメージを利用してもいい。
microsoft が提供するイメージ
コンテナイメージの指定以外にも Dockerfile や docker-compose.yml で指定する方法も用意されている。
.customizations.vscode.extensions
)
インストールする vscode 拡張機能(識別子を指定することでコンテナ環境の vscode に拡張機能をインストールする。
識別子は Python の拡張機能であれば ms-python.python
みたいなの。
.customizations.vscode.settings
)
vscode 設定(vscode に適用する設定。
普段の設定をそのまま貼り付けるだけ。
.forwardPorts
)
接続ポート(外部アクセスするのであればローカルとコンテナのポートを割り当てる。
.features
)
機能追加(指定することでコンテナにアプリケーションやツールなどをインストールする。
今回は利用しなかった。

今回構成したプロジェクト
開発の始め方
git clone git@github.com:s-fujimoto/python-dev-template.git
cd python-dev-template
code .
Reopen in Container
をクリックすればコンテナ環境が起動し、開発を開始できる状態になる。
構成説明
主に vscode、Dev Containers 関連ファイルについて説明します。
python-dev-template
├── .devcontainer
│ ├── devcontainer.json
│ └── postCreateCommand.sh
├── .python-env
├── .vscode
│ ├── extensions.json
│ └── launch.json
├── poetry.lock
├── pyproject.toml
└── src
│ └── app.py
└── tests
└── test_app.py
.devcontainer/devcontainer.json
- イメージは最新の 3.11系
- 初期設定は別ファイルでスクリプトにまとめた
- poetry インストール
- poetry 設定
- パッケージインストール
- vscode 設定
- 拡張機能と vscode 設定
.vscode/extensions.json
- Dev Containers をインストールしていない場合にインストール推奨
.vscode/launch.json
- flask の実行、デバッグできる設定
- flask 以外を開発する場合は修正が必要
.python-env
- プロジェクト内のコード参照先を
src
配下にしたかったので PYTHONPATH を指定

動作確認
Dev Containers 起動
Reopen in Containers
をクリックすると初期処理が始まる。
初回はコンテナイメージダウンロード、vscode 拡張機能インストール、Python ライブラリインストールなどがあるの数分かかる。
ログを表示していると、こんな出力が表示されるはず。
Python バージョン&ライブラリインストール確認
Terminal を起動する。
Python バージョンとインストールライブラリを確認する。
(python-dev-template-py3.11) vscode ➜ /workspaces/python-dev-template2 (main) $ python -V
Python 3.11.2
(python-dev-template-py3.11) vscode ➜ /workspaces/python-dev-template2 (main) $ pip list
Package Version
----------------- -------
(略)
Flask 2.2.3
(略)
ライブラリ参照
インストールした Flask の情報を参照できている。コードジャンプもできる。
Linter / Formatter
isort
src/app.py
の 2行目に import json
を加えて
from flask import Flask
import json
app = Flask(__name__)
保存すると
import json
from flask import Flask
app = Flask(__name__)
Black
src/app.py
の 8行目のインデントを 1つ下げて
def home():
return "Hello, Flask!"
保存すると
def home():
return "Hello, Flask!"
テスト
テスト UI に切り替えてテストファイルを開くと、
テストケースの表示と、テストケース毎のテスト実行ボタンが表示される。
実行するとテスト結果が反映される。
デバッグ
実行メニューから実行する
ブレイクポイントを張って、HTTP リクエストするとブレイクポイントで止まる
Notebook
.ipynb
ファイルを作成して開くと Notebook 形式の UI が表示される
Python コードを書いて実行できる。