LoginSignup
6
6

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-12-16

はじめに

こちらの記事は求ム!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アドレスを見つける

6
6
0

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
  3. You can use dark theme
What you can do with signing up
6
6