【Python】FlaskアプリケーションをDockerコンテナ内で実行できるように変換する

FlaskアプリケーションをDockerコンテナ内で実行できるように変換してみます。なお、Dockerコンテナ内で実行するようにアプリケーションを変換するプロセスをDockerize(Docker化)と言ったりします。

■環境

Windows10(DockerDesktopインストール済み)

docker version

Client:
Cloud integration: v1.0.22
Version: 20.10.12
API version: 1.41
Go version: go1.16.12
Git commit: e91ed57
Built: Mon Dec 13 11:44:07 2021
OS/Arch: windows/amd64
Context: default
Experimental: true

Server: Docker Engine - Community
Engine:
Version: 20.10.12
API version: 1.41 (minimum version 1.12)
Go version: go1.16.12
Git commit: 459d0df
Built: Mon Dec 13 11:43:56 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.12
GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.19.0
GitCommit: de40ad0

■ディレクトリを作成する

FlaskアプリケーションをDockerコンテナ内で実行できるように変換してみますが、その前にディレクトリを用意します。

今回は「C:\Users\user_(フォルダパス)」内に「app」というディレクトリを作成しました。

作成後、この「app」というディレクトリ内にさらに「src」というディレクトリを作成しました。

作成後、「src」というディレクトリ内に「server.py」というpyファイルを作成しました。作成したserver.pyを、コードエディタで開きます。

■コード

from flask import Flask

server = Flask(__name__)

@server.route('/')
def hello_test():
    return "こんにちは、世界。陽はまた昇る"

if __name__ == "__main__":
    server.run(host='0.0.0.0')

「from import」でflaskのFlaskを呼び出します。その後、serverという変数を定義し、__ name__変数をFlaskクラスに渡します。

次にserverに対して”/”というルートURLを関連付けします。その後にdef文を用いて今回はhello_test()という関数を定義します。関数が呼び出された時に実行する処理としては、returnとして、日本語の文字化けを返すというものです。

最後に「if __name__ == “__main__”:」を用いて、server.run()が実行されるようにします。

このコードをserver.pyに記述後、保存します。

次に「app」というディレクトリ内に「requirements.txt」を作成します。

■コード

Flask==1.1.1

作成後、コードエディタを開き、上記のコードを追加し、保存します。これでアプリケーションに必要なライブラリが追加されます。

追加後、「app」というディレクトリ内にDockerfileを作成します。

■コード

FROM python:3.8
WORKDIR /code
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ .
CMD ["python","./server.py"]

Dockerfileをコードエディタで開き、dockerがイメージを作成するために必要な命令を記述します。今回は「FROM」でpythonのバージョン3.8イメージを使用します。「WORKDIR」で、作業ディレクトリを設定します。今回は「code」ディレクトリを作成します。「COPY」でWORKDIRにrequirements.txtをコピーします。「RUN」で、pip install をキャッシュを利用せずに実行するために、「–no-cahe-dir」コマンドを付けます。これでrequirements.txtで定義されたライブラリがインストールされます。「COPY」でWORKDIRに「src」ディレクトリ内の全てをコピーします。

「CMD」でdockerがpythonを使用してコンテナ内の「./server.py」を実行します。

このコードをDockerfileに記述し保存します。

■イメージの構築する

保存後、イメージを構築するために、Windows10のコマンドプロンプトを起動します。

C:\Users\user_>cd app

起動後、上記のコマンドを入力し、Enterキーを押します。今回作成した「app」ディレクトリに移動します。

C:\Users\user_>docker build -t python-flask .

移動後、上記のコマンドを入力し、Enterキーを押します。今回は「python-flask」という名前のローカルDockerイメージを作成します。

[+] Building 8.5s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 189B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/python:3.8                                                      2.1s
 => [1/5] FROM docker.io/library/python:3.8@sha256:f8dd6cc493bb667f693293f69927ae7c5ebf430a88b9d384c0c3eeecc01be0  0.0s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 93B                                                                                   0.0s
 => CACHED [2/5] WORKDIR /code                                                                                     0.0s
 => CACHED [3/5] COPY requirements.txt .                                                                           0.0s
 => [4/5] RUN pip install --no-cache-dir -r requirements.txt                                                       5.9s
 => [5/5] COPY src/ .                                                                                              0.0s
 => exporting to image                                                                                             0.3s
 => => exporting layers                                                                                            0.2s
 => => writing image sha256:333294da8752fe9e9077855600c8b373f591a40bae2ba75df31db74ae5c23353                       0.0s
 => => naming to docker.io/library/python-flask                                                                    0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

Enterキーを押すと、構築が開始され、完了となります。

■コンテナの起動

完了後、コンテナを起動してみます。

C:\Users\user_\app>docker run -d -p 5000:5000 python-flask

起動する際は、今回は上記のコマンドを入力し、Enterキーを押します。runコマンドでpython-flaskの実行を行い、「-d」コマンドでコンテナをバックグラウンドで起動。「-p 5000:5000」コマンドでコンテナのポート5000を、Dockerホストのローカルポート5000にマップします。

Enterキーを押した後にWebブラウザを起動し、「http://localhost:5000/」と入力し、アクセスしましたが「このサイトにアクセスできません localhost で接続が拒否されました。」と出力され、アプリケーションが実行されませんでした。

Traceback (most recent call last):

  File "./server.py", line 1, in 

    from flask import Flask

  File "/usr/local/lib/python3.8/site-packages/flask/__init__.py", line 14, in 

    from jinja2 import escape

ImportError: cannot import name 'escape' from 'jinja2' (/usr/local/lib/python3.8/site-packages/jinja2/__init__.py)

アプリケーションが実行されいない原因を調べてみると「Docker Desktop」の方で、上記のエラーが発生していることが判明。このエラーを解決するために、「app」というディレクトリ内に作成した「requirements.txt」の内容を変更します。

■コード

Flask==2.1.0

FlaskV2.XXの新しいバージョンに更新するために、上記のコードを記述し、保存し、再度、イメージを構築してみることにしました。

C:\Users\user_\app>docker run -d -p 5000:5000 python-flask

構築後、再度上記のコマンドを入力し、Enterキーを押します。

Enterキーを押した後にWebブラウザを起動し、「http://localhost:5000/」と入力し、アクセスすると、今度はFlaskアプリケーションを実行することができました。

コメント

タイトルとURLをコピーしました