Share via


Azure Container Apps 및 PostgreSQL을 사용하여 Python 웹앱 빌드 및 배포

이 문서는 Python 웹앱을 컨테이너화하고 Azure Container Apps에 배포하는 방법에 대한 자습서의 일부입니다. Container Apps를 사용하면 복잡한 인프라를 관리하지 않고 컨테이너화된 앱을 배포할 수 있습니다.

자습서의 이 부분에서는 Python 샘플 웹앱(Django 또는 Flask)을 컨테이너화하고 배포하는 방법을 알아봅니다. 특히 클라우드에서 컨테이너 이미지를 빌드하고 Azure Container Apps에 배포합니다. 컨테이너 앱이 Azure Database for PostgreSQL - 유연한 서버 인스턴스에 연결할 수 있도록 하는 환경 변수를 정의합니다. 여기서 샘플 앱은 데이터를 저장합니다.

이 서비스 다이어그램은 컨테이너 이미지 빌드 및 배포와 같은 이 문서에서 다루는 구성 요소를 강조 표시합니다.

A screenshot of the services in the Tutorial - Deploy a Python App on Azure Container Apps. Section highlighted is what is covered in this article.

샘플 앱 가져오기

샘플 코드를 포크하고 개발자 환경에 복제합니다.

1단계. 샘플 앱(Django 또는 Flask)의 GitHub 리포지토리로 이동하여 포크를 선택합니다.

단계에 따라 디렉터리를 GitHub 계정으로 포크합니다. 포크 또는 GitHub 계정 없이 로컬 컴퓨터에 직접 코드 리포지토리를 다운로드할 수도 있지만 자습서의 뒷부분에서 설명하는 CI/CD를 설정할 수는 없습니다.

2단계. git clone 명령을 사용하여 포크된 리포지토리를 python 컨테이너 폴더에 복제합니다.

# Django
git clone https://github.com/$USERNAME/msdocs-python-django-azure-container-apps.git python-container

# Flask
# git clone https://github.com/$USERNAME/msdocs-python-flask-azure-container-apps.git python-container

3단계 디렉터리를 변경합니다.

cd python-container

웹앱 코드에서 컨테이너 이미지 빌드

다음 단계를 수행하면 샘플 코드에서 빌드된 Docker 컨테이너 이미지가 포함된 Azure Container Registry가 생성됩니다.

Azure CLI 명령은 Azure Cloud Shell에서 실행하거나 Azure CLI가 설치된 워크스테이션에서 실행할 수 있습니다.

1단계. az group create 명령을 사용하여 리소스 그룹을 만듭니다.

az group create \
--name pythoncontainer-rg \
--location <location>

<위치>는 명령az account list-locations -o table의 출력에서 Azure 위치 이름 값 중 하나입니다.

2단계. az acr create 명령을 사용하여 컨테이너 레지스트리를 만듭니 다.

az acr create \
--resource-group pythoncontainer-rg \
--name <registry-name> \
--sku Basic \
--admin-enabled

<registry-name> 은 Azure 내에서 고유해야 하며 5-50자 영숫자를 포함해야 합니다.

다음을 사용하여 관리자용으로 만든 자격 증명을 볼 수 있습니다.

az acr credential show \
--name <registry-name> \
--resource-group pythoncontainer-rg

3단계 az acr login 명령을 사용하여 레지스트리에 로그인 합니다.

az acr login --name <registry-name>

이 명령은 이름에 "azurecr.io"를 추가하여 정규화된 레지스트리 이름을 만듭니다. 성공하면 "로그인 성공"이라는 메시지가 표시됩니다. 레지스트리를 만든 구독과 다른 구독에서 레지스트리에 액세스하는 경우 스위치를 --suffix 사용합니다.

4단계 az acr build 명령을 사용하여 이미지를 빌드 합니다.

az acr build \
--registry <registry-name> \
--resource-group pythoncontainer-rg \
--image pythoncontainer:latest .

다음 사항에 유의합니다.

  • 명령의 끝에 있는 점(".")은 빌드할 소스 코드의 위치를 나타냅니다. 샘플 앱 루트 디렉터리에서 이 명령을 실행하지 않는 경우 코드 경로를 지정합니다.

  • Azure Cloud Shell git clone 에서 명령을 실행하는 경우 먼저 리포지토리를 Cloud Shell 환경으로 끌어오고 디렉터리를 프로젝트의 루트로 변경하여 점(".")이 올바르게 해석되도록 합니다.

  • (동일한--image) 옵션을 제외 -t 하면 명령은 로컬 컨텍스트 빌드를 레지스트리에 푸시하지 않고 큐에 대기합니다. 푸시하지 않고 빌드하면 이미지가 빌드되는 검사 데 유용할 수 있습니다.

5단계 az acr repository list 명령을 사용하여 컨테이너 이미지가 만들어졌는지 확인합니다.

az acr repository list --name <registry-name>

PostgreSQL 유연한 서버 인스턴스 만들기

샘플 앱(Django 또는 Flask)은 PostgreSQL 데이터베이스에 레스토랑 리뷰 데이터를 저장합니다. 이 단계에서는 데이터베이스를 포함할 서버를 만듭니다.

Azure CLI 명령은 Azure Cloud Shell에서 실행하거나 Azure CLI가 설치된 워크스테이션에서 실행할 수 있습니다.

1단계. az postgres flexible-server create 명령을 사용하여 Azure에서 PostgreSQL 서버를 만듭니다. 이 명령이 완료되기까지 몇 분 동안 실행되는 것은 드문 일이 아닙니다.

az postgres flexible-server create \
   --resource-group pythoncontainer-rg \
   --name <postgres-server-name>  \
   --location <location> \
   --admin-user <admin-username> \
   --admin-password <admin-password> \
   --sku-name Standard_D2s_v3 \
   --public-access 0.0.0.0 
  • "pythoncontainer-rg" → 이 자습서에서 사용되는 리소스 그룹 이름입니다. 다른 이름을 사용한 경우 이 값을 변경합니다.

  • <postgres-server-name> → PostgreSQL 데이터베이스 서버 이름입니다. 이 이름은 모든 Azure에서 고유해야 합니다. 서버 엔드포인트는 "https://< postgres-server-name.postgres.database.azure.com>"입니다. 허용되는 문자는 "A"-"Z", "0"-"9" 및 "-"입니다.

  • <location> → 웹앱에 사용되는 동일한 위치를 사용합니다. <위치>는 명령az account list-locations -o table의 출력에서 Azure 위치 이름 값 중 하나입니다.

  • <관리자-사용자 이름> → 관리자 계정의 사용자 이름입니다. "azure_superuser", "admin", "administrator", "root", "guest" 또는 "public"일 수 없습니다. 이 자습서에서는 "demoadmin"을 사용합니다.

  • <admin-password> 관리자 사용자의 암호입니다. 영어 대문자, 영어 소문자, 숫자 및 영숫자가 아닌 문자의 세 가지 범주에서 8~128자를 포함해야 합니다.

    Important

    사용자 이름 또는 암호를 만들 때는 "$" 문자를 사용하지 않습니다 . 나중에 "$" 문자가 Python 앱을 실행하는 데 사용되는 Linux 컨테이너 내에서 특별한 의미를 가지는 이러한 값을 사용하여 환경 변수를 만듭니다.

  • <sku-name> → 가격 책정 계층 및 컴퓨팅 구성의 이름입니다(예: "Standard_D2s_v3"). 자세한 내용은 Azure Database for PostgreSQL 가격 책정을 참조하세요. 사용 가능한 SKU를 나열하려면 .를 사용합니다 az postgres flexible-server list-skus --location <location>.

  • <public-access> → Container Apps와 같은 Azure 서비스에서 서버에 대한 공용 액세스를 허용하는 "0.0.0.0"을 사용합니다.

참고 항목

Azure CLI 이외의 도구를 사용하여 로컬 워크스테이션에서 PostgreSQL 서버를 작업하려는 경우 az postgres flexible-server firewall-rule create 명령을 사용하여 방화벽 규칙을 추가해야 합니다.

서버에 데이터베이스 만들기

이 시점에서 PostgreSQL 서버가 있습니다. 이 섹션에서는 서버에 데이터베이스를 만듭니다.

로컬 환경 또는 Azure Portal에서도 액세스할 수 있는 Azure Cloud Shell에서 PostgreSQL 대화형 터미널 psql을 사용할 수 있습니다. psql을 사용하는 경우 모든 종속성이 셸에 포함되기 때문에 Cloud Shell 을 사용하는 것이 더 쉬운 경우가 많습니다.

1단계. psql을 사용하여 데이터베이스에 커넥트.

psql --host=<postgres-server-name>.postgres.database.azure.com \
     --port=5432 \
     --username=demoadmin@<postgres-server-name> \
     --dbname=postgres

여기서 <postgres-server-name> 은 PostgreSQL 서버의 이름입니다. 이 명령은 관리자 암호를 묻는 메시지를 표시합니다.

연결하는 데 문제가 있는 경우 데이터베이스를 다시 시작하고 다시 시도합니다. 로컬 환경에서 연결하는 경우 IP 주소를 데이터베이스 서비스의 방화벽 규칙 목록에 추가해야 합니다.

2단계. 데이터베이스를 만듭니다.

postgres=> 프롬프트에서 다음을 입력합니다.

CREATE DATABASE restaurants_reviews;

명령의 끝에 있는 세미콜론(";")이 필요합니다. 데이터베이스가 성공적으로 만들어졌는지 확인하려면 명령을 \c restaurants_reviews사용합니다. 도움말을 표시하려면 \?를, 종료하려면 \q를 입력합니다.

Azure PostgreSQL 유연한 서버에 연결하고 Azure Data Studio 또는 PostgreSQL을 지원하는 다른 IDE를 사용하여 데이터베이스를 만들 수도 있습니다.

Container Apps에 웹앱 배포

컨테이너 앱은 보안 경계 역할을 하는 Container Apps 환경에 배포됩니다. 다음 단계에서는 환경, 환경 내의 컨테이너를 만들고 웹 사이트가 외부에 표시되도록 컨테이너를 구성합니다.

1단계. 필요한 경우 Azure에 로그인하고 인증합니다.

az login

2단계. az extension add 명령을 사용하여 Azure Container Apps에 대한 확장을 설치하거나 업그레이드합니다.

az extension add --name containerapp --upgrade

3단계 az containerapp env create 명령을 사용하여 Container Apps 환경을 만듭니 다.

az containerapp env create \
--name python-container-env \
--resource-group pythoncontainer-rg \
--location <location>

<위치>는 명령az account list-locations -o table의 출력에서 Azure 위치 이름 값 중 하나입니다.

4단계 Azure Container Registry에 대한 로그인 자격 증명을 가져옵니다.

az acr credential show -n <registry-name>

명령의 출력에서 반환된 사용자 이름과 암호 중 하나를 사용합니다.

5단계 az containerapp create 명령을 사용하여 환경에서 컨테이너 앱을 만듭니 다.

az containerapp create \
--name python-container-app \
--resource-group pythoncontainer-rg \
--image <registry-name>.azurecr.io/pythoncontainer:latest \
--environment python-container-env \
--ingress external \
--target-port 8000 \
--registry-server <registry-name>.azurecr.io \
--registry-username <registry-username> \
--registry-password <registry-password> \
--env-vars <env-variable-string>
--query properties.configuration.ingress.fqdn

<env-variable-string> 은 다음 값을 가진 key="value" 형식의 공백으로 구분된 값으로 구성된 문자열입니다.

  • AZURE_POSTGRESQL_HOST=<postgres-server-name.postgres.database.azure.com>
  • AZURE_POSTGRESQL_DATABASE=restaurants_reviews
  • AZURE_POSTGRESQL_USERNAME=demoadmin
  • AZURE_POSTGRESQL_PASSWORD=<db-password>
  • RUNNING_IN_PRODUCTION=1
  • AZURE_SECRET_KEY=<YOUR-SECRET-KEY>

의 출력python -c 'import secrets; print(secrets.token_hex())'을 사용하여 값 생성 AZURE_SECRET_KEY

예: --env-vars AZURE_POSTGRESQL_HOST="my-postgres-server.postgres.database.azure.com" AZURE_POSTGRESQL_DATABASE="restaurants_reviews" AZURE_POSTGRESQL_USERNAME="demoadmin" AZURE_POSTGRESQL_PASSWORD="somepassword" RUNNING_IN_PRODUCTION="1" AZURE_SECRET_KEY=asdfasdfasdf.

7단계 Django 전용으로 데이터베이스 스키마를 마이그레이션하고 만듭니다. (Flask 샘플 앱에서는 자동으로 수행되며 이 단계를 건너뛸 수 있습니다.)

az containerapp exec 명령을 사용하여 커넥트.

az containerapp exec \
--name python-container-app \
--resource-group pythoncontainer-rg

그런 다음, 셸 명령 프롬프트에서 python manage.py migrate.

컨테이너의 수정 버전을 마이그레이션할 필요가 없습니다.

8단계. 웹 사이트를 테스트합니다.

az containerapp create 이전에 입력한 명령은 앱을 탐색하는 데 사용할 수 있는 애플리케이션 URL을 출력합니다. URL은 "azurecontainerapps.io"로 끝납니다. 브라우저에서 URL로 이동합니다. 또는 az containerapp browse 명령을 사용할 수 있습니다.

다음은 레스토랑과 두 개의 리뷰를 추가한 후 샘플 웹 사이트의 예입니다.

Screenshot showing an example of the sample website built in this tutorial.

배포 문제 해결

  • 웹 사이트에 액세스하기 위한 애플리케이션 URL을 잊어버렸습니다.

    • Azure Portal에서 컨테이너 앱의 개요 페이지로 이동하여 애플리케이션 URL찾습니다.
    • VS Code에서 Azure 확장으로 이동하여 Container Apps 섹션을 선택합니다. 구독을 확장하고, 컨테이너 환경을 확장하고, 컨테이너 앱을 찾으면 python-container-app을 마우스 오른쪽 단추로 클릭하고 찾아보기를 선택합니다.
    • Azure CLI에서 az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn 명령을 사용합니다.
  • VS Code 에서 Azure 작업의 빌드 이미지는 오류를 반환합니다.

    • "오류: 컨텍스트를 다운로드하지 못했습니다. URL이 올바르지 않으면 검사." VS Code 출력 창에서 Docker 확장에서 레지스트리를 새로 고칩니다. 새로 고치려면 Docker 확장을 선택하고 레지스트리 섹션으로 이동하여 레지스트리를 찾아 선택합니다.
    • Azure 작업에서 빌드 이미지를 다시 실행하는 경우 검사 이전 실행의 레지스트리가 있는지 확인하고 있는 경우 사용합니다.
  • 컨테이너 앱을 만드는 동안 Azure Portal에 "ACR '<name.azurecr.io>'에 액세스할 수 없음"이 포함된 액세스 오류가 표시됩니다.

    • 이 오류는 ACR의 관리자 자격 증명을 사용하지 않도록 설정할 때 발생합니다. 포털에서 관리자 상태 검사 Azure Container Registry로 이동하여 액세스 키 리소스를 선택하고 관리 사용자가 사용하도록 설정되어 있는지 확인 합니다.
  • 컨테이너 이미지는 Azure Container Registry에 표시되지 않습니다.

    • Azure CLI 명령 또는 VS Code 출력의 출력을 확인하고 성공을 확인하는 메시지를 찾습니다.
    • Azure CLI를 사용하여 빌드 명령이나 VS Code 작업 프롬프트에서 레지스트리 이름이 올바르게 지정되었는지 확인합니다.
    • 자격 증명이 만료되지 않았는지 확인합니다. 예를 들어 VS Code에서 Docker 확장에서 대상 레지스트리를 찾아 새로 고칩니다. Azure CLI에서 .를 실행합니다 az login.
  • 웹 사이트는 "잘못된 요청(400)"을 반환합니다.

    • 컨테이너에 전달된 PostgreSQL 환경 변수를 확인합니다. 400 오류는 Python 코드가 PostgreSQL 인스턴스에 연결할 수 없음을 나타내는 경우가 많습니다.
    • 이 자습서에서 사용되는 샘플 코드는 "1"와 같은 값으로 설정할 수 있는 컨테이너 환경 변수RUNNING_IN_PRODUCTION의 존재에 대한 검사.
  • 웹 사이트는 "찾을 수 없음(404)"을 반환합니다.

    • 컨테이너의 개요 페이지에서 애플리케이션 URL 을 확인합니다. 애플리케이션 URL에 "internal"라는 단어가 포함되어 있으면 수신이 올바르게 설정되지 않습니다.
    • 컨테이너의 수신을 확인합니다. 예를 들어 Azure Portal에서 컨테이너의 수신 리소스로 이동하여 HTTP 수신을 사용하도록 설정하고 어디서나 트래픽 허용이 선택되어 있는지 확인합니다.
  • 웹 사이트가 시작되지 않거나 "스트림 시간 제한"이 표시되거나 아무것도 반환되지 않습니다.

    • 로그를 확인합니다.
      • Azure Portal에서 컨테이너 앱의 수정 버전 관리 리소스로 이동하여 컨테이너의 프로비전 상태를 검사.
        • "프로비전"이면 프로비전이 완료될 때까지 기다립니다.
        • "실패"이면 수정 버전을 선택하고 콘솔 로그를 봅니다. 열의 순서를 선택하여 "생성 시간", "Stream_s" 및 "Log_s"을 표시합니다. 가장 최근의 로그를 먼저 정렬하고 "Stream_s" 열에서 Python stderrstdout 메시지를 찾습니다. Python 'print' 출력은 stdout 메시지입니다.
      • Azure CLI를 사용하여 az containerapp logs show 명령을 사용합니다.
    • Django 프레임워크를 사용하는 경우 검사 restaurants_reviews 테이블이 데이터베이스에 있는지 확인합니다. 그렇지 않은 경우 콘솔을 사용하여 컨테이너에 액세스하고 실행 python manage.py migrate합니다.

다음 단계