はじめに
だんないよ、nikkieです。
mokupyでDocker触ってきました。(そしてAzureとの絡み?で絶賛ハマっています 苦笑)
勉強会の概要
主にPythonに関するやりたいことを各自持って来て、進めていく感じのゆるい会です。 もくもく開発をして情報共有したり、交流を深めることができればと思っています。 是非お気軽にご参加ください。(Python初心者の方でも大歓迎です!)
ゆるい感じが持ち味のもくもく会です。今回はデータ分析に取り組まれている方が多かった印象です。
取り組んだこと
FlaskのアプリケーションをDockerでデプロイする方法を身につける!
動機
- もくもくする中でAzureのWebApps(Windows OS)にFlaskアプリケーションをデプロイする知見がたまってきたのですが、ロックインを感じるようになりました。-> Dockerイメージでデプロイしてみたくなったので今回取り組みました。
- DockerFileのCMDに
python app.py
を指定する手順を多く見かけるのですが、これだと本番サーバではないというWARNING1が出るので、本番サーバとして動かす方法が知りたかったというのもあります。
以下に取り組みました。
- Hello WorldするだけのFlaskアプリケーションを本番サーバで動かすDockerイメージ作成
- 上記のDockerイメージをAzureにデプロイ
Hello World Dockerイメージ作成
Flask Mega Tutorialを参考に進めました。
The Flask Mega-Tutorial Part XIX: Deployment on Docker Containers - miguelgrinberg.com
Mega Tutorialを参考に作ったDockerfile2
# もととなる公式イメージ FROM python:3.6-alpine # アプリケーションを実行するためのユーザを作成(rootで実行するのはよくないとのこと) # -Dオプションはデフォルトの設定 RUN adduser -D microblog # アプリケーションがインストールされるデフォルトディレクトリ(microblogユーザのホームディレクトリを使っている) WORKDIR /home/microblog # Mega Tutorial作成者の好み(#7のコメント。python3とpip3というコマンドを使わなくてよくなる) COPY requirements.txt requirements.txt RUN python -m venv venv RUN venv/bin/pip install -r requirements.txt RUN venv/bin/pip install gunicorn COPY app app COPY microblog.py boot.sh ./ RUN chmod +x boot.sh ENV FLASK_APP microblog.py RUN chown -R microblog:microblog ./ USER microblog EXPOSE 5000 ENTRYPOINT ["./boot.sh"]
立ち入れていないですが、gunicornなるものでサーバを動かしているようです。
Hello WorldするだけのFlaskアプリケーションのファイル一式はこちら。
https://gist.github.com/ftnext/0d578da76d3d3d0adb60e18f5c02ddb9
docker run --name microblog -d -p 8000:5000 --rm microblog:latest
実行後、http://localhost:8000
へのアクセスでHelloWorldが確認できました。
DockerイメージをAzureにデプロイ
Web App on LinuxにDockerイメージをデプロイしました。
イメージをDockerHubにプッシュ。
https://hub.docker.com/r/ftnext/flask-azure-practice/
これを使ってWeb App on Linuxインスタンスを作ったのですが、
アクセスしてみると「Service Unavailable」_| ̄|○ il||li
(DockerのウリのはずのBuild, Ship, Runはいずこに。。。)
Kuduからログを見てみたところ./boot.sh: no such file or directory
2018-06-24 05:57:41.630 ERROR - Container start failed for nikkkie-flask-docker-practice_0 with System.AggregateException, One or more errors occurred.
InnerException: Docker.DotNet.DockerApiException, Docker API responded with status code=BadRequest, response={"message":"OCI runtime create failed: container_linux.go:296: starting container process caused \"exec: \\"./boot.sh\\": stat ./boot.sh: no such file or directory\": unknown"}
ローカルで実行できているのにAzureで実行できない理由がわからず、現在進行系でハマっています。。
原因がどこにあるかも切り分けられていないので、試してみたいことを書き出しておきます。(一部はもくもく会中で試しました)
- 別の端末(Mac)で同じイメージをdocker pullしても発生するのか? それともAzureでのみ発生?(AWSでは?)
- boot.shの実行の仕方に問題がある? -> (
ENTRYPOINT ["boot.sh"]
ではローカルで動かず(デプロイせず)、ENTRYPOINT ["/home/microblog/boot.sh"]
ではAzureで動かず) - macOSとLinuxの違いによる? ローカルにvagrantでLinux環境構築したら今回のイメージは動く?
- gunicornのDockerfileのサンプル探して見比べてみる
- CMDに
python app.py
を指定しない方法でFlaskアプリケーションを動かすことがやりたいので、gunicorn以外の手段を探す
感想
Docker使っているのに、デプロイ先で動かないとは思いませんでした。
DockerのウリのはずのBuild, Ship, RunできなかったことでAzureに手を噛まれた感が否めませんが、
スキマ時間にちょこちょこ取り組んでみます。(解決したら一本LTできるでしょうし)
お昼の時間、FlaskとDjangoの違いの話が聞けたのが参考になりました。
運営者・参加者の皆さま、1日ありがとうございました。
脚注
-
WARNING: Do not use the development server in a production environment.↩
-
adduser -D が調べた範囲では出てこなかったのですが、adduserコマンドとuseraddコマンドはCentOSでは同じものだそうです 参考: https://hydrocul.github.io/wiki/commands/adduser.html↩