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

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

[かわさきしんじ,Insider.NET編集部]

Dockerfileの記述

 以下では、Docker for Windowsがインストール済みであること、VS CodeにDocker拡張機能がインストール済みであるものとする。Docker for WindowsではLinuxコンテナを使用する。

Docker拡張機能 Docker拡張機能

 Docker拡張機能をVS Codeにインストールすると、現在作成しているプロジェクトにDockerfileやdocker-compose.ymlなどを追加/編集したり、そこからDockerイメージを作成したり、コンテナを作成したりといったことを簡単に行えるようにしてくれる(ただし、今回はDocker Composeおよびdocker-compose.ymlファイルには触れない)。

 例えば、現在のプロジェクトにDockerfileを追加するには、コマンドパレットから[Docker: Add Docker files to Workspace]コマンドを実行する。これにより、プラットフォームの選択、アプリが使用するポートの指定などを行うダイアログが順次表示されるので、適当なものを選んでいく。Pythonでの指定例を以下に示す(ここでは、ポートをFlaskで作成したWeb APIがリッスンしている5000に明示的に変更している)。

[Docker: Add Docker files to Workspace]コマンドを実行
[Docker: Add Docker files to Workspace]コマンドを実行
[Select Application Platform]で[Python]を選択
[Select Application Platform]で[Python]を選択
アプリがリッスンするポートを指定
アプリがリッスンするポートを指定
Dockerfilesなどがプロジェクトに追加される
Dockerfilesなどがプロジェクトに追加される

Dockerfileなどを追加


 これにより、.dockerignore/docker-compose.debug.yml/docker-compose.yml/Dockerfileの4つのファイルが追加される。今回触るのは、このうちの.dockerignoreファイルとDockerfileの2つになる。前者はDockerの管理管轄外とするファイルを指定する。現在のプロジェクトに含まれるファイルの中で、イメージ作成時に除外するファイルを指定することになる。例えば、現在作成しているプロジェクトでは、.vscodeフォルダやDockerイメージの内容を記述するDockerfile自体などは必要ない。また、以下ではPython環境を含んだベースイメージを使ってDockerイメージを作成するので、仮装環境myenvも必要ないだろう。そうしたファイルやフォルダを指定するのに.dockerignoreファイルを使用する。ここでは、デフォルトの内容に末尾に「myenv」だけを追加しておこう。

node_modules
npm-debug.log
Dockerfile*
docker-compose*
.dockerignore
.git
.gitignore
README.md
LICENSE
.vscode
myenv


.dockerignoreファイルの内容

 DockerfileはDockerイメージを作成するのに必要な「命令」を記述する。Docker拡張機能がデフォルトで作成するDockerfileの内容を以下に示す(コメントは削除)。

FROM python:alpine

LABEL Name=todoapi Version=0.0.1
EXPOSE 5000

WORKDIR /app
ADD . /app

RUN python3 -m pip install -r requirements.txt
CMD ["python3", "-m", "todoapi"]


デフォルトで作成されるDockerfileの内容

 大ざっぱな説明をすると、FROM命令によりその後の命令で使用するベースイメージを指定している。LABEL命令は、そのイメージに追加するラベルを指定するもの。EXPOSE命令は、コンテナの実行時にリッスンするポートを指定する。上の画像ではポートに5000を指定したので、それがここに反映されている。WORKDIR命令はその後のADD命令などの実行時に使用する(イメージ/コンテナ内の)フォルダを指定する。ADD命令では転送元と転送先を指定して、転送元のファイルやフォルダを転送先となるイメージ/コンテナの該当箇所に追加する。上の例では、プロジェクト内のカレントディレクトリの内容をコンテナの「/app」に転送するという意味になる。RUN命令は、その内容を見れば分かる通り、作成するイメージ上で何らかのコマンドを実行する。CMD命令はコンテナ実行時に実行されるコマンドを記述する。

 ここでは、これを次のように修正した。

FROM python:3.6.5-alpine

RUN adduser -D todoapi
USER todoapi

WORKDIR /home/todoapi

#ENV FLASK_APP=todoapi
ENV TODOAPI_ENV=docker
ENV TODOAPI_REMOTE_DEBUG=on
ENV PATH $PATH:/home/todoapi/.local/bin

ADD --chown=todoapi:todoapi . ./
RUN pip install --user flask flask-sqlalchemy flask-restless flask-cors waitress
#RUN pip install --user -r requirements.txt

EXPOSE 5000
CMD [ "python", "main.py" ]


修正後のDockerfile

 FROM命令では、本稿で使用していたPython 3.6.5を使用するように指定している。ちなみに、Alpine Linuxは小サイズで、Dockerコンテナのサイズを小さくするためによく使われているディストリビューションだ。そのAlpine LinuxにPythonをインストールしたものをここではベースイメージとしている。

 「RUN adduser -D totoapi」と「USER todoapi」の2行で「todoapi」というユーザーを追加し、その後の命令を実行するユーザーを「todoapi」に指定している。また、作業ディレクトリは「/home/todoapi」とした。

 幾つかあるENV命令は、このイメージで使用する環境変数を指定するもの。既におなじみのFLASK_APPは指定しなくても大丈夫だ(「python main.py」でブートするため)。TODOAPI_ENVの値は「docker」にしている。これにより、前ページで見たアプリ構成でDockerConfigクラスが使われるようになる(後で確認してみよう)。TODOAPI_REMOTE_DEBUGは、この後、VS Codeからコンテナ内で実行されるコードをデバッグしてみる際に利用する(そのためのコードはまだないが、後述する)。最後のPATHは、pipコマンドでパッケージをインストールする際に「--user」オプションを指定して「ユーザーローカル」にインストールしているため、インストール先となる「/home/todoapi/.local」以下のbinディレクトリをパスに追加している。

 ADD命令では「--chown」オプションでファイル所有者をtodoapiユーザーにして、カレントディレクトリの内容を「/home/todoapi」以下に転送している。ここではWindowsで開発をしている一方で、使用するのがLinuxコンテナであることから、転送されるファイルのパーミッションが自動的に「755」(所有者は読み/書き/実行が可能で、他のユーザーは読み込み/実行だけが可能)になるが、todoitems.dbファイルには書き込みが必要なため、所有者をtodoapiユーザーとしている。

 その後のRUN命令では、pipコマンドでWeb APIで使用していたパッケージ群を指定して、インストールを行っている。「--user」オプションは、既に述べた通り、「/home/todoapi/.local」ディレクトリ以下にパッケージをインストールする指示だ(筆者がこのオプションなしでpipコマンドを実行したときに、パッケージをグローバルにインストールできなかったため)。

 ここではインストールするパッケージを明示しているが、開発環境では既にこれらをインストール済みのはずなので、「pip freeze > requirements.txt」コマンドを実行して、インストールされているパッケージを「requirements.txt」に列挙しておき、それらを「pip install -r requirements.txt」としてインストールするのも一般的に行われているので、コメントアウトした形でこれも書いてある(が、筆者が試していると、pylintなどコンテナの実行では不要なものがあったり、パッケージのビルドに失敗したりすることがあったため、ここでは必要なパッケージを直に指定している)。

 最後の2行については特に説明は不要だろう。ポート5000をリッスンすることと、コンテナ起動時に「python main.py」コマンドを実行することを指定している。

 次ページでは、このDockerファイルを基にイメージを作成して、コンテナを実行してみよう。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

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

メールマガジン登録

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