【Docker】flask-uwsgi-nginx で簡単にアプリを公開

【Docker】flask-uwsgi-nginx で簡単にアプリを公開

こんばんはエンジニアの眠れない夜です。

ディープラーニング用のAPIを作成してFlaskで作成した時に

「簡単にウェブに公開できたらいいのになー」と思うのですが、なかなかシックリ来るものがなかったので作りました。

flask-uwsgi-nginx

「flask uwsgi nginx」という組み合わせのものは他にもググればたくさん出てくるのですが、私には使いづらかったです…(-_-;)

世界で一番使いやすいと個人的には思っているのでFlaskを公開したいと考えている人はぜひこちらをご利用ください!

Dockerで簡単デプロイ!flask-uwsgi-nginx の使い方

flask-uwsgi-nginx

まずは動作確認をします。すでに作成済みのイメージを起動します。

docker run -p 80:80 registry.gitlab.com/sleepless-se/flask-uwsgi-nginx

http://localhost にアクセスして「Welcome to Flask!」と表示されればOKです。

Welcome to Flask!

この状態でFlaskがuWSGIとNginxを経由して動いていることが確認できました。

Flaskを自分のプログラムに書き換える

まずはこちらからcloneします。

clone repository git clone git@gitlab.com:sleepless-se/flask-uwsgi-nginx.git

api.pyというファイルがflask-uwsgi-nginxに入っていることが確認できます。これがFlaskの本体です。

あとはこのapi.pyを自分好みに書き換えるだけです。

(こういうのが欲しかったんですよね… 無かったのか、見つけられなかったのか、なんなのか…)

オリジナルのFlaskをウェブに公開!

ここはDockerの使い方なので普通です。

まずはflask-uwsgi-nginxbuildしてイメージを作成します。

docker build -t HUB_USER/REPO_NAME:TAG .

※ HUB_USER REPO_NAME TAG は自分のものに置き換えてください。DockerHubの使い方はこちらの記事が参考になります。

作成したイメージをDockerHubにpushします。

docker push HUB_USER/REPO_NAME:TAG

いよいよサーバーに公開です。

プライベートでDockerHubにpushした場合は、docker login でDockerHubにログインします。

先程pushしたイメージを起動すれば完了です!

docker run -p 80:80 HUB_USER/REPO_NAME:TAG

ちゃんと公開できているかを確認します。

http://サーバーのIP or ドメイン にアクセスします。

自分のFlaskの内容が確認できれば公開成功です!

flask-uwsgi-nginxの詳細設定

flask-uwsgi-nginxは最小構成なので自分のFlaskアプリケーションを組み込むには上の説明だけじゃわからないぞ…(-_-;)

という方向けにもう少し詳しい設定方法を紹介していきます。

モジュール、アプリケーションをインストール

一番気になるのはモジュールやアプリケーションのインストールですよね。

flask-uwsgi-nginx/Dockerfileを開いてみてください。

アプリケーションをインストールしたい場合は4行目に続けてインストールしたいアプリケーションを追加します。

RUN apt update && apt install -y nginx python-pip
RUN apt update && apt install -y nginx python-pip vim #←こんな感じ

※ 正しいDockerfileの書き方的に続けて書くのは少し邪道ですが、後ろに続けて書いたほうがミスしづらいと思います。

pipでモジュールをインストールしたい場合も同じです。5行目に続けて欲しいモジュールを追加するだけです。

RUN pip install --upgrade pip && pip install uwsgi flask supervisor

え?requirements.txtは使えないのかって?

8行目に下記のコードを追加して、flask-uwsgi-nginx/requirements.txtを作成してください。

RUN pip install --upgrade pip && pip install -r /app/requirements.txt

あとは使いたいモジュールをrequirements.txtに書くだけです。

※ 7行のCOPY . /appする前に実行するとfile not foundと怒られます。

Flaskアプリのファイル名を変更したい場合

デフォルトではapi.pyがuWSGIで起動するようになっています。

ファイル名を変更してしまうとうまくアプリが動かなくなる…

という方は起動するFlaskアプリのファイル名を変更できます。

編集する場所はたった一箇所で、flask-uwsgi-nginx/uwsgi.iniの2行目の

wsgi-file=/app/api.py

を自分のFlaskファイルのパスを書き換えるだけです。

flask-uwsgi-nginxの中身がコンテナの中のappに全部コピーされます。

my_flask.pyというファイルを起動したい場合はflask-uwsgi-nginxmy_flask.pyを保存して、こんな感じに書き換えるだけです。

wsgi-file=/app/my_flask.py

後はbuildしなおせばmy_flask.pyが起動します。

ファイルをflask-uwsgi-nginxに保存して、uwsgi.iniを編集するだけなのでとても簡単です。

Flaskアプリの公開ポートを変更

デフォルトではポート80番を使っているので他のポートに変更したい!

そういうこともありますよね。Dockerコマンドの範疇ですが一応解説をすると、コンテナを移動するときの-p ホストのポート:コンテナのポートのホストのポートを変更するだけです。

試しにこれを

docker run -p 80:80 registry.gitlab.com/sleepless-se/flask-uwsgi-nginx

ポート5000番で起動するならこう書き換えるだけです。

docker run -p 5000:80 registry.gitlab.com/sleepless-se/flask-uwsgi-nginx

http://localhost:5000 にアクセスして「Welcome to Flask!」と表示されればOKです。

※ ローカル環境で起動した想定です。サーバーの場合はlocalhostをサーバーのIPアドレスに置き換えてください。

Pythonのバージョンを変えたり、機械学習用に使う場合

デフォルトではubuntu:19.04を利用しています。

1行目FROM ubuntu:19.04

Pythonのバージョンを確認して見ると2.7なのでバージョン3を使いたいところ…

python -V
Python 2.7.16

純粋にPythonをインストールたい場合はこちらから利用可能なバージョンを確認して、

Python-dockerhub-version-list

Dockerfileの1行目をFROM python:3.7.3に変更します。

これでビルドし直すだけでpython:3.7.3をデフォルトで利用できるようになります。

TensorflowやKerasを使いたい場合

pipでインストールしても良さそうな気がしますがDockerイメージが公開されているのでそちらを使いたい場合はFROM tensorflow/tensorflowをベースにイメージにします。

tensorflow/tensorflowのタグはいろいろあるのでお好みで選んでください。
tensorflow/tensorflow:latest-py3
tensorflow/tensorflow:latest-gpu-py3
tensorflow/tensorflow:latest-py3-jupyter

FROM tensorflow/tensorflowをベースイメージにすると機械学習に使いそうなモジュールがいろいろインストールされているので便利です。後はPythonと機械学習のライブラリとの互換性の心配も少なくて済みます。

例えばlatest-py3-jupyterにはこれらのモジュールがインストールされています。

pip freeze
absl-py==0.7.1
astor==0.7.1
attrs==19.1.0
backcall==0.1.0
bleach==3.1.0
cycler==0.10.0
decorator==4.4.0
defusedxml==0.6.0
entrypoints==0.3
enum34==1.1.6
gast==0.2.2
grpcio==1.20.1
h5py==2.9.0
ipykernel==5.1.0
ipython==7.5.0
ipython-genutils==0.2.0
ipywidgets==7.4.2
jedi==0.13.3
Jinja2==2.10.1
jsonschema==3.0.1
jupyter==1.0.0
jupyter-client==5.2.4
jupyter-console==6.0.0
jupyter-core==4.4.0
jupyter-http-over-ws==0.0.6
Keras-Applications==1.0.7
Keras-Preprocessing==1.0.9
kiwisolver==1.1.0
Markdown==3.1
MarkupSafe==1.1.1
matplotlib==3.0.3
mistune==0.8.4
mock==2.0.0
nbconvert==5.5.0
nbformat==4.4.0
notebook==5.7.8
numpy==1.16.3
pandocfilters==1.4.2
parso==0.4.0
pbr==5.2.0
pexpect==4.7.0
pickleshare==0.7.5
prometheus-client==0.6.0
prompt-toolkit==2.0.9
protobuf==3.7.1
ptyprocess==0.6.0
Pygments==2.3.1
pyparsing==2.4.0
pyrsistent==0.15.1
python-dateutil==2.8.0
pyzmq==18.0.1
qtconsole==4.4.3
Send2Trash==1.5.0
six==1.12.0
tensorboard==1.13.1
tensorflow==1.13.1
tensorflow-estimator==1.13.0
termcolor==1.1.0
terminado==0.8.2
testpath==0.4.2
tornado==6.0.2
traitlets==4.3.2
wcwidth==0.1.7
webencodings==0.5.1
Werkzeug==0.15.2
widgetsnbextension==3.4.2

めっちゃいろいろ入ってます…(;´∀`)

Kerasはデフォルトだとこれだけなので、pipで追加してください。

Keras-Applications==1.0.7
Keras-Preprocessing==1.0.9

GPU環境を使ってtensorflow/tensorflow:latest-gpu-py3から動かす方法はまだよく分かっていないので理解できたらまた書きます。

GPUEaterというサービスがあって、ここならGPU搭載マシンを月7500円〜動かせるのでディープラーニングのAPI公開に使いたいところです。

最後に

後半少し話しがそれてしまった気もしますが、こんな感じでとっても簡単にFlaskをインターネットに公開することができるようになりました。

Flaskでアプリを作っていて「あれ?これどうやって公開するんだったかな…?」

「前にもやったことあるのにuWSGIとNginxの設定がうまくいかないぞ…(;´Д`)?」

と、悩みに悩んだ末に作り出したflask-uwsgi-nginx の紹介でした。

これでこの先、一生、Flaskの公開で悩まなくて済みそうです。

環境設定はプログラミングとはまた違って、これがなかなか大変…

特にLinuxとかサーバー関係が得意ではない人には辛いところ…

ブログとか見ながらやってもうまくいかないぞ!!なんてことがよくあるので

こうして環境をまるごと配布・再現・再利用できるってDockerって凄いですよね。

flask-uwsgi-nginx がこの記事を読んでくれている方のお役に立てれば幸いです。

最後まで読んでいただきありがとうございました。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください