2
1

作成したアプリをPipelineでApp Serviceに自動デプロイする方法

Last updated at Posted at 2023-12-10

やりたいこと

FastAPIで作成したアプリをApp Serviceにデプロイします。
Azure Portalからリポジトリを参照して手動デプロイすることも可能ですが、デプロイするたびに作業するのが面倒なのでmainブランチにマージされたら自動デプロイしてくれるようにしたいです。

DevOpsでPipelineを作成して、Dockerのコンテナイメージの管理とApp Serviceへのデプロイを自動化させます。

フローの流れ

スクリーンショット 2023-11-02 18.34.28.png

① 開発者がローカルで書いたソースコードをReposにPushします。
② ReposのmasterブランチにPushされたことを検知して、Pipelineを自動で実行させます。
③ PipelineからContainer Registryに新しいコンテナイメージをアップします。
④ 新しいコンテナイメージをApp Service側に配置して、デプロイさせます。

使うサービス

◾️ FastAPI

Pythonの軽量フレームワークで、APIの開発に特化。
アプリはこのFastAPIで作成してます。

◾️ Docker

Dockerについての詳しい内容は記載しませんが、使用。

◾️ Azure Container Registry

Dockerをクラウド側で管理するために使用。

◾️ App Service

作成したアプリをデプロイするために使用。

◾️ Azure Pipelines

デプロイを自動化するために使用

事前準備

◾️ Azureの環境を用意

Subscriptionを作成し、リソースグループを一つ作成

◾️ App Service Planを作成

App Serviceを作成するために必要です。

◾️ Azure Container Registryを作成

Dockerのコンテナイメージを管理するために必要です。

◾️ Azure Devopsの用意

Reposでのソースコードの管理、Pipelinesの作成を行うために必要です。

手順

1. App Serviceを作成

スクリーンショット 2023-12-10 20.27.45.png
リソースの作成から「Webアプリ」を選択

スクリーンショット 2023-12-10 20.01.00.png
公開方法は「Dockerコンテナー」にします。
OSとRegionはApp Services Planと同じにしてください。
自分はPlan作成時にJapan Eastにしたので、App Serviceも同様に「Japan East」にします。

スクリーンショット 2023-12-10 20.01.11.png
OSとRegionをApp Service Planと同じに合わせると「価格プラン」に作成したApp Service Planが出てくると思うので、選択。


スクリーンショット 2023-12-10 20.01.21.png
「データベース」タブはスキップして、「Docker」タブに移動。
イメージソースは「クイックスタート」を選択。


スクリーンショット 2023-12-10 20.08.36.png
既にContainer Registryにイメージをアップしている場合は、イメージソースを「Azure Container Registry」にしてレジストリ、イメージ、タグを選択することでApp Serviceリソース作成と同時にDockerの情報をもとにデプロイしてくれます。


スクリーンショット 2023-12-10 20.01.35.png
「ネットワーク」タブは既定のままでOK。


スクリーンショット 2023-12-10 20.01.43.png
「監視」タブも既定のまま。

確認および作成」を選択して、リソース作成完了。


2. ローカルで簡単なアプリを作成

今回はFastAPIでアプリを作成してます。

1. プロジェクト作成
mkdir <プロジェクト名>
2. プロジェクト直下に移動
cd <プロジェクト名>
3. pythonファイルを一つ作成
touch main.py
4. 仮想環境を作成
python -m venv .venv
5. 仮想環境に入る
source .venv/bin/activate
6. 必要なパッケージをインストール
pip install fastapi uvicorn gunicorn
7. main.pyに記載
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
def root():
    return {"message": "Hello World"}

デプロイできたことを確認できればいいので、必要最低限のみ記載。


3. Dockerの用意

1. Dockerファイルを作成
touch Dockerfile
2. Dockerfileに記載
FROM python:3.9

WORKDIR /code

COPY requirements.txt .

RUN apt-get update && apt-get -y upgrade

RUN pip install --no-cache-dir --upgrade -r requirements.txt

COPY . .

EXPOSE 3100

CMD ["gunicorn", "main:app"]
3. .dockerignoreファイルを作成
touch .dockerignore
4. .dockerignoreファイルに記載
.dockerignore
.git*
**/*.pyc
.venv/

4. デプロイ設定

1. 依存関係を出力するファイルを作成
touch requirements.txt
2. パッケージをrequirements.txtファイルに出力。
pip freeze > requirements.txt
3. gunicornの構成ファイルを作成
touch gunicorn.conf.py
4. gunicorn.conf.pyに記載
gunicorn.conf.py
# Gunicorn configuration file
import multiprocessing

max_requests = 1000
max_requests_jitter = 50

log_file = "-"

bind = "0.0.0.0:3100"

worker_class = "uvicorn.workers.UvicornWorker"
workers = (multiprocessing.cpu_count() * 2) + 1


5. service connectionの作成

スクリーンショット 2023-12-10 20.44.30.png
Devopsの左下にある設定ボタンを選択して、「Service connections」を選択。
右上の「New service connection」から新しいservice connectionを作成。

スクリーンショット 2023-12-10 20.41.24.png
Azure Resource Manager」を選択。


スクリーンショット 2023-12-10 20.48.17.png
Service principal(automatic)」を選択。


スクリーンショット 2023-12-10 20.43.01.png
対象のSubscriptionとResource Groupを選択して、適当な名前のService connection nameを入力して、「Save」をクリック。

これでservice connectionは作成完了。


6. Pipelineを作成

スクリーンショット 2023-12-10 20.58.36.png
サイドメニューから「Pipelines」 を選択して、「New pipeline」から新しいパイプラインを作成。

スクリーンショット 2023-12-10 20.52.26.png
Azure Repos Git」を選択。

スクリーンショット 2023-12-10 20.52.41.png
対象のリポジトリを選択。
二つある「Docker」のうち、「Build and push an image to Azure Container Registry」の方を選択。

スクリーンショット 2023-12-10 20.56.05.png
対象のSubscriptionを選択。

スクリーンショット 2023-12-10 21.05.32.png
認証が通った後、Container Registryを選択して、適当なImage Nameをつける。
「Validate and configure」をクリック。


スクリーンショット 2023-12-10 20.56.59.png
以下の画面になったらOK。


7. ymlファイルを記載

azure-pipelines.yml
# Docker
# Build and push an image to Azure Container Registry
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:
  # 以下追記
  azureSubscription: '<5.で作成したservice connection>'
  appName: '<App Serviceリソース名>'
  
  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '<規定のまま>'
  imageRepository: '<規定のまま>'
  containerRegistry: '<規定のまま>'
  dockerfilePath: '**/Dockerfile-deploy'
  tag: '$(Build.BuildId)'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

# 追記
- stage: Deploy
  dependsOn: Build
  condition: succeeded()
  displayName: Deploy to App Services
  jobs:
    - job: Deploy
      displayName: Deploy
      pool:
        vmImage: $(vmImageName)
      steps:
        - task: AzureWebAppContainer@1
          displayName: Azure Web App on Container Deploy
          inputs:
            azureSubscription: $(azureSubscription)
            appName: $(appName)
            imageName: $(containerRegistry)/$(imageRepository):$(tag)

▪️ triggerは「master」に設定しているため、masterにpushされるたびに実行されます。もし自動で実行されたくない場合は「none」とする。
▪️ stageの「Build」ではContainer Registryにイメージをpushします。
▪️ stageの「Deploy」でApp Serviceにデプロイします。


8. 実行

スクリーンショット 2023-12-10 21.13.30.png
「Save and run」を実行。

...

スクリーンショット 2023-12-10 21.11.52.png

スクリーンショット 2023-12-10 21.12.25.png

スクリーンショット 2023-12-10 21.17.02.png
無事デプロイできました。

2
1
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
2
1