ペイの技術MEMO

文系大学生の技術メモ

FlaskをDockerで動かす

目標

前回Flaskで作成したAPIをDockerで動かします。具体的にはlocalhostからDockerコンテナ内にアクセスし、レスポンスを取得します。

ここではDockerを中心に説明するのでAPIのコードは下記を参考にお願いします。

注意としては下記の記事ではsqliteをインメモリで動かしているのでsqliteをファイルで動くように変更してください。参考

peei.hatenablog.com

環境

  • docker-version 18.09.1

イメージ

下記の図のようなイメージで作成します。

https://deparkes.co.uk/2018/03/02/simple-docker-flask-sqlite-api/ https://deparkes.co.uk/wp-content/uploads/2018/02/DockerFlaskSQLite_schematic.png

Dockerfile

app.py(API)と同じディレクトリDockerfileを作ります。

flask/
    ├ Dockerfile
    └ app.py

↓Dockerfile

FROM python:3.7-slim

COPY app.py /root/app.py

RUN pip install flask Flask-SQLAlchemy 

ENV FLASK_APP /root/app.py

CMD ["flask", "run", "-h", "0.0.0.0"]

FROM

Dockerイメージのベースになるイメージを指定します。イメージの取得はDocker Hubレジストリからできます。

Dockerfileはビルドする際にFROMで指定されているイメージをダウンロードしてから実行します。

今回の場合pythonのイメージを指定し、:3.7-slimタグを指定しています。

:以降はタグと呼ばれ、イメージのバージョンなどを指定します。

COPY

ホストマシン上のファイル、ディレクトリをDockerコンテナ内にコピーします。

今回はapp.pyにapiの処理を書いているので、Dockerコンテナ内のrootに配置します。

RUN

Dockerイメージビルド時に、Dockerコンテナ内で実行するコマンドです。

引数はターミナル等で書く感じで大丈夫です。APIはFlaskとsqlalchemyをpip installしないと動かないようになっているので、Dockerコンテナ内でも同じことをします。

ENV

Dockerコンテナ内で使える環境変数を指定します。

Flaskではローカルでapp.pyをflask runコマンドを使って動かしたい時export FLASK_APP = app.pyのようにエクスポートします。

そのため、Dockerコンテナ内でflask runを使用するにはENVに環境変数を指定しておく必要があります。(指定しなくても直接ファイルを動かすようにもできます。)

CMD

Dockerコンテナ内で実行するコマンドです。CMDは起動時に一度実行されるのでコンテナそのものを動かすコマンドと考えましょう。

上記のENVでflask runが使えるのでflask run -h 0.0.0.0を実行させるようにします。

CMDではRUNのように普通のターミナルに書くような感じでは書けなくて1つのコマンドを空白で分割し、配列形式で指定します。

flask runではDockerコンテナ自体を動かしているので、flask runだけでは動きません。最初のイメージの図で紹介したようにDocker内のホストを指定してあげます。

ビルドする

ではDockerfileをビルドしてイメージを作成してみます。

docker build -t flask_docker .

ビルドするにはdocker buildをします。

オプションの-tはビルドが成功した後にリポジトリ名をつけるときに指定します。なので上記の場合はflask_dockerというリポジトリ名ができます。

末尾の.はDockerfile配置ディレクトリのパスを指定します。

ビルドすると以下のようにステップ実行されてる内容がステップ毎にわかります。

Step 1/5 : FROM python:3.7-slim
 ---> 6ba8638f69d7
Step 2/5 : COPY app.py /root/app.py
 ---> Using cache
 ---> ef6c6d4ab332
Step 3/5 : RUN pip install flask Flask-SQLAlchemy
 ---> Using cache
 ---> 01e50e93be98
Step 4/5 : ENV FLASK_APP /root/app.py
 ---> Using cache
 ---> 592afeb1b548
Step 5/5 : CMD ["flask", "run", "-h", "0.0.0.0"]
 ---> Using cache
 ---> 8f6c2251f151
Successfully built 8f6c2251f151
Successfully tagged flask_docker:latest

docker imagesコマンドでイメージが作成されてるのを確認しましょう。

コンテナの起動

ビルドし、イメージができたのでコンテナを起動してみます。

docker run -p 5000:5000 -it flask_docker

コンテナを実行するにはdocker runコマンドを使用します。

-pではポートを指定しています。ホスト5000番からDocker内で動かしているFlaskの5000番にアクセスします。参考

-itで先ほど作成したイメージのリポジトリ名を指定しています。

APIを叩く

コンテナが起動したので、違うターミナルに移動してAPIを叩いてみます。

http localhost:5000/users

HTTP/1.0 200 OK
Content-Length: 3
Content-Type: application/json
Date: Fri, 26 Apr 2019 14:33:40 GMT
Server: Werkzeug/0.15.2 Python/3.7.3

[]

http localhost:5000/users name=hoge

HTTP/1.0 201 CREATED
Content-Length: 23
Content-Type: application/json
Date: Fri, 26 Apr 2019 14:34:31 GMT
Server: Werkzeug/0.15.2 Python/3.7.3

{
    "id": 1,
    "name": "hoge"
}

参考

DockerコンテナでFlaskを起動し, JSONデータのPOSTとGET - Qiita

Simple Docker Flask SQLite API - deparkes