エンジニア夫婦の技術日記

【Django】ローカルで作成したWebアプリをAzureにデプロイしてみる


2022年7月17日
Posted by 

以前の記事でご紹介した、家計請求額算出WebアプリをAzure App Seerviceにデプロイ出来ないという試みです。

結果

出来ました。躓いた部分もあったので学びは多かったです。

デプロイするまでの手順を綴ります。



参考サイト様

Anacondaを使った仮想環境の保存をする

@ozaki_physics

PythonのWebアプリをAzureにデプロイする

Youtubeより クラウドデベロッパーちゃんねる


目標

  1. Azure App Service にWebアプリをデプロイするという経験を得る
  2. 毎回サーバーを起動するという手順を省けるようにする

必須要件

  • 私だけ、あるいは私の自宅からだけアクセス出来るように制限を掛けられること

Step0.バックアップを取る

現在運用しているWebアプリのソースコードはローカルにのみありますが、
バージョン管理もしてなければバックアップも何も取っておりません。

つまり、もし壊れた時に取り返しがつきません。

そのため着手する前に一旦ソースコードのバックアップを取ります。

ひとまず、バックアップはローカルのDドライブ(HDD)に保存していきます。

Anacondaを使った仮想環境の保存

参考サイト様ではいくつかの方法を挙げてくださっておりますが、
今回どれが適しているか私が理解出来ていないため、
以下2点を実施します。

  1. conda envを使う方法
  2. condaを使う方法

djangoの仮想環境を立ち上げる

Anaconda Navigatorを起動して仮想環境を立ち上げます。

conda envを使う方法の手順を実施する

以下のコマンドで保存します。

conda env export

condaを使う方法の手順を実施する

以下のコマンドで保存します。

conda list --export

実ファイルの保存

念のためzip化して保存しておきます。


Step1.Azure Web Apps を作成する

Azureポータル画面から以下の順で画面遷移します。

リソースの作成 > Webアプリ

ここで、参考の動画と違う画面が表示されました。

F1プラン(無料枠)を使いたいので、恐らく「無料試用版から開始する」の方ですかね。

Azure の無料アカウント作成の画面が出てきました。
従量課金なしと書いているため、自動で有料版に切り替わってしまうということはなさそうです。

クレジットカード情報等諸々の情報を入力し、アカウント作成をしました。

その後再度ポータル画面から同じ順で遷移したところ、Webアプリの作成画面が表示されました!

Webアプリの設定をする

リソースグループ、Webアプリ名

どちらも

CardDetailCalculator

にします。

ランタイムスタック

現在使用しているpythonのバージョンを以下コマンドで調べたところ3.8.5だったため、
Python 3.8
を選択します。

python --version

地域

私は鹿児島に居るので
Japan West
にします。

スペックの選択

今のところ試験的にデプロイしてみるということのため「F1」(無料枠)を使います。

各設定内容

以下のキャプチャの通りです。

これで作成を実行!

エラー!

はい。上記設定ですとエラーが出て作成ができませんでした。

エラーの内容は以下の通りです。

{"code":"InvalidTemplateDeployment","details":[{"code":"ValidationForResourceFailed","message":"Validation failed for a resource. Check 'Error.Details[0]' for more information.","details":[{"code":"SubscriptionIsOverQuotaForSku","message":"This region has quota of 0 instances for your subscription. Try selecting different region or SKU."}]}],"message":"The template deployment 'Microsoft.Web-WebApp-Portal-11cb4ad3-8d32' is not valid according to the validation procedure. The tracking id is 'afef89ad-2049-4d83-8e6b-69c88982b206'. See inner errors for details."}

んー…?

This region has quota of 0 instances for your subscription. Try selecting different region or SKU.

クォータというのがよくわからないですが、違う地域を選択してみてくださいとありますね。

地域を変えてみる

Japan East

にしてみたところ、、、

いけた!!!

アクセスしてみる

お!チュートリアル画面のようなものが表示されましたね!
一旦これでF1プランのAzure App Servcieを作成できました!

アクセス制限の設定をする

次に、Azure ポータルからアクセス制限の設定をしてみます。

ネットワークサービス > アクセス制限

私のグローバルIPアドレスを許可するルールを追加したところ、
それ以外は許可しない設定が自動で追加されました!

試しにスマホからアクセスしてみる

試しに手元にあった私のスマホのWi-fiを切ってアクセス(別のグローバルIPアドレスからアクセス)してみたところ、
ちゃんと403権限エラーになりました!


Step2.ソースコードをGitに上げる

元々夫婦で共同開発している別のアプリがありまして、そちらはGit管理しています。

その際にSourceTreeというツールを使ってGitの操作を行っているため、
参考動画とは違いますがそのままSourceTreeで操作しようと思います。

リポジトリの作成

まずはGitHubにてリポジトリを作成します。

機微な情報が含まれるかもしれないので、今回はPrivateリポジトリにします。

リポジトリのクローン

以下の順でClone用のタブを開いてクローンしてきます。

SourceTree > 「+」タブ > Clone

クローン先のディレクトリに既存のソースコードをコピーして、コミットします。

その際、以下のディレクトリはgitに上げる必要が無いため、.gitignoreに設定します。

.vscode
__pycache__

.vscode
__pycache__

Step3.Azureデプロイセンターを設定する

ソースがGitに上がったので、Gitの状態をAzureにデプロイするためにデプロイセンターを設定します。

設定を保存する

GitHubを選びます。承認するボタンが出てきたので、GitHubのアカウントで承認します。

デプロイするリポジトリとブランチ名を設定して保存をすると、自動でデプロイが始まるようです。

…?

全然デプロイされないのですが…。

デプロイがされない原因を調査

そういえば、以下のファイルを作成していなかったです。

requirements.txt

どうやらAzureとGitHubを連携した際に登録されるGitHub Actionsのワークフローで、
以下コマンドを実行する仕組みになっているようです。

pip install -r requirements.txt

ファイルが無ければエラーになるのでこれが原因だと思い、
以下のコマンドで作成してmasterにpushしてみます。

pip freeze > requirements.txt

うん。変わらない。

次は、

アクセス制限ってGitHubへのアクセスすら制限されているのか?

と考えました。
一度アクセス制限を外してみます。

変わらず。

変わらなかったのでアクセス制限を戻します。

GitHub Actionsを確認してみます。


ビルドが通ってなかった

はい、GitHubのActionsで×マークがついてます。

以下がエラーの内容です。

Run pip install -r requirements.txt
  pip install -r requirements.txt
  shell: /usr/bin/bash -e {0}
  env:
    pythonLocation: /opt/hostedtoolcache/Python/3.8.13/x64
ERROR: Invalid requirement: 'asgiref=3.3.1=pyhd3eb1b0_0' (from line 1 of requirements.txt)
Hint: = is not a valid operator. Did you mean == ?
Error: Process completed with exit code 1.

requirements.txtでエラー出てますね。

requiremetns.txtの中を見てみます。

asgiref @ file:///tmp/build/80754af9/asgiref_1605055780383/work
beautifulsoup4==4.9.3
certifi==2022.5.18.1
cycler @ file:///tmp/build/80754af9/cycler_1637851556182/work
Django @ file:///tmp/build/80754af9/django_1609784082548/work
django-bootstrap4==2.3.1
djangorestframework @ file:///home/conda/feedstock_root/build_artifacts/djangorestframework_1616757768152/work
fonttools==4.25.0
kiwisolver @ file:///C:/ci/kiwisolver_1653292408254/work
matplotlib @ file:///C:/ci/matplotlib-suite_1647423638658/work
mkl-fft==1.3.1
mkl-random @ file:///C:/ci/mkl_random_1626186184278/work
mkl-service==2.4.0
munkres==1.1.4
numpy @ file:///C:/ci/numpy_and_numpy_base_1652802206636/work
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
Pillow==9.0.1
psycopg2 @ file:///C:/ci/psycopg2_1608147681824/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
python-dateutil @ file:///tmp/build/80754af9/python-dateutil_1626374649649/work
pytz @ file:///tmp/build/80754af9/pytz_1608922264688/work
sip==4.19.13
six @ file:///tmp/build/80754af9/six_1644875935023/work
soupsieve==2.1
sqlparse @ file:///tmp/build/80754af9/sqlparse_1602184451250/work
tornado @ file:///C:/ci/tornado_1606942392901/work
wincertstore==0.2

ん?なんか途中謎のパスが出てない???

Anacondaの場合に起きる

どうやら

@ file...

という書き方はAnacondaを利用している場合に起きるようです。

以下のコマンドであれば問題ないフォーマットで出力されました。

pip list --format=freeze

OK。もう一回プッシュ!

pytzのバージョン

エラー!

GitHubのActionsを見てみると途中まではうまくインストールが進んでいました。

落ちていたのは以下をインストールしようとした時にバージョンが存在しないというものでした。

pytz==2020.5

しかも存在するバージョンと見比べると全然フォーマットが違う…。

ソースコード内を検索してもこのライブラリは使用していなかったため、requirementsから削除して再トライ。

今度は以下のバージョンが存在しないと言われました。

setuptools==51.3.3.post20210118
ssip==4.19.13

これもimportしていないので削除してpush。

…buildが通った!

あとはdeployさえうまくいけば…!

デプロイセンターの方を見てみるとデプロイのログが出てきました。

ここに辿り着くのに何時間も掛かりました…。

ようやく進んだ感じがします!

数十分後…

成功のログが出ました。ブラウザのキャッシュをクリアしてアクセスしてみます。

デプロイ「は」出来た!

チュートリアル画面ではない画面が出ました。なんかエラー吐いてます。

エラーに書いている通り、settings.pyファイルにALLOWED_HOSTSにurlを追記してみます。


ALLOWED_HOSTS = ['carddetailcalculator.azurewebsites.net']

なんか見た目おかしい

サイトが表示はされましたが、CSSが当たっていないような感じです。


F12キーでGoogleの開発者ツールを開いてコンソールを見てみます。


やはり404エラーがいくつも出てますね。

デプロイ後にパスが通っていないってAzureに限らずあるあるな気がします。

公式ドキュメントを参考に、静的ファイルのパスを通すための設定をしてみます。

※whitenoiseモジュールをインストール際はrequirements.txtに追加も忘れずに!

…変わらず。

ひとまず検索処理が動いたのは確認したので静的ファイルの設定は明日に繰り越し。

翌日の朝

翌日の朝にサイトにアクセスしたところ、CSSが反映されてました。

キャッシュが残っていたのか、あるいはデプロイがまだ終わっていなかったのか…?

ひとまず出来ました!


結果

目標、必須要件を全て実現出来ました!

目標

  1. Azure App Service にWebアプリをデプロイするという経験を得る
  2. 毎回サーバーを起動するという手順を省けるようにする

必須要件

  • 私だけ、あるいは私の自宅からだけアクセス出来るように制限を掛けられること

Azure Web Serviceを使用した所感

DjangoはDBの移行が楽

DjangoはデフォルトではSQLiteを使用しています。

ローカル環境で登録したデータをそのままGitに上げてデプロイ出来るので、
DB用のServiceを別途用意する必要がありません。

今回のように自宅ローカルサーバーで動かしているアプリを移行するのには便利です。

やはりF1プランは重い

無料枠なので仕方ないことですが、ローカルで実行している際よりレスポンスが遅いです。


今後に向けて

今回グローバルIPアドレスを指定してアクセス制限を行っているため、
自宅のLANに繋がっている端末であればアクセス可能です。

そのため今まで私のPCでしかアクセス出来なかったのですが、
今回からは妻のPCでもアクセス可能となりました。

そこで家計分析が出来ることのメリットが上がったと思います。

そのため次に実施することは

ダッシュボードに意味のあるグラフを表示する

です。

進捗がありましたらまた記事を投稿します。


経験を通して学んだこと

  • Pythonアプリ開発時は必ずrequirements.txtを作成しよう
  • Anacondaで開発時のrequirements.txtはpip list --format=freezeを使用しよう
  • ビルド成功しているかどうかはGitHub Actionsを確認しよう

コメントを書く