GitHub Actions에서 CI/CD를 사용하여 Linux의 Azure 앱 Service에 Python 웹앱 배포

GitHub Actions CI/CD(지속적인 통합 및 지속적인 업데이트) 플랫폼을 사용하여 Linux의 Azure 앱 Service에 Python 웹앱을 배포합니다. GitHub Actions 워크플로는 리포지토리에 커밋이 있을 때마다 코드를 자동으로 빌드하고 App Service에 배포합니다. GitHub Actions 워크플로에서 테스트 스크립트, 보안 검사 및 다단계 배포와 같은 다른 자동화를 추가할 수 있습니다.

앱 코드에 대한 리포지토리 만들기

사용할 Python 웹앱이 이미 있는 경우 GitHub 리포지토리에 커밋되어 있는지 확인합니다.

작업할 앱이 필요한 경우 .에서 https://github.com/Microsoft/python-sample-vscode-flask-tutorial리포지토리를 포크하고 복제할 수 있습니다. 이 코드는 Visual Studio Code의 Flask 자습서에서 제공됩니다.

참고 항목

앱이 Django 및 SQLite 데이터베이스를 사용하는 경우 이 자습서에서는 작동하지 않습니다. Django 앱이 PostgreSQL과 같은 별도의 데이터베이스를 사용하는 경우 이 자습서에서 사용할 수 있습니다. Django에 대한 자세한 내용은 이 문서의 뒷부분에 있는 Django에 대한 고려 사항을 참조하세요.

대상 Azure 앱 Service 만들기

App Service 인스턴스를 만드는 가장 빠른 방법은 대화형 Azure Cloud Shell통해 Azure CLI(명령줄 인터페이스)를 사용하는 것입니다. Cloud Shell에는 Git 및 Azure CLI가 포함됩니다. 다음 단계에서는 az webapp을 사용하여 App Service를 만들고 앱의 첫 번째 배포를 수행합니다.

1단계. https://portal.azure.com에서 Azure Portal에 로그인합니다.

2단계. 포털 도구 모음에서 Cloud Shell 아이콘을 선택하여 Azure CLI를 엽니다.

Screenshot showing how to open Azure Cloud Shell in Azure portal.

3단계 Cloud Shell의 드롭다운에서 Bash를 선택합니다.

Screenshot showing an Azure Cloud Shell Bash shell in Azure portal.

4단계 Cloud Shell에서 git 복제본을 사용하여 리포지토리를 복제합니다. 예를 들어 Flask 샘플 앱을 사용하는 경우 명령은 다음과 같습니다.

git clone https://github.com/<github-user>/python-sample-vscode-flask-tutorial.git

github-user>를 리포지토리를 포크한 GitHub 계정의 이름으로 바꿉 <있습니다. 다른 앱 리포지토리를 사용하는 경우 이 리포지토리는 GitHub Actions를 설정하는 위치입니다.

참고 항목

Cloud Shell은 cloud-shell-storage-your-region이라는 리소스 그룹의 Azure Storage 계정으로 지원됩니다>.< 해당 스토리지 계정에는 복제된 리포지토리를 저장하는 Cloud Shell의 파일 시스템 이미지가 포함되어 있습니다. 이 스토리지에는 약간의 비용이 듭니다. 이 문서의 끝부분에 있는 스토리지 계정을 사용자가 만든 다른 리소스와 함께 삭제할 수 있습니다.

Cloud Shell에 붙여넣려면 Ctrl+Shift+V를 사용하거나 마우스 오른쪽 단추를 클릭하고 상황에 맞는 메뉴에서 붙여넣기를 선택합니다.

5단계 Cloud Shell에서 디렉터리를 Python 앱이 있는 리포지토리 폴더로 변경하여 az webapp up 명령이 앱을 Python으로 인식합니다. 예제의 경우 Flask 샘플 앱의 경우:

cd python-sample-vscode-flask-tutorial

6단계 Cloud Shell에서 az webapp up을 사용하여 App Service를 만들고 처음에 앱을 배포합니다.

az webapp up --name <app-service-name> --runtime "PYTHON:3.9"

Azure에서 고유한 App Service 이름을 지정합니다. 이름은 3~60자여야 하며 문자, 숫자 및 하이픈만 포함할 수 있습니다. 이름은 문자로 시작하고 문자 또는 숫자로 끝나야 합니다.

사용 가능한 런타임 목록을 가져오는 데 사용합니다 az webapp list-runtimes . PYTHON|X.Y Python 버전인 X.Y 형식을 사용합니다.

매개 변수를 사용하여 App Service --location 의 위치를 지정할 수도 있습니다. 명령을 az account list-locations --output table 사용하여 사용 가능한 위치 목록을 가져옵니다.

7단계 앱에서 사용자 지정 시작 명령을 사용하는 경우 az webapp config를 사용하여 해당 명령을 사용합니다. 앱에 사용자 지정 시작 명령이 없는 경우 이 단계를 건너뜁니다.

예를 들어 python-sample-vscode-flask-tutorial 앱에는 다음과 같이 사용할 수 있는 시작 명령이 포함된 startup.txt라는 파일이 포함되어 있습니다.

az webapp config set \
  --resource-group <resource-group-name> \
  --name <app-service-name> \
  --startup-file startup.txt

이전 az webapp up 명령의 출력에서 리소스 그룹 이름을 찾을 수 있습니다. 리소스 그룹 이름은 azure-account-name>_rg_<시작합니다.

8단계. 실행 중인 앱을 보려면 브라우저를 열고 http://< app-service-name.azurewebsites.net> 이동합니다.

일반 페이지가 표시되면 App Service가 시작될 때까지 몇 초 정도 기다렸다가 페이지를 새로 고칩니다. 제네릭 페이지가 계속 표시되면 올바른 폴더에서 배포한 검사. 예를 들어 Flask 샘플 앱을 사용하는 경우 폴더는 python-sample-vscode-flask-tutorial입니다. 또한 Flask 샘플 앱의 경우 시작 명령을 올바르게 설정한 검사.

App Service에서 연속 배포 설정

아래 단계에서는 CD(연속 배포)를 설정합니다. 즉, 워크플로가 트리거될 때 새 코드 배포가 발생합니다. 이 자습서의 트리거는 PR(끌어오기 요청)과 같이 리포지토리의 기본 분기에 대한 변경 내용입니다.

1단계. az webapp deployment github-actions add 명령을 사용하여 GitHub Action을 추가 합니다.

az webapp deployment github-actions add \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

매개 변수는 --login-with-github 대화형 메서드를 사용하여 개인 액세스 토큰을 검색합니다. 프롬프트에 따라 인증을 완료합니다.

App Service에서 사용하는 이름과 충돌하는 기존 워크플로 파일이 있는 경우 덮어쓸지 여부를 선택하라는 메시지가 표시됩니다. 매개 변수를 --force 사용하여 묻지 않고 덮어씁 수 있습니다.

add 명령의 기능:

  • 리포지토리에 .github/workflows/<workflow-name.yml>이라는 새 워크플로 파일을 만듭니다. 파일 이름에는 App Service의 이름이 포함됩니다.
  • App Service에 대한 비밀이 포함된 게시 프로필을 가져와서 GitHub 작업 비밀로 추가합니다. 비밀의 이름은 AZUREAPPSERVICE_PUBLISHPROFILE_ 시작합니다. 이 비밀은 워크플로 파일에서 참조됩니다.

2단계. az webapp deployment source show 명령을 사용하여 소스 제어 배포 구성의 세부 정보를 가져옵니다.

az webapp deployment source show \
  --name <app-service-name> \
  --resource-group <resource-group-name>

명령의 출력에서 해당 값과 branch 속성의 repoUrl 값을 확인합니다. 이러한 값은 이전 단계에서 지정한 값과 일치해야 합니다.

GitHub 워크플로 및 작업 설명

워크플로는 리포지토리의 /.github/workflows/ 경로에 있는 YAML(.yml) 파일에 의해 정의됩니다. 이 YAML 파일에는 GitHub 리포지토리와 연결된 자동화된 프로세스인 워크플로를 구성하는 다양한 단계와 매개 변수가 포함되어 있습니다. 워크플로를 사용하여 GitHub에서 모든 프로젝트를 빌드, 테스트, 패키지, 릴리스 및 배포할 수 있습니다.

각 워크플로는 하나 이상의 작업으로 구성됩니다. 각 작업은 차례로 단계 집합입니다. 마지막으로 각 단계는 셸 스크립트 또는 작업입니다.

App Service에 배포하기 위해 Python 코드로 설정된 워크플로의 관점에서 워크플로에는 다음과 같은 작업이 있습니다.

작업 설명
검사out 실행기, GitHub Actions 에이전트의 리포지토리를 확인합니다.
setup-python 실행기에서 Python을 설치합니다.
appservice-build 웹앱을 빌드합니다.
webapps-deploy 게시 프로필 자격 증명을 사용하여 웹앱을 배포하여 Azure에서 인증합니다. 자격 증명은 GitHub 비밀저장됩니다.

워크플로를 만드는 데 사용되는 워크플로 템플릿은 Azure/actions-workflow-samples입니다.

워크플로는 지정된 분기에 대한 푸시 이벤트에서 트리거됩니다. 이벤트 및 분기는 워크플로 파일의 시작 부분에 정의됩니다. 예를 들어 다음 코드 조각은 워크플로가 기본 분기에 대한 푸시 이벤트에서 트리거됨을 보여 줍니다.

on:
  push:
    branches:
    - main

OAuth 권한 있는 앱

지속적인 배포를 설정할 때 Azure 앱 Service에 GitHub 계정에 대한 권한 있는 OAuth 앱 권한을 부여합니다. App Service는 권한 있는 액세스를 사용하여 .github/workflows</workflow-name.yml>에서 GitHub 작업 YML 파일을 만듭니다. 권한 있는 앱을 확인하고 통합/애플리케이션에서 설정 GitHub 계정에서 권한을 취소할 수 있습니다.

Screenshot showing how to view authorized OAuth Apps for a GitHub account.

워크플로 게시 프로필 비밀

리포지토리에 추가된 .github/workflows/<workflow-name.yml> 워크플로 파일에 워크플로의 배포 작업에 필요한 게시 프로필 자격 증명의 자리 표시자가 표시됩니다. 게시 프로필 정보는 보안/작업 아래의 리포지토리 설정 암호화되어 저장됩니다.

Screenshot showing how to view action secrets in GitHub.

이 문서에서 GitHub 작업은 게시 프로필 자격 증명을 사용하여 인증합니다. 서비스 주체 또는 OpenID 커넥트 인증하는 다른 방법이 있습니다. 자세한 내용은 GitHub Actions를 사용하여 App Service에 배포를 참조 하세요.

워크플로 실행

이제 리포지토리를 변경하여 워크플로를 테스트합니다.

1단계. 샘플 리포지토리(또는 사용한 리포지토리)의 포크로 이동하여 트리거의 일부로 설정한 분기를 선택합니다.

Screenshot showing how to go to the repo and branch where the GitHub Actions workflow is defined.

2단계. 약간 변경합니다.

예를 들어 VS Code Flask 자습서를 사용한 경우

  • 트리거 분기의 /hello-app/templates/home.html 파일로 이동합니다.
  • 편집을 선택하고 "재배포됨!" 텍스트를 추가합니다.

3단계 작업 중인 분기에 직접 변경 내용을 커밋합니다.

  • 편집 중인 페이지의 오른쪽 위에서 변경 내용 커밋 ... 단추를 선택합니다. 변경 내용 커밋 창이 열립니다. 변경 내용 커밋 창에서 원하는 경우 커밋 메시지 수정한 다음 변경 내용 커밋 단추를 선택합니다.
  • 커밋은 GitHub Actions 워크플로를 시작합니다.

워크플로를 수동으로 시작할 수도 있습니다.

1단계. 연속 배포를 위해 설정된 리포지토리의 작업 탭으로 이동합니다.

2단계. 워크플로 목록에서 워크플로를 선택한 다음, 워크플로 실행을 선택합니다.

실패한 워크플로 문제 해결

워크플로의 상태 검사 리포지토리의 작업 탭으로 이동합니다. 이 자습서에서 만든 워크플로 파일을 자세히 살펴보면 두 개의 작업 "build"와 "deploy"가 표시됩니다. 실패한 작업의 경우 작업 태스크의 출력을 확인하여 실패의 표시를 확인합니다. 일반적인 문제는 다음과 같습니다.

  • 종속성 누락으로 인해 앱이 실패하는 경우 배포 중에 requirements.txt 파일이 처리되지 않았습니다. 이 동작은 이 문서에 표시된 대로 명령을 사용하지 az webapp up 않고 포털에서 직접 웹앱을 만든 경우에 발생합니다.

  • 포털을 통해 앱 서비스를 프로비전한 경우 빌드 작업 SCM_DO_BUILD_DURING_DEPLOYMENT 설정이 설정되지 않았을 수 있습니다. 이 설정은 .로 true설정해야 합니다. 이 az webapp up 명령은 빌드 작업을 자동으로 설정합니다.

  • "TLS 핸드셰이크 시간 제한"이라는 오류 메시지가 표시되면 리포지토리의 작업 탭에서 트리거 자동 배포를 선택하여 워크플로를 수동으로 실행하여 시간 초과가 일시적인 문제인지 확인합니다.

  • 이 자습서와 같이 컨테이너 앱에 대한 지속적인 배포를 설정하는 경우 워크플로 파일(.github/workflows/<workflow-name.yml>)이 처음에 자동으로 만들어집니다. 수정한 경우 수정 내용을 제거하여 오류가 발생하는지 확인합니다.

배포 후 스크립트 실행

예를 들어 배포 후 스크립트는 앱 코드에서 예상하는 환경 변수를 정의할 수 있습니다. 앱 코드의 일부로 스크립트를 추가하고 시작 명령을 사용하여 실행합니다.

워크플로 YML 파일에서 변수 값을 하드 코딩하지 않도록 하려면 대신 GitHub 웹 인터페이스에서 변수 값을 참조한 다음 스크립트에서 변수 이름을 참조할 수 있습니다. 리포지토리 또는 환경(계정 리포지토리)에 대해 암호화된 비밀을 만들 수 있습니다. 자세한 내용은 GitHub Docs의 암호화된 비밀을 참조 하세요.

Django에 대한 고려 사항

이 문서의 앞부분에서 설명한 것처럼 별도의 데이터베이스를 사용하는 경우 GitHub Actions를 사용하여 Linux의 Azure 앱 Service에 Django 앱을 배포할 수 있습니다. App Service에서 db.sqlite3 파일을 잠가 읽기 및 쓰기를 모두 차단하므로 SQLite 데이터베이스를 사용할 수 없습니다. 이 동작은 외부 데이터베이스에 영향을 주지 않습니다.

App Service - 컨테이너 시작 프로세스에서 Python 앱 구성 문서에 설명된 대로 App Service는 앱 코드 내에서 일반적으로 앱 개체를 포함하는 wsgi.py 파일을 자동으로 찾습니다. 이 명령을 사용하여 webapp config set 시작 명령을 설정한 경우 매개 변수를 --startup-file 사용하여 앱 개체가 포함된 파일을 지정했습니다. 웹앱 배포 작업에서는 이 webapp config set 명령을 사용할 수 없습니다. 대신 매개 변수를 startup-command 사용하여 시작 명령을 지정할 수 있습니다. 예를 들어 다음 코드 조각은 워크플로 파일에서 시작 명령을 지정하는 방법을 보여줍니다.

startup-command: startup.txt

Django를 사용하는 경우 일반적으로 앱 코드를 배포한 후 명령을 사용하여 python manage.py migrate 데이터 모델을 마이그레이션하려고 합니다. 배포 후 스크립트에서 마이그레이션 명령을 실행할 수 있습니다.

GitHub Actions 연결 끊기

App Service에서 GitHub Actions의 연결을 끊으면 앱 배포를 다시 구성할 수 있습니다. 연결을 끊은 후 워크플로 파일의 저장 또는 삭제 여부를 선택할 수 있습니다.

Azure CLI az webapp deployment github-actions remove 명령을 사용하여 GitHub Actions 연결을 끊 습니다.

az webapp deployment github-actions remove \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

리소스 정리

이 자습서에서 만든 Azure 리소스에 대한 요금이 발생하지 않도록 하려면 App Service 및 App Service 계획이 포함된 리소스 그룹을 삭제합니다.

Azure Cloud Shell을 포함하여 Azure CLI가 설치된 모든 곳에서 az group delete 명령을 사용하여 리소스 그룹을 삭제할 수 있습니다.

az group delete --name <resource-group-name>

매월 약간의 요금이 발생하는 Cloud Shell의 파일 시스템과 기본 스토리지 계정을 삭제하려면 cloud-shell-storage-시작하는 리소스 그룹을 삭제합니다. 그룹의 유일한 사용자인 경우 리소스 그룹을 삭제해도 안전합니다. 다른 사용자가 있는 경우 리소스 그룹에서 스토리지 계정을 삭제할 수 있습니다.

Azure 리소스 그룹을 삭제한 경우 지속적인 배포를 위해 연결된 GitHub 계정 및 리포지토리를 다음과 같이 수정하는 것이 좋습니다.

  • 리포지토리에서 .github/workflows/<workflow-name.yml> 파일을 제거합니다.
  • 리포지토리 설정에서 워크플로에 대해 만든 AZUREAPPSERVICE_PUBLISHPROFILE_ 비밀 키를 제거합니다.
  • GitHub 계정 설정에서 Azure 앱 Service를 GitHub 계정에 대한 권한 있는 Oauth 앱으로 제거합니다.