連載
» 2018年09月06日 05時00分 公開

Visual Studio Codeで始めるPythonプログラミング:VS CodeとPythonとDockerでWeb APIをコンテナ化! (3/3)

[かわさきしんじ,Insider.NET編集部]
前のページへ 1|2|3       

Dockerイメージの作成

 Dockerfileの記述が終わったら、これを基にイメージを作成する。これにはターミナルから「docker build ……」コマンドを実行してもよいが、Docker拡張機能をインストールしていれば、Dockerfileを開いたエディタ内でどこかを右クリックして、コンテキストメニューから[Build Image]を選択するのが簡単だ(コマンドパレットには[Docker: Build Image]コマンドもある)。すると、Dockerイメージのイメージ名とタグ名を指定するダイアログが表示されるので、適当なものを入力して(ここではデフォルトの「todoapi:latest」のままとした)[Enter]キーを押せば、イメージが作成される。

コンテキストメニューから[Build Image]を選択
コンテキストメニューから[Build Image]を選択
イメージとタグを指定して(ここではデフォルトのまま)、[Enter]キーを押す
イメージとタグを指定して(ここではデフォルトのまま)、[Enter]キーを押す

Dockerイメージの作成


 これにより、ターミナルが新規に開かれ、そこで「docker build」コマンドが実行される。作成したイメージは、アクティビティーバーの[Docker]アイコンをクリックして、[Docker Explorer]ビューを表示すると、その[Images]の下に一覧される。

[Docker Explorer]ビュー [Docker Explorer]ビュー

 ベースイメージの「python:3.6.5-alpine」と「todoapi:latest」の2つが[Images]の下にあることが分かる。

コンテナの起動

 コンテナの起動には、「todoapi:latest」を右クリックして、コンテキストメニューから[Run]または[Run Interactive]を選択する。ここでは[Run Interactive]を選択してみた。

コンテナの実行 コンテナの実行

 これにより、ターミナルが新規に開き、「docker run」コマンドが実行される。

VS CodeからDockerコンテナを起動したところ VS CodeからDockerコンテナを起動したところ

 この画像を見ると分かるが、[Docker Explorer]ビューの[Containers]の下には、「todoapi:latest」イメージから作成したコンテナが表示されている。また、ウィンドウ右下にはターミナルが開かれ、そこで「docker run」コマンドが実行されている。実際にDockerコンテナでコードが実行されているかを調べるために、ブラウザで「localhost:5000」にアクセスした結果を以下に示す。

環境変数TODOAPI_ENVの値を参照した結果、DockerConfigクラスで構成された値が表示された 環境変数TODOAPI_ENVの値を参照した結果、DockerConfigクラスで構成された値が表示された

 Dockerfileでは環境変数TODOAPI_ENVの値を「docker」に指定していた。これにより、config.pyファイルで定義したDockerConfigクラスを利用して、__init__.pyファイルの「app.config.from_object」メソッドが実行されたことで、ブラウザには「configured by DockerConfig in config.py」というメッセージが表示されている。前回に見た、from_objectメソッドと環境変数を組み合わせ、さらにインスタンスフォルダを使用することで、アプリを実行する環境に合わせた構成を行う一例として見てほしい。

 また、[Docker Explorer]ビューでは、今見たようなイメージからコンテナを起動したり、イメージを削除したり、あるいはコンテナを再起動したり停止したり、削除したり、起動中のコンテナのシェルにアタッチしたりといった操作が可能なので、便利に使ってみてほしい。特にコンテナを多数作った後で削除するのが面倒という場合は、[Docker Explorer]ビューの右上にある[System Prune]ボタンでまとめて削除できるので、覚えておこう。

VS Codeでコンテナ内で実行されているコードをリモートデバッグ

 最後に、VS Codeからコンテナ内で実行されているPythonコードをリモートデバッグする方法についても簡単に見ておこう。

 これには、ptvsdパッケージが必要になる。また、以下ではデバッグ構成を行うのに、[Python Experimental]を利用する。利用したptvsdのバージョンは4.1.1だ。

 まずは「pip install ptvsd」を実行して、開発環境にptvsdパッケージを追加しておく。Dockerfileでpipコマンドを実行している行でも同様な変更を行っておく。また、リモートデバッグで使用するポートもリッスンするようにしておこう。

# ……省略……
RUN pip install --user flask flask-sqlalchemy flask-restless flask-cors waitress ptvsd
# ……省略……
EXPOSE 5000 3000
# ……省略……


ptvsdもインストールし、デバッグで使用するポートもリッスンするように、Dockerfileを変更

 main.pyファイルには次の行を追加した(強調書体の部分)。

from todoapi import app
from waitress import serve
import os
import ptvsd

if os.getenv("TODOAPI_REMOTE_DEBUG") == "on":
  ptvsd.enable_attach(address=("0.0.0.0", 3000))
  ptvsd.wait_for_attach()
  ptvsd.break_into_debugger()

if __name__ == "__main__":
  serve(app, host="0.0.0.0", port=5000)

変更後のmain.pyファイル

 ここでは環境変数TODOAPI_REMOTE_DEBUGが「on」の場合に(そのようにDockerfileでは指定していた)、ptvsdパッケージが提供するenable_attach関数でリモートデバッグを有効にし、wait_for_attach関数でプロセスにアタッチされるのを待機して、最後にアタッチされたらbreak_into_debugger関数で実行を中断している。開発環境では環境変数TODOAPI_REMOTE_DEBUGを定義しない、またはon以外に設定しておけば、上記のコードは実行されない。

 [デバッグ]ビューの歯車アイコンをクリックして、[環境の選択]ダイアログが表示されたら、[Python Experimental]を選択し、launch.jsonファイルを作成する。その後、「Python Experimental: Attach」という名前の設定項目を探して、以下のように修正をしておこう。

{
  "version": "0.2.0",
  "configurations": [
    // …… 省略 ……
    {
      "name": "Python Experimental: Attach",
      "type": "pythonExperimental",
      "request": "attach",
      "port": 3000,
      "host": "localhost",
      "pathMappings": [
        {
          "localRoot": "${workspaceFolder}",
          "remoteRoot": "/home/todoapi"
        }
      ]
    },
    // …… 省略 ……
  ]
}


修正後のlaunch.jsonファイル

 ポートは先ほど述べたように3000を指定する。pathMappings項目は、ローカルの開発環境とリモートの実行環境のディレクトリ構造が一致するように指定する。ここではlocalRoot項目には「${workspaceFolder}」つまりVS Codeで開いているフォルダを、remoteRoot項目にはDockerfileのWORKDIR命令で指定したディレクトリである「/home/todoapi」を指定している。

 変更後のDockerfileからイメージを再作成して(これにより、上記のptvsdパッケージのインストールや、main.pyファイルの変更が反映されたイメージが作成される)、コンテナを起動すると、コンテナはアタッチされるのを待機する。そこで、VS Codeの[デバッグ]ビューでデバッグ構成に[Python Experimental: Attach]を選択して、デバッグを開始する。アタッチが完了すると、次のようにif節の最後のbreak_into_debugger関数が終了した状態で実行が中断する。

プログラム起動時に実行を中断したところ プログラム起動時に実行を中断したところ

 本稿ではデバッグしたくなるほどのコードを書いていないので役には立たないが、このようにすることでDockerコンテナ内のコードのリモートデバッグも可能だ。ただし、ブレークポイントがうまく機能していないといった報告もWeb上では見かけたので、注意はしよう(ptvsdを活用したい方は、GitHubにあるptvsdリポジトリのIssuesなどを定期的に訪れるとよいだろう)。


 今回は、これまでの総まとめという感じで、Web APIをコンテナ化してみた。まだ他にも話題はあるが、VS Code+Flaskという組み合わせはここでいったんお終いとして、しばらくしたらまた別のネタでVS Code+Pythonの連載を続ける予定だ。

「Visual Studio Codeで始めるPythonプログラミング」のインデックス

Visual Studio Codeで始めるPythonプログラミング

前のページへ 1|2|3       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。