vscodeとDevContainerでらくらく開発環境構築(Python)

この記事で紹介すること

Dockerコンテナ内でPython開発をするための必要なことを紹介します。
具体的には

  • Dockeコンテナ内でファイルを同期する方法
  • vscodeのDev Container拡張機能を利用して、コンテナ環境でvscode開発を行う方法
  • コンテナ内でPythonをDebug実行する方法
    などです。PythonフレームワークとしてFlaskを利用しています。

ディレクトリ構成

.
├── app
│   ├── Dockerfile
│   ├── app.py
│   ├── requirements.txt
│   └── templates
│       └── index.html
├── .devcontainer
│   └── devcontainer.json
├── .vscode
│   └── launch.json
├── docker-compose.yml
└── test

※testディレクトリは使用しません。

開発環境用イメージのビルドで利用するDockerfileを準備する

一旦これだけです。

FROM python:3.9
RUN pip install flask

Dockerコンテナでファイルを同期する方法

ローカルホストの特定のディレクトリをコンテナ内のディレクトリに同期するにはバインドマウントを利用します。
バインドマウントをでソースコードを配置しているディレクトリをコンテナにマウントすることで、
Dev Container利用時にコンテナ環境でのファイル操作をローカルと同期できるようになります。

docker-compose.ymlを作成する

現在はdocker-composeのバージョン指定は不要みたいですが、一応付けています。

version: '3.9'
services:
  app:
    container_name: flask_app
    build: ./app
    ports:
      - 8080:5000
    tty: true
    volumes:
      - ./app:/workspace
    working_dir: /workspace
    environment:
      - FLASK_APP=app
    # flaskアプリの起動コマンド
    # command: flask run --host=0.0.0.0

この部分で、ローカルのappディレクトリをコンテナの/workspaceディレクトリにバインドマウントしています。

    volumes:
      - ./app:/workspace

ここまででdocker-compose.ymlの存在するディレクトリで

docker compose up --build

を実行すれば、FlaskパッケージをインストールしたPythonコンテナが立ち上がります。 Dockerコンテナが無事に起動することを確認できたら、DevContainerの準備に入ります。

DevContainerのインストール

vscode拡張機能で"DevContainer"と検索し、画像の拡張機能をインストールします。 (Remote Developmentをインストールしても入ります。)

devcontainer.jsonを作成する

DevContainerではdevcontainer.jsonで各種設定を行うことで、起動したコンテナ内でvscodeでの開発ができるようになります。
今回使用したdevcontainer.jsonはこちらです。

{
    "name": "flask-container",
    "service": "app",
    "workspaceFolder": "/workspace",
    "dockerComposeFile": "../../docker-compose.yml",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
            ]
        }
    }
}

それぞれの値を解説していきます。

name値はvscodeで表示されるプロジェクト名(?)です。

"name": "flask-container",

このように表示されます。

service値は後述するdockerComposeFileで指定したdocker-compose内のサービス名を記載します。

"service": "app",

workspaceFolder値はプロジェクトのルートディレクトリを指定します。

workspaceFolder": "/workspace",

dockerComposeFile値はDevContainerで接続したいコンテナをビルドするdocker-compose.ymlを指定します。

"dockerComposeFile": "../../docker-compose.yml",

customizations値では、vscodeへの個別の設定や拡張機能を入れられるようです。

"customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
            ]
        }
    }

今回はPython拡張機能しか入れていませんが、vscodeのsettingsから設定できる値は結構入れられそうな雰囲気です。
github.com

DevContainerでコンテナ環境へ接続する

新規でvscodeのウィンドウを立ち上げます。
立ち上げたらCtrl + Pで検索窓を表示し、DevContainerと入力すると画像のようになるので、Open Folder in Container を選択します。

今回はdocker-composeでappディレクトリをビルド対象にしているため、DevContainerでappディレクトリを開きます。

コンテナ起動が成功し、DevContainerによる接続が成功すると以下のようになります(画像ではログを出力しています。)

この状態ですでにローカルPCのディレクトリとコンテナのディレクトリがバインドマウントできているため、コンテナ内で編集した内容がローカルPC側にも同期されます。

コンテナ環境でデバッグ実行する

コンテナ環境であっても、vscode拡張機能vscodeの標準機能などは利用できるため、設定を行うことでデバッグ実行もできるようになります。 以下はlaunch.jsonの設定値です。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "app.py",
                "FLASK_DEBUG": "1"
            },
            "args": [
                "run",
                "--no-debugger",
                "--no-reload",
                "--host=0.0.0.0"
            ],
            "jinja": true,
        }
    ]
}

launch.jsonについての解説は今回は割愛します(ほぼデフォルトから変えていません)。
launch.jsonがある状態でapp.pyからF5を押せば以下の状態になり、flaskアプリが立ち上がります。

この状態でブラウザからhttp://localhost:8080/にアクセスすると
ちゃんとデバッガがブレークポイントで止まってくれています。

コンテナのビルド時にrequirements.txtを読み込む

今回立ち上げたコンテナのDockerfileを以下のようにすることで、コンテナイメージをビルドする際にrequirements.txtからPythonパッケージをインストールできます。

FROM python:3.9
WORKDIR /workspace
COPY ./requirements.txt /workspace/
RUN pip install --no-cache-dir -r requirements.txt

作業ディレクトリなどの指定は必須ではありませんが、一応PCとマウントしているディレクトリにrequirements.txtが配置されるようにしています。 マウントしたディレクトリにrequirements.txtがあることで、コンテナ環境で出力したパッケージ情報をPC側にも共有できるため、git管理するのもやりやすくなると思います。

参考にしたもの

Udemyのこちらの講座を参考に各種設定などを行いました。
www.udemy.com

Dockerはなんとなく苦手意識があってあまり触ってこなかったんですが、今回基礎的な部分からいろいろ触れたのでこの講座を買ってよかったです。