LoginSignup
3

More than 1 year has passed since last update.

posted at

updated at

FastAPIで作ったアプリをApp ServiceとAzure Database for MySQL上にデプロイする

はじめに

こちらの記事は求ム!Pythonを使ってAzureで開発する時のTips!【PR】日本マイクロソフト Advent Calendar 2020の16日目の記事です。
最近触り始めたFastAPI.このフレームワークで作成したサンプルアプリをAzure上にデプロイすべく手順をまとめてみます。
サンプルアプリと言いつつもHelloWorldだけだと少し味気ないのでDBが絡むような簡単なコードを実装してみました。

何ができるようになるのか

  • 開発環境からAzureへのFastAPIを利用したアプリのデプロイ
  • Python(SQLAlcemy)を利用してAzure Database for MySQLへのSSL/TLS接続構成

動作環境

以下のシステム要件を想定しております。

  • Docker最新版 ※ローカルで動作確認を行うため
  • App Service on Linux(Python3.7系)
  • Azure Database for MySQL5.7
  • VSCodeのApp Service拡張機能

手順

ローカルでの動作確認

  • ここからローカルにソースをクローンします。
  • .env.sample から .envをコピーする。※編集はこの後行います。
  • docker-compose up --buildで起動します。
  • 起動したら http://localhost:8000/ にアクセスし {"message":"Hello World"} が表示されたらOKです。

App Serviceを作成

  • こちらの手順を元にApp Service、WebAppsを作成します。ランタイムは python3.7 としてください。

Azure Database for MySQLを作成

  • Azure Potalにアクセスします。
  • 左上のハンバーガーメニューから[リソースの作成]をクリックし、[データベース]を選択ください。 image.png
  • Azure Database for MySQLをクリックし、[単一サーバー] or [フレキシブルサーバー]の選択となります。今回はサンプルということもあるので[フレキシブルサーバー]にしたいと思います。
    image.png

  • 基本設定は下記の通りとしてます。

    • サブスクリプション[任意]
    • リソースグループ[任意]
    • サーバ名[任意] ※こちらは控えておいてください
    • リージョン[先ほど作成したApp Serviceと同一リージョン]
    • ワークロードの種類[実稼働(小規模/中規模)]
    • MySQLバージョン[5.7]
    • 管理者アカウント[任意] ※こちらは控えておいてください image.png
  • SKUは下記の通りとしてます。※今回はミニマムとしてます。

    • Computer Tier[バースト可能]
    • コンピューティングサイズ[Standart_B1s]
    • ストレージサイズ[10GB] image.png
  • ネットワーク設定ですが、今回は[パブリックアクセス]とし、 AppServiceからの接続とローカル(開発端末) からのみ許可しました。要件によってはVNET IntegrationとPrivate Endpointを組み合わせてセキュアにしても良いかもしれません。送信元IPはこちらのページを参考に確認ください。
    image.png

DB初期設定

  • 下記の手順で初期設定を行います。
# 接続
mysql -h fastapi.mysql.database.azure.com -u <ユーザ名> -p

# DB作成 ※こちらは控えておいてください。
create database <DB名>;

# DB指定
use <DB名>;

# テーブル作成
CREATE TABLE users (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL DEFAULT '',
    email VARCHAR(255) NOT NULL DEFAULT '',
    password VARCHAR(255) NOT NULL DEFAULT '',
    token TEXT,
    created_at datetime DEFAULT CURRENT_TIMESTAMP,
    updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

# 初期データ追加
INSERT INTO users (name, email, password) VALUES ("admin", "admin@example.com", "<hash password>");
※passwordの作成方法は後述します。

環境変数の設定とアップロード

  • ローカルでの動作確認の項で作成した .env を下記の通り更新します。
.env
...
ENVIRONMENT="production"
SECRET_KEY="<任意の文字列>"
ALGORITHM="HS256"
ACCESS_TOKEN_EXPIRE_MINUTES=60

# MySQL
MYSQL_SERVER="<Azure Database for MySQLのサーバー名>"
MYSQL_USER="<Azure Database for MySQLのユーザ名>"
MYSQL_PASSWORD="<Azure Database for MySQLのパスワード>"
MYSQL_DB="<Azure Database for MySQLのスキーマ名>"
...

※フレキシブルサーバの場合はユーザ名は単一サーバー版とは異なり、hoge@hostnameではなく、hogeのみで良さそうです。

更新後、VSCodeからアップロードします。
image.png

スタートアップファイルの設定

Webappsの[構成]ブレードの全般設定タブのスタートアップコマンドに startup.txt を登録しておきます。
image.png

startup.txtの中身はこのような感じです。必要に応じてオプションを付け足してみてください。 オプションの詳細はこちら

startup.txt
python -m uvicorn src.main:app --host 0.0.0.0

ソースのデプロイ

VSCodeからアップロードします。赤囲みの矢印ボタンをクリックし
image.png
デプロイ中は[output]タブにて進行状況が確認できます。
image.png

デプロイが正常終了するとこのような表示になります。
TOPページ
image.png

docsページ
image.pngimage.png

試しにJWTを取得するAPIを叩いても問題なくレスポンスが返ってきます。
image.png

補足

  • パスワードの作成について
    passlibを用いハッシュしてます。 pipでpasslib, bcryptをそれぞれインストールした上で下記を実行すると作成できます。
import passlib.hash

secret = "plain text"
salt = "saltsalt"
hashed = passlib.hash.sha512_crypt.hash(secret, salt=salt)
print(hashed)

最後に

FlaskやDjangoをApp Serviceにデプロイする記事は見かけることはありましたが、FastAPIの記事はまだ少ない印象でしたので、参考になれば幸いです。
サンプルコードがまだまだ成熟し切っていないので、さわりだけ掴んでもらえればと思います。
雛形にできるよう今後も少しずつ改善してきます。

参考

3:Visual Studio Code から App Service を作成する
IPアドレスを見つける

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3