nikkie-ftnextの日記

イベントレポートや読書メモを発信

イベントレポート | 第29回 Pythonもくもく会 〜AzureにDockerイメージがBuild, Ship, Runできずハマりました。。〜 #mokupy

はじめに

だんないよ、nikkieです。
mokupyでDocker触ってきました。(そしてAzureとの絡み?で絶賛ハマっています 苦笑)

勉強会の概要

第29回 Pythonもくもく会 - connpass

主にPythonに関するやりたいことを各自持って来て、進めていく感じのゆるい会です。 もくもく開発をして情報共有したり、交流を深めることができればと思っています。 是非お気軽にご参加ください。(Python初心者の方でも大歓迎です!)

ゆるい感じが持ち味のもくもく会です。今回はデータ分析に取り組まれている方が多かった印象です。

取り組んだこと

FlaskのアプリケーションをDockerでデプロイする方法を身につける!

動機

  • もくもくする中でAzureのWebApps(Windows OS)にFlaskアプリケーションをデプロイする知見がたまってきたのですが、ロックインを感じるようになりました。-> Dockerイメージでデプロイしてみたくなったので今回取り組みました。
  • DockerFileのCMDにpython app.pyを指定する手順を多く見かけるのですが、これだと本番サーバではないというWARNING1が出るので、本番サーバとして動かす方法が知りたかったというのもあります。

以下に取り組みました。

  1. Hello WorldするだけのFlaskアプリケーションを本番サーバで動かすDockerイメージ作成
  2. 上記の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で動かず)
  • macOSLinuxの違いによる? ローカルにvagrantLinux環境構築したら今回のイメージは動く?
  • gunicornのDockerfileのサンプル探して見比べてみる
  • CMDにpython app.pyを指定しない方法でFlaskアプリケーションを動かすことがやりたいので、gunicorn以外の手段を探す

感想

Docker使っているのに、デプロイ先で動かないとは思いませんでした。
DockerのウリのはずのBuild, Ship, RunできなかったことでAzureに手を噛まれた感が否めませんが、
スキマ時間にちょこちょこ取り組んでみます。(解決したら一本LTできるでしょうし)
お昼の時間、FlaskとDjangoの違いの話が聞けたのが参考になりました。

運営者・参加者の皆さま、1日ありがとうございました。

脚注


  1. WARNING: Do not use the development server in a production environment.

  2. adduser -D が調べた範囲では出てこなかったのですが、adduserコマンドとuseraddコマンドはCentOSでは同じものだそうです 参考: https://hydrocul.github.io/wiki/commands/adduser.html