チュートリアル:PostgreSQL を使用した Django Web アプリを Azure App Service にデプロイする

このチュートリアルでは、データ ドリブンの Python Django Web アプリを Azure App Service にデプロイし、それを Azure Database for Postgres データベースに接続する方法について説明します。 上記のオプションを選択して、PostgresSQL フレキシブル サーバー (プレビュー) を試すこともできます。 フレキシブル サーバーには、よりシンプルなデプロイ メカニズムが用意されており、継続的なコスト削減が可能になります。

このチュートリアルでは、Azure CLI を使用して以下のタスクを実了します。

  • Python と Azure CLI を使用して初期環境を設定する
  • Azure Database for PostgreSQL データベースを作成する
  • Azure App Service にコードをデプロイして PostgreSQL に接続する
  • コードを更新して再デプロイする
  • 診断ログを表示する
  • Azure portal で Web アプリを管理する

このチュートリアルの Azure portal バージョンも使用できます。

このチュートリアルでは、データ ドリブンの Python Django Web アプリを Azure App Service にデプロイし、それを Azure Database for PostgreSQL フレキシブル サーバー (プレビュー) データベースに接続する方法について説明します。 PostgreSQL フレキシブル サーバー (プレビュー) を使用できない場合は、上記の [単一サーバー] オプションを選択します。

このチュートリアルでは、Azure CLI を使用して以下のタスクを実了します。

  • Python と Azure CLI を使用して初期環境を設定する
  • Azure Database for PostgreSQL フレキシブル サーバー データベースを作成する
  • Azure App Service にコードをデプロイして PostgreSQL フレキシブル サーバーに接続する
  • コードを更新して再デプロイする
  • 診断ログを表示する
  • Azure portal で Web アプリを管理する

このチュートリアルの Azure portal バージョンも使用できます。

1.初期環境を設定する

  1. アクティブなサブスクリプションが含まれる Azure アカウントを用意します。 無料でアカウントを作成できます
  2. Python 3.6 以降をインストールします。
  3. Azure CLI 2.18.0 以降をインストールします。これを任意のシェルで使用してコマンドを実行し、Azure リソースのプロビジョニングと構成を行います。

ターミナル ウィンドウを開き、Python のバージョンが 3.6 以降であることを確認します。

python3 --version

Azure CLI のバージョンが 2.18.0 以降であることを確認します。

az --version

アップグレードする必要がある場合は、az upgrade コマンド (バージョン 2.11 以降が必要) を試すか、「 Azure CLI のインストール」をご覧ください。

次に CLI から Azure にサインインします。

az login

このコマンドを実行すると、お客様の資格情報を収集するためにブラウザーが開かれます。 コマンドが終了すると、ご利用のサブスクリプションに関する情報を含んだ JSON 出力が表示されます。

サインイン後は、Azure CLI を使用して Azure コマンドを実行して、サブスクリプション内のリソースを操作することができます。

問題がある場合は、 お知らせください

2.サンプル アプリをクローンまたはダウンロードする

サンプル リポジトリをクローンします。

git clone https://github.com/Azure-Samples/djangoapp

次に、そのフォルダーに移動します。

cd djangoapp

フレキシブル サーバー (プレビュー) の場合は、サンプルのフレキシブル サーバー ブランチを使用します。このブランチでは、データベース サーバーの URL の設定方法や、Azure PostgreSQL フレキシブル サーバーの必要に応じて Django データベース構成に 'OPTIONS': {'sslmode': 'require'} を追加することなど、いくつかの変更が必要となります。

git checkout flexible-server

djangoapp サンプルには、データ ドリブンの Django 投票アプリが含まれます。これを、Django ドキュメントの「はじめての Django アプリ作成」に従って取得します。 参考までに、完成したアプリをここに記載しています。

このサンプルは、App Service のような運用環境で実行するために変更もされています。

  • 運用環境の設定は、azuresite/production.py ファイルにあります。 開発環境の設定は、azuresite/settings.py にあります。
  • WEBSITE_HOSTNAME 環境変数を設定すると、アプリで運用環境の設定が使用されます。 この変数は、Azure App Service によって Web アプリの URL (msdocs-django.azurewebsites.net など) に自動的に設定され ます。

運用環境の設定は、任意の運用環境で実行するために Django を構成する場合に固有であり、App Service に固有なものではありません。 詳細については、Django デプロイ チェックリストに関するページを参照してください。 一部の変更点の詳細については、Azure 上での Django の運用設定に関するセクションを参照してください。

問題がある場合は、 お知らせください

3.Azure で Postgres データベースを作成する

Azure CLI 用 db-up 拡張機能をインストールします。

az extension add --name db-up

az コマンドが認識されない場合は、「初期環境を設定する」の説明に従って Azure CLI がインストールされていることを確認してください。

次に、az postgres up コマンドを使用して Azure に Postgres データベースを作成します。

az postgres up --resource-group DjangoPostgres-tutorial-rg --location centralus --sku-name B_Gen5_1 --server-name <postgres-server-name> --database-name pollsdb --admin-user <admin-username> --admin-password <admin-password> --ssl-enforcement Enabled
  • <postgres-server-name>Azure 全体で一意 である名前に置き換えます (サーバー エンドポイントは https://<postgres-server-name>.postgres.database.azure.com になります)。 会社名と別の一意の値を組み合わせて使用すると、適切なパターンになります。
  • <admin-username><admin-password> には、この Postgres サーバーの管理者ユーザーを作成するための資格情報を指定します。 管理者のユーザー名に azure_superuserazure_pg_adminadminadministratorrootguest、または public は使用できません。 pg_ で始めることはできません。 パスワードには、次のうちの 3 つのカテゴリの、8 から 128 文字 が含まれている必要があります: 英大文字、英小文字、数字 (0 から 9)、英数字以外の文字 (!、#、% など)。 パスワードにユーザー名を含めることはできません。
  • ユーザー名とパスワードに $ 文字は使用しないでください。 後で、これらの値を使用して環境変数を作成しますが、Python アプリの実行に使用する Linux コンテナー内では、環境変数内の $ 文字に特殊な意味があります。
  • ここで使用している B_Gen5_1 (Basic、Gen5、1 コア) の価格レベルは、コストが最も低いものです。 運用データベースの場合は、--sku-name 引数を省略して、代わりに GP_Gen5_2 (General Purpose、Gen 5、2 コア) レベルを使用します。

このコマンドによって次の操作が実行されます。これには数分かかる場合があります。

  • DjangoPostgres-tutorial-rg というリソース グループがまだない場合は、作成します。
  • --server-name 引数によって指定された Postgres サーバーを作成します。
  • --admin-user および --admin-password 引数を使用して、管理者アカウントを作成します。 これらの引数を省略すると、コマンドによって一意の資格情報が自動的に生成されるようになります。
  • --database-name 引数で指定されたとおりに pollsdb データベースを作成します。
  • ローカル IP アドレスからのアクセスを有効にします。
  • Azure サービスからのアクセスを有効にします。
  • pollsdb データベースへのアクセス権を持ったデータベース ユーザーを作成します。

すべての手順は、他の az postgres および psql コマンドを使用して個別に実行することもできますが、az postgres up を使用すれば、そのすべての手順をまとめて実行できます。

コマンドが完了すると、サーバーの URL、生成されたユーザー名 ("joyfulKoala@msdocs-djangodb-12345" など)、GUID パスワードと共に、データベースのさまざまな接続文字列を含む JSON オブジェクトが出力されます。 このチュートリアルの後半で必要になるため、ユーザー名とパスワードを一時的なテキスト ファイルにコピー します。

ヒント

-l <location-name> は、いずれかの Azure リージョンに設定することができます。 ご利用のサブスクリプションから使用できるリージョンは、az account list-locations コマンドを使用して取得できます。 運用アプリの場合は、データベースとアプリを同じ場所に配置してください。

  1. すべてのコマンドでパラメーターを指定する必要がないように、Azure CLI でのパラメーターのキャッシュを有効にします。 (キャッシュされた値は .azure フォルダーに保存されます。)

    az config param-persist on 
    
  2. リソース グループを作成します (必要に応じて名前を変更できます)。 リソース グループ名はキャッシュされ、後続のコマンドに自動的に適用されます。

    az group create --name Python-Django-PGFlex-rg --location centralus
    
  3. データベース サーバーを作成します (この処理には数分かかります)。

    az postgres flexible-server create --sku-name Standard_B1ms --public-access all
    

    az コマンドが認識されない場合は、「初期環境を設定する」の説明に従って Azure CLI がインストールされていることを確認してください。

    az postgres flexible-server create コマンドでは、次のアクションが実行されます (数分かかります)。

    • キャッシュされた名前がまだ存在していない場合は、既定のリソース グループを作成します。
    • PostgreSQL フレキシブル サーバーを作成します:
      • 既定では、このコマンドでは server383813186 のような生成された名前が使用されます。 --name パラメーターを使用して、独自の名前を指定できます。 Azure 全体で重複しない、一意の名前にしてください。
      • このコマンドでは、最も低コストの価格レベル Standard_B1ms が使用されます。 既定の Standard_D2s_v3 レベルを使用するには、--sku-name 引数を省略します。
      • このコマンドでは、前の az group create コマンドからキャッシュされたリソース グループと場所が使用されます。この例では、centralus リージョン内のリソース グループ Python-Django-PGFlex-rg です。
    • ユーザー名とパスワードを使用して管理者アカウントを作成します。 これらの値は、--admin-user および --admin-password パラメーターを使用して直接指定できます。
    • 既定の flexibleserverdb という名前のデータベースを作成します。 --database-name パラメーターを使用すると、データベース名を指定できます。
    • 完全なパブリック アクセスを有効にして、--public-access パラメーターを使用して制御できます。
  4. コマンドが完了したら、コマンドの JSON 出力をファイルにコピー します。このチュートリアルで後ほど、出力された値 (特にホスト、ユーザー名、パスワード) とデータベース名が必要となります。

問題がある場合は、 お知らせください

4.Azure App Service にコードをデプロイする

このセクションでは App Service アプリでアプリ ホストを作成し、このアプリを Postgres データベースに接続して、そのホストにコードをデプロイします。

4.1 App Service アプリを作成する

ターミナルで、現在の場所がアプリ コードを含む djangoapp リポジトリ フォルダーであることを確認します。

az webapp up コマンドを使用して App Service アプリ (ホスト プロセス) を作成します。

az webapp up --resource-group DjangoPostgres-tutorial-rg --location centralus --plan DjangoPostgres-tutorial-plan --sku B1 --name <app-name>
  • --location 引数には、前のセクションでデータベースに使用したのと同じ場所を使用します。
  • <app-name> を Azure 全体で一意である名前に置き換えます (サーバー エンドポイントは https://<app-name>.azurewebsites.net)。 <app-name> に使用できる文字は A-Z0-9- です。 会社名とアプリ識別子を組み合わせて使用すると、適切なパターンになります。

このコマンドによって次の操作が実行されます。これには数分かかる場合があります。

  • リソース グループがまだ存在していない場合は作成します (このコマンドでは、先ほどデータベースを作成したのと同じリソース グループを使用します)。
  • Basic 価格レベル (B1) で App Service プラン DjangoPostgres-tutorial-plan を作成します (存在しない場合)。 --plan--sku は省略可能ですが、
  • App Service アプリが存在しない場合は作成します。
  • アプリの既定のログがまだ有効になっていない場合は、有効にします。
  • ビルド オートメーションを有効にし、ZIP デプロイを使用してリポジトリをアップロードします。
  • リソース グループの名前や App Service プランなどの一般的なパラメーターをファイル .azure/config にキャッシュします。このため、後のコマンドで同じパラメーターをすべて指定する必要はありません。 たとえば、変更を加えた後でアプリを再デプロイするには、パラメーターを指定せずに az webapp up を再実行するだけです。 ただし、CLI 拡張機能に含まれるコマンド (az postgres up など) では、現時点でキャッシュが使用されません。そのため、ここでは、リソース グループと場所を az webapp up の初回使用時に指定する必要がありました。
  1. ターミナルで、現在の場所がアプリ コードを含む djangoapp リポジトリ フォルダーであることを確認します。

  2. サンプル アプリの flexible-server ブランチに切り替えます。 このブランチには、PostgreSQL フレキシブル サーバーに必要な特定の構成が含まれています。

    git checkout flexible-server
    
  3. 次の az webapp up コマンドを実行して、アプリの App Service ホストを作成します。

    az webapp up --name <app-name> --sku B1 
    

    このコマンドでは、前の az group create コマンドからキャッシュされたリソース グループと場所を使用して (この例では Python-Django-PGFlex-rg リージョン内のグループ centralus)、次のアクションが実行されます。これには数分かかる場合があります。

    • Basic 価格レベル (B1) で App Service プランを作成します。 --sku を省略すると、既定値を使用できます。
    • App Service アプリを作成します。
    • アプリの既定のログを有効にします。
    • ビルド オートメーションを有効にし、ZIP デプロイを使用してリポジトリをアップロードします。

デプロイが成功すると、コマンドによって次の例のような JSON 出力が生成されます。

az webapp up コマンド出力の例

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

4.2 データベースに接続するための環境変数を構成する

コードを App Service にデプロイしたので、次の手順として、アプリを Azure の Postgres データベースに接続します。

アプリ コードでは、DBHOSTDBNAMEDBUSER、および DBPASS という 4 つの環境変数でデータベース情報を検索することを想定しています。

App Service で環境変数を設定するには、次の az webapp config appsettings set コマンドを使用して "アプリ設定" を作成します。

az webapp config appsettings set --settings DBHOST="<postgres-server-name>" DBUSER="<username>" DBPASS="<password>" DBNAME="pollsdb" 
  • <postgres-server-name> は、先ほど az postgres up コマンドで使用した名前に置き換えます。 azuresite/production.py 内のコードによって、完全な Postgres サーバー URL を作成するための .postgres.database.azure.com が自動的に追加されます。
  • <username><password> を、前の az postgres up コマンドで使用した管理者の資格情報、または az postgres up によって自動的に生成された資格情報に置き換えます。 azuresite/production.py 内のコードを実行すると、完全な Postgres ユーザー名が DBUSER および DBHOST を基に自動的に作成されます。そのため、@server の部分は含めないようにしてください。 (また、前述したように、どちらの値にも $ 文字は使用しないでください。Linux 環境変数では、この文字に特殊な意味があります。)
  • リソース グループとアプリ名は、 .azure/config ファイル内のキャッシュされた値から取得されます。
az webapp config appsettings set --settings DBHOST="<host>" DBUSER="<username>" DBPASS="<password>" DBNAME="flexibleserverdb" 

ホスト、ユーザー名、パスワードの値を、前に使用した az postgres flexible-server create コマンドの出力の値に置き換えます。 ホストは server383813186.postgres.database.azure.com のような URL である必要があります。

また、az postgres flexible-server create コマンドで変更した場合は、flexibleserverdb をデータベース名に置き換える必要があります。

Python コードでは、os.environ.get('DBHOST') のようなステートメントを使用して、環境変数としてこれらの設定にアクセスします。 詳細については、「環境変数へのアクセス」を参照してください。

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

4.3 Django データベースの移行を実行する

Django データベースの移行によって、Azure データベース上の PostgreSQL のスキーマが、コードに記述されているスキーマと一致していることが確認されます。

  1. az webpp ssh を実行して、ブラウザーで Web アプリの SSH セッションを開きます。

    az webapp ssh
    

    SSH セッションに接続できない場合は、アプリ自体が起動に失敗しています。 詳細については、診断ログを確認してください。 たとえば、前のセクションで必要なアプリ設定を作成していない場合、ログには KeyError: 'DBNAME' と示されます。

  2. SSH セッションで次のコマンドを実行します (Ctrl+Shift+V キーを使用してコマンドを貼り付けることができます)。

    # Run database migrations
    python manage.py migrate
    
    # Create the super user (follow prompts)
    python manage.py createsuperuser
    

    データベースへの接続に関するエラーが発生した場合は、前のセクションで作成したアプリケーション設定の値を確認してください。

  3. createsuperuser コマンドを使用すると、スーパーユーザーの資格情報の入力を求められます。 このチュートリアルの目的では、既定のユーザー名である root を使用し、Enter キーを押してメール アドレスを空白のままにして、パスワードを「Pollsdb1」と入力します。

  4. データベースがロックされているというエラーが表示された場合は、前のセクションで az webapp settings コマンドを実行したことを確認してください。 それらの設定を行わないと、migrate コマンドがデータベースと通信できずにエラーが発生します。

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

4.4 アプリで投票の質問を作成する

  1. アプリの Web サイトを開きます。 データベース内に特定の投票がまだないため、アプリには "Polls app (投票アプリ)" および "No polls are available (投票は利用できません)" というメッセージが表示されます。

    az webapp browse
    

    "アプリケーション エラー" が表示される場合は、前の手順「データベースに接続するための環境変数を構成する」で必須の設定を作成していないか、またはそれらの値にエラーが含まれていることが考えられます。 コマンド az webapp config appsettings list を実行して、設定を確認します。 また、診断ログ調べて、アプリの起動時に発生したエラーを具体的に確認することもできます。 たとえば、該当する設定を作成していない場合、ログには KeyError: 'DBNAME' というエラーが示されます。

    設定を更新してエラーを修正したら、アプリが再起動するまで少し待ってから、ブラウザーを最新の状態に更新します。

  2. URL に /admin を追加して、Web アプリの管理ページを参照します (例: http://<app-name>.azurewebsites.net/admin)。 前のセクションで用いた Django のスーパーユーザー資格情報 (rootPollsdb1) を使用してサインインします。 [Polls](投票) で、 [Questions](質問) の横の [Add](追加) を選択し、いくつかの選択肢がある投票の質問を作成します。

  3. メインの Web サイト (http://<app-name>.azurewebsites.net) に戻り、質問がユーザーに表示されるようになったことを確認します。 質問に自由に回答してデータベースにデータを生成します。

お疲れさまでした。 アクティブな Postgres データベースを使用して、Azure App Service for Linux で Python Django Web アプリが実行されています。

問題がある場合は、 お知らせください

注意

App Service では、各サブフォルダー内で wsgi.py ファイル (manage.py startproject によって既定で作成されます) を探すことにより、Django プロジェクトが検出されます。 App Service でそのファイルが見つかると、Django Web アプリが読み込まれます。 詳細については、組み込みの Python イメージの構成に関するページを参照してください。

5.コードの変更を加えて再デプロイする

このセクションでは、アプリに対してローカルでの変更を行い、App Service にコードを再デプロイします。 このプロセスで、進行中の作業をサポートする Python 仮想環境を設定します。

5.1 アプリをローカルで実行する

ターミナル ウィンドウで次のコマンドを実行します。 スーパーユーザーを作成するときは、必ずプロンプトに従ってください。

# Configure the Python virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt
# Run Django migrations
python manage.py migrate
# Create Django superuser (follow prompts)
python manage.py createsuperuser
# Run the dev server
python manage.py runserver

Web アプリが完全に読み込まれると、Django 開発サーバーによって、次のメッセージにローカル アプリの URL が表示されます: "Starting development server at http://127.0.0.1:8000/. Quit the server with CTRL-BREAK" (http://127.0.0.1:8000/ で開発サーバーを起動しています。CTRL-BREAK キーを押してサーバーを終了します)。

Django 開発サーバーの出力例

次の手順に従って、アプリをローカルでテストします。

  1. ブラウザーで http://localhost:8000 にアクセスすると、"No polls are available" (投票は利用できません) というメッセージが表示されます。

  2. http://localhost:8000/admin に移動し、先ほど作成した管理者ユーザーを使用してサインインします。 [Polls](投票) で、 [Questions](質問) の横の [Add](追加) をもう一度選択し、いくつかの選択肢がある投票の質問を作成します。

  3. http://localhost:8000 に再び移動し、アプリをテストするために質問に回答します。

  4. Ctrl+C キーを押して Django サーバーを停止します。

ローカルで実行している場合、アプリではローカルの Sqlite3 データベースを使用しており、運用データベースに干渉することはありません。 必要に応じて、ローカルの PostgreSQL データベースを使用して、運用環境をより正確にシミュレートすることもできます。

問題がある場合は、 お知らせください

5.2 アプリを更新する

polls/models.py で、choice_text で始まる行を見つけ、max_length パラメーターを 100 に変更します。

# Find this line of code and set max_length to 100 instead of 200
choice_text = models.CharField(max_length=100)

データ モデルを変更したので、新しい Django の移行を作成し、データベースを移行します。

python manage.py makemigrations
python manage.py migrate

python manage.py runserver を使用して開発サーバーを再度実行し、http://localhost:8000/admin でアプリをテストします。

Ctrl+C キーを使用して Django Web サーバーを再度停止します。

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

5.3 Azure にコードを再デプロイする

リポジトリのルートで次のコマンドを実行します。

az webapp up

このコマンドでは、 .azure/config ファイルにキャッシュされたパラメーターを使用します。 アプリが既に存在することが App Service によって検出されるので、コードの再デプロイだけが行われます。

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

5.4 Azure で移行を再実行する

データ モデルに変更を加えたので、App Service へのデータベースの移行を再実行する必要があります。

ブラウザーで https://<app-name>.scm.azurewebsites.net/webssh/host にアクセスして SSH セッションを再度開きます。 次に、次のコマンドを実行します。

python manage.py migrate

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

5.5 運用環境でアプリを確認する

(az webapp browse を使用するか、http://<app-name>.azurewebsites.net に移動して) もう一度アプリを参照し、アプリを実稼働環境で再度テストします。 (データベース フィールドの長さを変更しただけなので、質問の作成時に長い回答を入力しようとした場合にのみ、この変更が明らかになります)。

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

6.診断ログをストリーミングする

Azure 上でアプリをホストするコンテナー内から生成されたコンソール ログに、アクセスすることができます。

ログ ストリームを確認するには、次の Azure CLI コマンドを実行します。 このコマンドでは、 .azure/config ファイルにキャッシュされたパラメーターを使用します。

az webapp log tail

コンソール ログがすぐに表示されない場合は、30 秒以内にもう一度確認します。

任意のタイミングでログのストリーミングを停止するには、Ctrl+C キーを押します。

問題がある場合は、 お知らせください

注意

https://<app-name>.scm.azurewebsites.net/api/logs/docker で、ブラウザーからログ ファイルを検査することもできます。

az webapp up を実行すると、既定のログが自動的にオンになります。 パフォーマンス上の理由から、このログはしばらくすると自動的にオフになりますが、また az webapp up を実行すると、その都度オンに戻ります。 これを手動でオンにするには、次のコマンドを実行します。

az webapp log config --docker-container-logging filesystem

7.Azure portal でアプリを管理する

Azure portal でアプリ名を探し、結果内のアプリを選択します。

Azure portal で Python Django アプリに移動する

既定では、アプリの [Overview](概要) ページがポータルに表示されます。これにより、全般的なパフォーマンス ビューが提供されます。 ここでは、参照、停止、再開、削除といった基本的な管理タスクを実行することもできます。 ページの左側にあるタブは、開くことができるさまざまな構成ページを示しています。

Azure portal の [概要] ページで Python Django アプリを管理する

問題がある場合は、 まず、トラブルシューティング ガイドを参照し、それでも解決しない場合はお知らせください

8.リソースをクリーンアップする

アプリを残しておく場合、またはその他のチュートリアルに進む場合は、「次のステップ」に進んでください。 それ以外の場合は、継続して料金が発生しないように、このチュートリアルで作成したリソース グループを削除できます。

az group delete --name Python-Django-PGFlex-rg --no-wait

リソース グループを削除することによって、その中に含まれるすべてのリソースの割り当て解除と削除も行われます。 このコマンドを使用する前に、グループ内のリソースが不要になったことを確認してください。

すべてのリソースが削除されるまでには多少時間がかかります。 --no-wait 引数を指定すると、コマンドからすぐに制御が戻されます。

問題がある場合は、 お知らせください

次のステップ

カスタム DNS 名をアプリにマップする方法を確認する:

App Service で Python アプリが実行される方法を確認する: