Azure WebApps(windows)×SQLDatabase で Django!

# はじめに

表題のとおり、WebApps×SQLDatabase上にDjangoをデプロイした際に大分苦戦したのでまとめ

苦戦その①：そもそもデプロイが失敗してしまう。
苦戦その②：デプロイ成功後、たまにレスポンスが異常に遅くなる（15秒程度）

苦戦その①については
@tag1216 さんの記事のおかげで大分楽にできました

https://qiita.com/tag1216/items/0432f53e6b1a30dea912

その①は基本的には上記の記事をご確認ください。

# 早速デプロイ

## 前提

Azure WebApps × SQLDatabase + Djangoのデプロイ方法を記載します。
(Djangoプロジェクトの作成については一切触れません)
原則コンソールは使わずにダッシュボードの操作のみで行きます。

## 苦戦その①：そもそもデプロイが失敗してしまう。

デプロイの手順を書いていきます。

### インスタンスの作成 & 設定

#### SQL Database

SQLDatabaseの作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184107/996ba8eb-ea24-d683-c830-131aaf7f363d.png)
（※場所はパンくずリストをみてくださいホーム＞SQL データベース＞SQL Databaseのところです。）
Djangoの設定に関係ないので、インスタンスだけ作成します。

Djangoの設定

先にライブラリをインストール

```Bash
pip install django-pyodbc-azure
```

接続文字列は以下のような感じ

```Python
DATABASES = {
    'default': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': '******', # 作成したデータベース名に変更してください
        'USER': '******', # ユーザ名　作成時のユーザではなく、セキュリティの制約を付けたユーザを作成して設定した方が良いです。
        'PASSWORD': '*******', # 該当ユーザのパスワード
        'HOST': '******.database.windows.net', # ホスト名を適宜変更してください。
        'PORT': '1433',

        'OPTIONS': {
            'driver': 'ODBC Driver 17 for SQL Server',
            'connection_timeout': 10, # タイムアウト時間等も適宜設定してください。
            'connection_retries': 5,
            'query_timeout': 30,
        },
    },
}
```

※ODBC Driver 17 for SQL Server
Azureのダッシュボードから確認すると「ODBC Driver 13 for SQL Server」となっていますが、
2018/07/08にAzureの一部インスタンスで運用作業中に一時的に消されています。（サポート問い合わせの結果、運用ミスであるとのこと）
今後17にしていくとのことだったので、はじめからODBC Driver 17 for SQL Serverにしておいた方が良いと思います。


#### WebApps

WebAppsの作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184107/98bf87f6-f1c8-e292-bae6-70bfd50abd99.png)
（※場所はパンくずリストをみてくださいホーム＞App Service＞Web・・・のところです。）

リソースへ移動
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184107/4334e7f9-b307-c806-3425-59d9a2aa6bfc.png)

拡張機能を追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184107/cb0f6fb8-64f7-5d58-2c7c-a360ff3321d8.png)
（デフォルトはx86ですので、今回はpython3.6.4 x86を追加）

#### Djangoのデプロイファイルを記載

https://qiita.com/tag1216/items/0432f53e6b1a30dea912
で書いてくださっていますが、
以下を用意します。

プロジェクトフォルダの直下に
requirements.txt　⇒ pip freeze > requirements.txt で出力しておく
runtime.txt
web.config
ptvs_virtualenv_proxy.py
.deployment
deploy.cmd

のファイルを作成して、配置（内容は以下にファイルごと記載）

- runtime.txt

利用するバージョンを指定

```Text
python-3.6
```


- web.config

サーバの処理方法を記載
一旦
https://qiita.com/tag1216/items/0432f53e6b1a30dea912
に記載がありますので、コピペして、pythonのバージョンだけ361->364に修正してください。
（その②に続きます。）

- ptvs_virtualenv_proxy.py

仮想環境のプロキシ設定
https://docs.microsoft.com/ja-jp/azure/app-service/web-sites-python-configure
に記載がありますので、コピペしてみてください。

- .deployment

デプロイコマンドを指定

```Text
[config]
command = deploy.cmd
```

- deploy.cmd

デプロイコマンドを記載
https://qiita.com/tag1216/items/0432f53e6b1a30dea912
で記載のとおり、pipやpythonのパスを通したりをデフォルトから追加
今回は3.6.4のため、
以下の3行のみ修正

```Text
SET PYTHON_HOME=D:\home\python364x86
SET PYTHON=%PYTHON_HOME%\python.exe
SET PIP=%PYTHON% -m pip
```

#### github等にあげる

私はbitbucketを利用していますが、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184107/a9ba47cb-550c-6c87-54ff-9dcc477f9dc0.png)

上記のいずれかが良いと思います。

デプロイオプションからそのまま設定を進めると
デプロイが進みます。

## デプロイ完了

一旦上記の手順でデプロイ自体は成功すると思います。（2018/08/16時点）

# 苦戦その②：デプロイ成功後、たまにレスポンスが異常に遅くなる（15秒程度）

これで開発を進めていたのですが、
たまにレスポンスが遅くなる事案が発生

サポートに問い合わせたところ

IIS(AzureWebAppsのWebServer) => wfastcgi(デフォルト) => Python
(wfastcgi.py provides a bridge between IIS and Python using WSGI and FastCGI, similar to what mod_python provides for Apache HTTP Server.)

を利用している場合、

起動しているPythonのプロセスは良いのですが、
一定数以上の同時接続があった場合は、リクエストを待たせることなく、
新規Pythonプロセスが立ち上がるとのことでした。（なので、起動しなおすのと同じ状態なので、たまに遅いというような事象が発生します。）
waitressとか使ったら、どうですか？と教えてもらえました。

で、検索したところ、以下のサイトに手順等載っていました。
https://blogs.msdn.microsoft.com/azureossds/2017/09/01/django-app-with-httpplatformhandler-in-azure-app-services-windows/

waitressのインストール

```Bash
pip install waitress
```

web.configを以下に修正（全文記載 本番用のrunserverを使わない状態です）

```
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="PythonHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
    </handlers>
    <httpPlatform processPath="D:\home\python364x86\python.exe"
                  arguments="D:\home\site\wwwroot\server.py --port %HTTP_PLATFORM_PORT%"
                  stdoutLogEnabled="false"
                  requestTimeout="00:04:00"
                  startupRetryCount="3"
                  startupTimeLimit="120">
      <environmentVariables>
        <environmentVariable name="PYTHONPATH" value="D:\home\python364x86" />
        <environmentVariable name="SERVER_PORT" value="%HTTP_PLATFORM_PORT%" />
      </environmentVariables>
    </httpPlatform>
  </system.webServer>
</configuration>
```

プロジェクト直下に
server.pyを追加

```Python
import sys
from waitress import serve
from yell_server.wsgi import application

args = sys.argv
if __name__ == '__main__':
    serve(application, host="0.0.0.0", port=args[2], url_scheme='https')
```

requirements.txtを再出力して、
コードをデプロイします。

以上、お疲れ様です。

# 補足

dbのmigrateやstaticやセキュリティの設定は別途行ってください。

wheelがない場合はpipでのインストールができないため、下記サイトをお試しを

https://qiita.com/YuichiNukiyama/items/ad125213c44b4100764b