FlaskをDockerで動かす
目標
前回Flaskで作成したAPIをDockerで動かします。具体的にはlocalhostからDockerコンテナ内にアクセスし、レスポンスを取得します。
ここではDockerを中心に説明するのでAPIのコードは下記を参考にお願いします。
注意としては下記の記事ではsqliteをインメモリで動かしているのでsqliteをファイルで動くように変更してください。参考
環境
- docker-version 18.09.1
イメージ
下記の図のようなイメージで作成します。
https://deparkes.co.uk/2018/03/02/simple-docker-flask-sqlite-api/
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" }