こんばんはエンジニアの眠れない夜です。
ディープラーニング用のAPIを作成してFlaskで作成した時に
「簡単にウェブに公開できたらいいのになー」と思うのですが、なかなかシックリ来るものがなかったので作りました。
「flask uwsgi nginx」という組み合わせのものは他にもググればたくさん出てくるのですが、私には使いづらかったです…(-_-;)
世界で一番使いやすいと個人的には思っているのでFlaskを公開したいと考えている人はぜひこちらをご利用ください!
Dockerで簡単デプロイ!flask-uwsgi-nginx の使い方
まずは動作確認をします。すでに作成済みのイメージを起動します。
docker run -p 80:80 registry.gitlab.com/sleepless-se/flask-uwsgi-nginx
http://localhost にアクセスして「Welcome to Flask!」と表示されればOKです。
この状態で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-nginx
でbuild
してイメージを作成します。
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-nginx
にmy_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をインストールたい場合はこちらから利用可能なバージョンを確認して、
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公開に使いたいところです。
GPU搭載の格安レンタルサーバーを発見!
ディスク容量、IOPS、ネットワーク料金コミコミで
AWSより最大80%も安く、一番安いマシンは月約7500円で利用できる!ディープラーニングを使った開発やサービス提供の敷居がグッと下がるはず。https://t.co/UoDQHHzGBb pic.twitter.com/yd1Wvk7u71
— エンジニアの眠れない夜 (@sleepless_se) April 18, 2019
最後に
後半少し話しがそれてしまった気もしますが、こんな感じでとっても簡単にFlaskをインターネットに公開することができるようになりました。
Flaskでアプリを作っていて「あれ?これどうやって公開するんだったかな…?」
「前にもやったことあるのにuWSGIとNginxの設定がうまくいかないぞ…(;´Д`)?」
と、悩みに悩んだ末に作り出したflask-uwsgi-nginx の紹介でした。
これでこの先、一生、Flaskの公開で悩まなくて済みそうです。
環境設定はプログラミングとはまた違って、これがなかなか大変…
特にLinuxとかサーバー関係が得意ではない人には辛いところ…
ブログとか見ながらやってもうまくいかないぞ!!なんてことがよくあるので
こうして環境をまるごと配布・再現・再利用できるってDockerって凄いですよね。
flask-uwsgi-nginx がこの記事を読んでくれている方のお役に立てれば幸いです。
最後まで読んでいただきありがとうございました。
[…] 【Docker】flask-uwsgi-nginx で簡単にアプリを公開 […]