이 문서에서는 Azure App Service 에서 Python 앱을 실행하는 방법, 기존 앱을 Azure로 마이그레이션하는 방법 및 필요할 때 App Service의 동작을 사용자 지정하는 방법을 설명합니다. Python 앱은 필요한 모든 pip 모듈과 함께 배포되어야 합니다.
App Service 배포 엔진은 자동으로 가상 환경을 활성화하고 pip install -r requirements.txt
를 배포하거나 빌드 자동화를 사용하도록 설정된zip 패키지를 배포할 때 자동으로 실행됩니다.
참고
현재 App Service에서는 requirements.txt
이 있더라도 프로젝트 루트 디렉터리에 pyproject.toml
가 필요합니다. 권장 방법은 pyproject.toml에서 requirements.txt 생성을 참조하세요.
이 가이드에서는 App Service의 기본 제공 Linux 컨테이너를 사용하는 Python 개발자를 위한 주요 개념과 지침을 제공합니다. Azure App Service를 사용한 적이 없는 경우 먼저 PostgreSQL 자습서를 사용하여 Python 빠른 시작 및 Flask, Django 또는 FastAPI 를 따릅니다.
구성에 Azure Portal 또는 Azure CLI를 사용할 수 있습니다.
Azure 포털에서 앱의 설정>구성 페이지를 Azure 포털에서 App Service 앱 구성에 설명된 대로 사용합니다.
Azure CLI: 두 가지 옵션이 있습니다.
- Azure Cloud Shell에서 명령을 실행합니다.
- 최신 버전의 Azure CLI를 설치하여 로컬로 명령을 실행한 다음 az login을 사용하여 Azure에 로그인합니다.
참고
Linux는 App Service에서 Python 앱을 실행하는 유일한 운영 체제 옵션입니다. Windows의 Python은 더 이상 지원되지 않습니다. 그러나 사용자 지정 Windows 컨테이너 이미지를 직접 빌드하여 App Service에서 실행할 수 있습니다. 자세한 내용은 사용자 지정 Docker 이미지 사용을 참조하세요.
Python 버전 구성
Azure Portal: Linux 컨테이너에 대한 일반 설정 구성에 설명된 대로 구성 페이지의 일반 설정 탭을 사용합니다.
Azure CLI:
az webapp config show를 사용하여 현재 Python 버전을 표시합니다.
az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion
<resource-group-name>
및<app-name>
을 웹앱에 적합한 이름으로 바꿉니다.az webapp config set을 사용하여 Python 버전 설정
az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "PYTHON|3.11"
az webapp list-runtimes를 사용하여 Azure App Service에서 지원되는 모든 Python 버전을 표시합니다.
az webapp list-runtimes --os linux | grep PYTHON
사용자 고유의 컨테이너 이미지를 빌드하여 지원되지 않는 Python 버전을 실행할 수도 있습니다. 자세한 내용은 사용자 지정 Docker 이미지 사용을 참조하세요.
App Service에서 오래된 런타임은 어떻게 되나요?
오래된 런타임은 유지 관리 조직에서 더 이상 사용되지 않거나 심각한 취약성이 있는 것으로 확인됩니다. 따라서 포털의 만들기 및 구성 페이지에서 제거됩니다. 오래된 런타임이 포털에서 숨겨지면 해당 런타임을 계속 사용하는 모든 앱이 계속 실행됩니다.
더 이상 포털에 표시되지 않는 오래된 런타임 버전으로 앱을 만들려면 Azure CLI, ARM 템플릿 또는 Bicep을 사용합니다. 이러한 배포 대안을 사용하면 포털에서 제거되었지만 여전히 지원되는 사용되지 않는 런타임을 만들 수 있습니다.
런타임이 App Service 플랫폼에서 완전히 제거된 경우 Azure 구독 소유자는 제거 전에 이메일 알림을 받습니다.
빌드 자동화 사용자 지정
참고
Python 애플리케이션이 빌드 자동화로 배포되는 경우, 콘텐츠는 /tmp/<uid>
가 아닌 /home/site/wwwroot
에서 배포되고 제공됩니다. 이 콘텐츠 디렉터리는 APP_PATH
환경 변수를 통해 액세스할 수 있습니다. 런타임에 생성된 추가 파일은 지속성을 위해 /home
아래 또는 사용 중인 위치에 기록되어야 합니다. 이 동작에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
앱 설정 SCM_DO_BUILD_DURING_DEPLOYMENT
이(가) 1
(으)로 설정된 경우 App Service의 빌드 시스템인 Oryx는 앱을 배포할 때 다음 단계를 수행합니다.
해당 단계가
PRE_BUILD_COMMAND
설정에 의해 지정된 경우 사용자 지정 빌드 전 스크립트를 실행합니다. (스크립트는 다른 Python 및 Node.js 스크립트, pip 및 npm 명령, yarn과 같은 노드 기반 도구(예:yarn install
및yarn build
)를 실행할 수 있습니다.)pip install -r requirements.txt
를 실행합니다. requirements.txt 파일은 프로젝트의 루트 폴더에 있어야 합니다. 그렇지 않으면 빌드 프로세스에서 "setup.py 또는 requirements.txt를 찾을 수 없습니다. pip install을 실행하고 있지 않습니다."라는 오류가 보고됩니다.리포지토리의 루트(Django 앱 표시)에 manage.py 있는 경우 collectstatic을 manage.py 실행합니다. 그러나
DISABLE_COLLECTSTATIC
설정이true
인 경우 이 단계를 건너뜁니다.해당 단계가
POST_BUILD_COMMAND
설정에 의해 지정된 경우 사용자 지정 빌드 후 스크립트를 실행합니다. (또한, 이 스크립트는 다른 Python 및 Node.js 스크립트, pip 및 npm 명령, 노드 기반 도구를 실행할 수 있습니다.)
기본적으로 PRE_BUILD_COMMAND
, POST_BUILD_COMMAND
및 DISABLE_COLLECTSTATIC
설정은 비어 있습니다.
Django 앱을 빌드할 때 collectstatic을 실행하지 않도록 설정하려면
DISABLE_COLLECTSTATIC
설정을true
로 설정합니다.빌드 전 명령을 실행하려면
PRE_BUILD_COMMAND
같은 명령 또는echo Pre-build command
같은 프로젝트 루트를 기준으로 스크립트 파일의 경로를 포함하도록scripts/prebuild.sh
설정을 설정합니다. 모든 명령은 프로젝트 루트 폴더에 대한 상대 경로를 사용해야 합니다.빌드 후 명령을 실행하려면
POST_BUILD_COMMAND
같은 명령 또는echo Post-build command
같은 프로젝트 루트를 기준으로 스크립트 파일의 경로를 포함하도록scripts/postbuild.sh
설정을 설정합니다. 모든 명령은 프로젝트 루트 폴더에 대한 상대 경로를 사용해야 합니다.
빌드 자동화를 사용자 지정하는 다른 설정은 Oryx 구성을 참조하세요.
빌드 및 배포 로그에 액세스하려면 Access 배포 로그를 참조하세요.
App Service가 Linux에서 Python 앱을 실행하고 빌드하는 방법에 대한 자세한 내용은 Oryx가 Python 앱을 검색하고 빌드하는 방법을 참조하세요.
참고
PRE_BUILD_SCRIPT_PATH
및 POST_BUILD_SCRIPT_PATH
설정은 PRE_BUILD_COMMAND
및 POST_BUILD_COMMAND
와 동일하며 레거시 용도로 지원됩니다.
SCM_DO_BUILD_DURING_DEPLOYMENT
또는 true
을(를) 포함하는 경우 1
(이)라는 설정은 배포 중에 발생하는 Oryx 빌드를 트리거합니다. 이 설정은 Git, Azure CLI 명령 true
및 Visual Studio Code를 사용하여 배포할 때 az webapp up
입니다.
참고
Oryx가 실행되는 빌드 컨테이너는 앱이 실행되는 런타임 컨테이너와 다르므로 모든 빌드 전 및 빌드 후 스크립트에서 항상 상대 경로를 사용해야 합니다. 컨테이너 내에서 앱 프로젝트 폴더의 정확한 배치를 사용하지 마세요(예: 사이트/wwwroot 아래에 배치됨).
pyproject.toml에서 requirements.txt를 생성합니다.
App Service는 현재 pyproject.toml
을 직접 지원하지 않습니다. Poetry나 uv와 같은 도구를 사용하는 경우 권장되는 방식은 프로젝트 루트에 배포하기 전에 호환되는 requirements.txt
를 생성하는 것입니다.
Poetry 사용
poetry export -f requirements.txt --output requirements.txt --without-hashes
uv 사용
uv 사용:
uv export --format requirements-txt --no-hashes --output-file requirements.txt
기존 애플리케이션을 Azure로 마이그레이션
기존 웹 애플리케이션은 다음과 같이 Azure에 다시 배포할 수 있습니다.
원본 리포지토리: GitHub와 같은 적합한 리포지토리에서 소스 코드를 유지 관리하므로 이 프로세스의 뒷부분에서 지속적인 배포를 설정할 수 있습니다.
- 필요한 패키지를 자동으로 설치하려면 requirements.txt 파일이 App Service에 대한 리포지토리의 루트에 있어야 합니다.
데이터베이스: 앱이 데이터베이스에 의존하는 경우 Azure에서도 필요한 리소스를 만듭니다.
App Service 리소스: 애플리케이션을 호스트할 리소스 그룹, App Service 계획 및 App Service 웹앱을 만듭니다. Azure CLI 명령
az webapp up
을(를) 실행하여 이 작업을 쉽게 수행할 수 있습니다. 또는 PostgreSQL 자습서를 사용하여 Flask, Django 또는 FastAPI 에 표시된 대로 리소스를 만들고 배포할 수 있습니다. 애플리케이션에 더 적합하도록 리소스 그룹, App Service 계획 및 웹앱의 이름을 바꿉니다.환경 변수: 애플리케이션에 환경 변수가 필요한 경우 동등한 App Service 애플리케이션 설정을 만듭니다. 이러한 App Service 설정은 Access 환경 변수에 설명된 대로 코드에 환경 변수로 표시됩니다.
- 예를 들어 데이터베이스 연결은 자습서: PostgreSQL을 사용하여 Django 웹앱 배포 - 연결 설정 확인에 표시된 것처럼 이러한 설정을 통해 관리되는 경우가 많습니다.
- 일반적인 Django 앱에 대한 특정 설정은 Django 앱 에 대한 프로덕션 설정을 참조하세요.
앱 시작: 이 문서의 뒷부분에 있는 컨테이너 시작 프로세스 섹션을 검토하여 App Service에서 앱을 실행하는 방법을 이해합니다. App Service는 기본적으로 Gunicorn 웹 서버를 사용하며, 앱 개체 또는 wsgi.py 폴더를 찾을 수 있어야 합니다. 필요한 경우 시작 명령을 사용자 지정할 수 있습니다.
지속적인 배포: Azure App Service에 대한 지속적인 배포 문서에 설명된 대로 GitHub Actions, Bitbucket 또는 Azure Repos에서 지속적인 배포를 설정합니다. 또는 로컬 Git 배포 문서에 설명된 대로 로컬 Git에서 Azure App Service로 지속적인 배포를 설정합니다.
사용자 지정 작업: Django 데이터베이스 마이그레이션과 같이 앱을 호스트하는 App Service 컨테이너 내에서 작업을 수행하려면 SSH를 통해 컨테이너에 연결할 수 있습니다. Django 데이터베이스 마이그레이션을 실행하는 예제는 자습서: PostgreSQL을 사용하여 Django 웹앱 배포 - 데이터베이스 스키마 생성을 참조하세요.
- 연속 배포를 사용하는 경우 빌드 자동화 사용자 지정의 앞부분에서 설명한 대로 빌드 후 명령을 사용하여 이러한 작업을 수행할 수 있습니다.
이러한 단계가 완료되면 변경 내용을 원본 리포지토리에 커밋하고 해당 업데이트가 App Service에 자동으로 배포되도록 할 수 있습니다.
Django 앱의 프로덕션 설정
Azure App Service와 같은 프로덕션 환경의 경우 Django 앱은 Django의 배포 검사 목록을 따라야 합니다.
다음 표에는 Azure와 관련된 프로덕션 설정이 설명되어 있습니다. 이러한 설정은 앱의 setting.py 파일에 정의됩니다.
Django 설정 | Azure에 대한 지침 |
---|---|
SECRET_KEY |
Access 앱 설정에 설명된 대로 App Service 설정에 값을 환경 변수로 저장합니다. 또는 Azure Key Vault에 값을 비밀로 저장할 수 있습니다. |
DEBUG |
App Service에서 값이 0(false)인 DEBUG 설정을 만든 다음, 해당 값을 환경 변수로 로드합니다. 개발 환경에서 값이 1(true)인 DEBUG 환경 변수를 만듭니다. |
ALLOWED_HOSTS |
프로덕션에서 Django는 앱의 URL을 settings.py 배열에 ALLOWED_HOSTS 포함해야 합니다. 코드 os.environ['WEBSITE_HOSTNAME'] 을 사용한 런타임에 이 URL을 검색할 수 있습니다. App Service는 자동으로 WEBSITE_HOSTNAME 환경 변수를 앱의 URL로 설정합니다. |
DATABASES |
App Service에서 데이터베이스 연결에 대한 설정을 정의한 다음, 해당 설정을 환경 변수로 로드하여 DATABASES 사전을 채웁니다. 또는 값(특히 사용자 이름 및 암호)을 Azure Key Vault 비밀로 저장할 수 있습니다. |
Django 앱용 정적 파일 제공
Django 웹앱에 정적 프런트 엔드 파일이 포함된 경우 먼저 Django 설명서의 정적 파일 관리에 대한 지침을 따릅니다.
App Service의 경우 다음과 같이 수정합니다.
환경 변수(로컬 개발의 경우) 및 앱 설정(클라우드에 배포하는 경우)을 사용하여 Django
STATIC_URL
및STATIC_ROOT
변수를 동적으로 설정하는 것이 좋습니다. 예를 들면 다음과 같습니다.STATIC_URL = os.environ.get("DJANGO_STATIC_URL", "/static/") STATIC_ROOT = os.environ.get("DJANGO_STATIC_ROOT", "./static/")
DJANGO_STATIC_URL
및DJANGO_STATIC_ROOT
는 로컬 및 클라우드 환경에 따라 변경할 수 있습니다. 예를 들어 정적 파일의 빌드 프로세스에서 파일을django-static
이라는 폴더에 배치하는 경우 기본값을 사용하지 않도록DJANGO_STATIC_URL
을/django-static/
으로 설정할 수 있습니다.다른 폴더에 정적 파일을 생성하는 빌드 전 스크립트가 있는 경우 Django의
STATICFILES_DIRS
프로세스에서 찾을 수 있도록 해당 폴더를 Djangocollectstatic
변수에 포함합니다. 예를 들어 프런트 엔드 폴더에서yarn build
를 실행하고 yarn에서 정적 파일을 포함하는build/static
폴더를 생성하는 경우 다음과 같이 해당 폴더를 포함합니다.FRONTEND_DIR = "path-to-frontend-folder" STATICFILES_DIRS = [os.path.join(FRONTEND_DIR, 'build', 'static')]
여기서는
FRONTEND_DIR
yarn과 같은 빌드 도구가 실행되는 경로를 빌드하는 데 사용됩니다. 원하는 대로 환경 변수 및 앱 설정을 다시 사용할 수 있습니다.whitenoise
을 requirements.txt 파일에 추가합니다. WhiteNoise (whitenoise.evans.io)는 프로덕션 Django 앱이 자체 정적 파일을 간단하게 제공할 수 있도록 하는 Python 패키지입니다. WhiteNoise는 특히 DjangoSTATIC_ROOT
변수로 지정된 폴더에 있는 파일을 제공합니다.settings.py 파일에서 WhiteNoise에 대해 다음 줄을 추가합니다.
STATICFILES_STORAGE = ('whitenoise.storage.CompressedManifestStaticFilesStorage')
또한 WhiteNoise를 포함하도록
MIDDLEWARE
및INSTALLED_APPS
목록을 수정합니다.MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # Add whitenoise middleware after the security middleware 'whitenoise.middleware.WhiteNoiseMiddleware', # Other values follow ] INSTALLED_APPS = [ "whitenoise.runserver_nostatic", # Other values follow ]
Flask 앱용 정적 파일 제공
Flask 웹앱에 정적 프런트 엔드 파일이 포함된 경우 먼저 Flask 설명서의 정적 파일 관리에 대한 지침을 따릅니다. Flask 애플리케이션에서 정적 파일을 제공하는 예제는 GitHub의 샘플 Flask 애플리케이션 을 참조하세요.
애플리케이션의 경로에서 직접 정적 파일을 제공하려면 send_from_directory
메서드를 사용할 수 있습니다.
from flask import send_from_directory
@app.route('/reports/<path:path>')
def send_report(path):
return send_from_directory('reports', path)
컨테이너 특성
App Service에 배포되면 Python 앱은 App Service Python GitHub 리포지토리에 정의된 Linux Docker 컨테이너 내에서 실행됩니다. 버전별 디렉터리 내에서 이미지 구성을 찾을 수 있습니다.
이 컨테이너에는 다음과 같은 특성이 있습니다.
앱은 추가 인수를 사용하여
--bind=0.0.0.0 --timeout 600
사용하여 실행됩니다.시작 명령을 사용자 지정하여 Gunicorn에 대한 구성 설정을 제공할 수 있습니다.
우발적이거나 의도적인 DDOS 공격으로부터 웹앱을 보호하기 위해 Gunicorn은 Gunicorn 배포에 설명된 대로 Nginx 역방향 프록시 뒤에서 실행됩니다.
기본적으로 기본 컨테이너 이미지에는 Flask 웹 프레임워크만 포함되지만, 컨테이너는 WSGI 및 Python 3.6 이상과 호환되는 다른 프레임워크(예: Django)를 지원합니다.
Django와 같은 다른 패키지를 설치하려면 직접 종속성을 지정하는 프로젝트 루트에 requirements.txt 파일을 만듭니다. 그러면 프로젝트를 배포할 때 App Service에서 이러한 종속성을 자동으로 설치합니다.
종속성을 설치하려면 requirements.txt 파일이 프로젝트 루트에 있어야 합니다 . 그렇지 않으면 빌드 프로세스에서 "setup.py 또는 requirements.txt를 찾을 수 없습니다. pip install을 실행하고 있지 않습니다."라는 오류가 보고됩니다. 이 오류가 발생하는 경우 요구 사항 파일의 위치를 확인합니다.
App Service는 웹앱의 URL을 사용하여
WEBSITE_HOSTNAME
이라는 환경 변수를 자동으로 정의합니다(예:msdocs-hello-world.azurewebsites.net
). 또한 앱 이름을 사용하여WEBSITE_SITE_NAME
을 정의합니다(예:msdocs-hello-world
).npm 및 Node.js는 컨테이너에 설치되므로 yarn과 같은 노드 기반 빌드 도구를 실행할 수 있습니다.
컨테이너 시작 프로세스
시작하는 동안 Linux의 App Service 컨테이너에서 실행하는 단계는 다음과 같습니다.
- 사용자 지정 시작 명령(제공된 경우)을 사용합니다.
- Django 앱이 있는지 확인하고, 검색된 경우 Gunicorn을 시작합니다.
- Flask 앱이 있는지 확인하고, 감지된 경우 Gunicorn을 시작합니다.
- 다른 앱이 없으면 컨테이너에 기본적으로 제공되는 기본 앱을 시작합니다.
다음 섹션에서는 각 옵션에 대한 추가 세부 정보를 제공합니다.
Django 앱
Django 앱의 경우 App Service는 앱 코드 내에서 wsgi.py
라는 파일을 찾고, 다음 명령을 사용하여 Gunicorn을 실행합니다.
# <module> is the name of the folder that contains wsgi.py
gunicorn --bind=0.0.0.0 --timeout 600 <module>.wsgi
시작 명령을 보다 구체적으로 제어하려면 사용자 지정 시작 명령을 사용하고, <module>
wsgi.py 포함된 폴더의 이름으로 바꾸고, 해당 모듈이 프로젝트 루트에 없는 경우 인수를 추가 --chdir
합니다. 예를 들어 wsgi.py 프로젝트 루트의 knboard/backend/config 아래에 있는 경우 인수 --chdir knboard/backend config.wsgi
를 사용합니다.
프로덕션 로깅을 사용하도록 설정하려면 --access-logfile
및 --error-logfile
매개 변수를 추가하고, 사용자 지정 시작 명령의 예제를 참조하세요.
Flask 앱
Flask의 경우 App Service는 application.py 또는 app.py 파일을 찾고 다음과 같이 Gunicorn을 시작합니다.
# If application.py
gunicorn --bind=0.0.0.0 --timeout 600 application:app
# If app.py
gunicorn --bind=0.0.0.0 --timeout 600 app:app
기본 앱 모듈이 다른 파일에 포함된 경우 앱 개체에 다른 이름을 사용합니다. Gunicorn에 다른 인수를 제공하려면 사용자 지정 시작 명령을 사용합니다.
기본 동작
App Service에서 사용자 지정 명령, Django 앱 또는 Flask 앱을 찾을 수 없는 경우 opt/defaultsite 폴더에 있으며 다음 이미지에 표시된 기본 읽기 전용 앱을 실행합니다.
코드를 배포하고 기본 앱이 계속 표시되는 경우 문제 해결 - 앱이 표시되지 않음을 참조하세요.
시작 명령 사용자 지정
사용자 지정 시작 명령을 제공하거나 시작 명령 파일의 여러 명령을 제공하여 컨테이너의 시작 동작을 제어할 수 있습니다. 시작 명령 파일은 startup.sh, startup.cmd, startup.txt 등 원하는 이름을 사용할 수 있습니다.
모든 명령은 프로젝트 루트 폴더에 대한 상대 경로를 사용해야 합니다.
시작 명령 또는 명령 파일을 지정하는 방법은 다음과 같습니다.
Azure Portal: 앱의 구성 페이지를 선택한 다음 일반 설정을 선택합니다. 시작 명령 필드에 시작 명령의 전체 텍스트 또는 시작 명령 파일의 이름을 배치합니다. 그런 다음 저장 을 선택하여 변경 내용을 적용합니다. Linux 컨테이너에 대한 일반 설정 구성 을 참조하세요.
Azure CLI: az webapp config set 명령을 매개 변수와 함께
--startup-file
사용하여 시작 명령 또는 파일을 설정합니다.az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<custom-command>"
<custom-command>
를 시작 명령의 전체 텍스트 또는 시작 명령 파일의 이름으로 바꿉니다.
App Service는 사용자 지정 시작 명령 또는 파일을 처리할 때 발생하는 모든 오류를 무시한 다음, Django 및 Flask 앱을 찾아 시작 프로세스를 계속 진행합니다. 예상하는 동작이 발생하지 않는 경우 시작 명령 또는 파일이 오류 없이 작동하고 시작 명령 파일이 앱 코드와 함께 App Service에 배포되었는지 확인합니다. 진단 로그에서 자세한 내용을 확인할 수도 있습니다. 또한 Azure Portal에서 앱의 진단 및 문제 해결 페이지를 확인합니다.
시작 명령 예
Gunicorn 인수 추가: 다음 예제에서는 Django 앱을 시작하기 위한 Gunicorn 명령줄에 인수를 추가
--workers=4
합니다.# <module-path> is the relative path to the folder that contains the module # that contains wsgi.py; <module> is the name of the folder containing wsgi.py. gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi
자세한 내용은 Gunicorn 실행을 참조하세요. 자동 크기 조정 규칙을 사용하여 웹앱을 확장 및 축소하는 경우 시작 명령에서
NUM_CORES
환경 변수(예:--workers $((($NUM_CORES*2)+1))
)를 사용하여 Gunicorn 작업자 수를 동적으로 설정해야 합니다. 권장되는 Gunicorn 근로자 수를 설정하는 방법에 대한 자세한 내용은 Gunicorn FAQ를 참조하세요.Django에 대한 프로덕션 로깅 사용: 명령줄에
--access-logfile '-'
인수 및--error-logfile '-'
인수를 추가합니다.# '-' for the log files means stdout for --access-logfile and stderr for --error-logfile. gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi --access-logfile '-' --error-logfile '-'
이러한 로그는 App Service 로그 스트림에 표시됩니다.
자세한 내용은 Gunicorn 로깅을 참조하세요.
사용자 지정 Flask 주 모듈: 기본적으로 App Service는 Flask 앱의 주 모듈이 application.py 또는 app.py 가정합니다. 기본 모듈이 다른 이름을 사용하는 경우 시작 명령을 사용자 지정해야 합니다. 예를 들어 기본 모듈이 hello.py Flask 앱이 있고 해당 파일의 Flask 앱 개체 이름이 지정된
myapp
경우 명령은 다음과 같습니다.gunicorn --bind=0.0.0.0 --timeout 600 hello:myapp
기본 모듈이 하위 폴더(예:
website
)인 경우--chdir
인수로 이 폴더를 지정합니다.gunicorn --bind=0.0.0.0 --timeout 600 --chdir website hello:myapp
Gunicorn이 아닌 서버 사용: aiohttp와 같은 다른 웹 서버를 사용하려면 시작 명령 또는 시작 명령 파일에서 적절한 명령을 사용합니다.
python3.7 -m aiohttp.web -H localhost -P 8080 package.module:init_func
앱 설정에 환경 변수로 액세스
앱 설정은 앱 구성 설정에 설명된 대로 앱용으로 클라우드에 저장된 값입니다. 이러한 설정은 앱 코드에서 환경 변수로 사용할 수 있으며 표준 os.environ 패턴을 사용하여 액세스합니다.
예를 들어 DATABASE_SERVER
라는 앱 설정을 만든 경우 다음 코드는 해당 설정의 값을 검색합니다.
db_server = os.environ['DATABASE_SERVER']
HTTPS 세션 검색
App Service에서 TLS/SSL 종료 는 네트워크 부하 분산 장치에서 발생하므로 모든 HTTPS 요청은 암호화되지 않은 HTTP 요청으로 앱에 도달합니다. 앱 논리에서 사용자 요청의 암호화 여부를 확인해야 하는 경우 X-Forwarded-Proto
헤더를 검사합니다.
if 'X-Forwarded-Proto' in request.headers and request.headers['X-Forwarded-Proto'] == 'https':
# Do something when HTTPS is used
인기 있는 웹 프레임워크를 사용하여 표준 앱 패턴의 X-Forwarded-*
정보에 액세스할 수 있습니다. 예를 들어 Django에서 SECURE_PROXY_SSL_HEADER 사용하여 Django에 헤더를 사용하도록 X-Forwarded-Proto
지시할 수 있습니다.
진단 로그 액세스
컨테이너 내부에서 생성된 콘솔 로그에 액세스할 수 있습니다.
컨테이너 로깅을 켜려면 다음 명령을 실행합니다.
az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem
<app-name>
과 <resource-group-name>
을 웹앱에 적절한 이름으로 바꿉니다.
컨테이너 로깅을 켠 후 다음 명령을 실행하여 로그 스트림을 확인합니다.
az webapp log tail --name <app-name> --resource-group <resource-group-name>
콘솔 로그가 즉시 나타나지 않으면 30초 후에 다시 확인합니다.
언제든지 로그 스트리밍을 중지하려면 Ctrl+를 선택합니다.
Azure Portal을 통해 로그에 액세스하려면 앱의 왼쪽 메뉴에서 모니터링>로그 스트림 을 선택합니다.
배포 로그 액세스
코드를 배포할 때 App Service는 빌드 자동화 사용자 지정 섹션의 앞부분에서 설명한 빌드 프로세스를 수행합니다. 빌드는 자체 컨테이너에서 실행되기 때문에 빌드 로그는 앱의 진단 로그와 별도로 저장됩니다.
다음 단계에 따라 배포 로그에 액세스합니다.
- 웹앱에 대한 Azure Portal의 왼쪽 메뉴에서 배포>배포 센터를 선택합니다.
- 로그 탭에서 가장 최근 커밋에 대한 커밋 ID를 선택합니다.
- 표시되는 로그 세부 정보 페이지에서 "oryx 빌드 실행 중..." 옆에 표시되는 로그 표시 링크를 선택합니다.
requirements.txt 잘못된 종속성 및 빌드 전 또는 빌드 후 스크립트의 오류와 같은 빌드 문제가 이러한 로그에 표시됩니다. 요구 사항 파일의 이름이 requirements.txt 없거나 프로젝트의 루트 폴더에 표시되지 않는 경우에도 오류가 표시됩니다.
브라우저에서 SSH 세션 열기
컨테이너를 사용하여 직접 SSH 세션을 열려면 앱이 실행 중이어야 합니다.
az webapp ssh 명령을 사용합니다.
아직 인증을 받지 못한 경우 연결하기 위해서는 Azure 구독에서 인증을 받아야 합니다. 인증되면 컨테이너 내부에서 명령을 실행할 수 있는 브라우저 내부 셸을 확인합니다.
참고
디렉터리 외부에서 /home
변경한 내용은 컨테이너 자체에 저장되며 앱 다시 시작 후에도 유지되지 않습니다.
로컬 컴퓨터에서 원격 SSH 세션을 열려면 원격 셸에서 SSH 세션 열기를 참조하세요.
SSH 세션에 성공적으로 연결되면 창 아래쪽에 "SSH 연결 설정됨"이라는 메시지가 표시됩니다. "SSH_CONNECTION_CLOSED" 또는 컨테이너가 다시 시작 중이라는 메시지와 같은 오류가 표시되면 앱 컨테이너가 시작되지 않을 수 있습니다. 가능한 문제를 조사하는 단계는 문제 해결 을 참조하세요.
URL 다시 쓰기
Linux용 Azure App Service에 Python 애플리케이션을 배포할 때 애플리케이션 내에서 URL 다시 쓰기를 처리해야 할 수 있습니다. 이는 외부 웹 서버 구성에 의존하지 않고 특정 URL 패턴이 올바른 엔드포인트로 리디렉션되도록 하는 데 특히 유용합니다. Flask 애플리케이션의 경우 URL 프로세서 및 사용자 지정 미들웨어를 사용하여 이를 달성할 수 있습니다. Django 애플리케이션에서 강력한 URL 디스패처 를 사용하면 URL 재작성을 효율적으로 관리할 수 있습니다.
문제 해결
일반적으로 문제 해결의 첫 번째 단계는 App Service 진단을 사용하는 것입니다.
- 웹앱에 대한 Azure Portal의 왼쪽 메뉴에서 진단 및 문제 해결 을 선택합니다.
- 가용성 및 성능을 선택합니다.
- 가장 일반적인 문제가 나타나는 애플리케이션 로그, 컨테이너 크래시 및 컨테이너 문제 옵션의 정보를 검사합니다.
다음으로, 배포 로그와앱 로그 에서 오류 메시지를 모두 검사합니다. 이러한 로그를 검사하여 앱 배포 또는 앱 시작을 방해하는 특정 문제를 파악할 수 있는 경우가 자주 있습니다. 예를 들어 requirements.txt 파일에 잘못된 파일 이름이 있거나 프로젝트 루트 폴더에 없는 경우 빌드가 실패할 수 있습니다.
다음 섹션에서는 특정 문제에 대한 참고 자료를 제공합니다.
- 앱이 표시되지 않음 - 기본 앱 표시
- 앱이 표시되지 않음 - "서비스를 사용할 수 없음" 메시지
- setup.py 또는 requirements.txt찾을 수 없습니다.
- 시작 시 ModuleNotFoundError
- 데이터베이스가 잠겨 있습니다.
- 입력할 때 SSH 세션에 암호가 표시되지 않음
- SSH 세션의 명령이 차단된 것처럼 보입니다.
- Django 앱에 정적 자산이 표시되지 않음
- 심각한 SSL 연결이 필요합니다.
앱이 표시되지 않음
사용자 고유의 앱 코드가 배포되면 기본 앱이 표시됩니다. App Service에 앱 코드를 배포하지 않았거나 App Service에서 앱 코드를 찾지 못하고 대신 기본 앱을 실행했기 때문에 기본 앱이 나타납니다.
App Service를 다시 시작하고, 15-20초 동안 기다린 다음, 앱을 다시 확인합니다.
SSH를 사용하여 App Service 컨테이너에 직접 연결하고 파일이 사이트/wwwroot 아래에 있는지 확인합니다. 파일이 없으면 다음 단계를 수행합니다.
- 값이 1인
SCM_DO_BUILD_DURING_DEPLOYMENT
라는 앱 설정을 만들고, 코드를 다시 배포하고, 몇 분 정도 기다렸다가 앱에 다시 액세스를 시도합니다. 앱 설정을 만드는 방법에 대한 자세한 내용은 Azure Portal 에서 App Service 앱 구성을 참조하세요. - 배포 프로세스를 검토하고, 배포 로그를 확인하고, 오류를 수정하고, 앱을 다시 배포합니다.
- 값이 1인
파일이 있으면 App Service에서 특정 시작 파일을 식별하지 못한 것입니다. App Service에서 Django 또는 Flask에 대해 예상하는 대로 앱이 구조화되어 있는지 확인하거나 사용자 지정 시작 명령을 사용합니다.
브라우저에 "서비스를 사용할 수 없음" 메시지가 표시됩니다. 브라우저에서 App Service에서 응답을 기다리는 시간이 초과되었습니다. 이는 App Service가 Gunicorn 서버를 시작했지만 앱 자체가 시작되지 않았음을 나타냅니다. 이 상태는 Gunicorn 인수가 올바르지 않거나 앱 코드에 오류가 있다는 뜻일 수 있습니다.
특히 App Service 계획에서 가장 낮은 가격 책정 계층을 사용하는 경우 브라우저를 새로 고칩니다. 예를 들어 무료 계층을 사용할 때 앱이 시작하는 데 시간이 더 오래 걸릴 수 있으며 브라우저를 새로 고친 후 응답이 됩니다.
App Service에서 Django 또는 Flask에 대해 예상하는 대로 앱이 구조화되어 있는지 확인하거나 사용자 지정 시작 명령을 사용합니다.
앱 로그 스트림에서 오류 메시지를 검사합니다. 이 로그는 앱 코드의 오류를 보여줍니다.
setup.py 또는 requirements.txt 파일을 찾을 수 없음
로그 스트림에 "setup.py 또는 requirements.txt찾을 수 없습니다. pip 설치를 실행하지 않음.": Oryx 빌드 프로세스에서 requirements.txt 파일을 찾지 못했습니다.
- SSH를 통해 웹앱의 컨테이너에 연결하고 requirements.txt 이름이 올바르게 지정되고 사이트/wwwroot 바로 아래에 있는지 확인합니다. 파일이 없는 경우 파일이 리포지토리에 있고 배포에 포함되어 있는지 확인합니다. 파일이 별도의 폴더에 있으면 루트로 이동합니다.
앱 시작 시 ModuleNotFoundError
ModuleNotFoundError: No module named 'example'
같은 오류가 표시되는 경우 애플리케이션이 시작될 때 Python에서 하나 이상의 모듈을 찾지 못했음을 의미합니다. 이 오류는 코드를 사용하여 가상 환경을 배포하는 경우에 주로 발생합니다. 가상 환경은 이동할 수 없으므로 애플리케이션 코드를 사용하여 가상 환경을 배포하면 안 됩니다. 대신, 앱 설정 SCM_DO_BUILD_DURING_DEPLOYMENT
를 만들고 1
로 설정하여 Oryx에서 가상 환경을 만들고 웹앱에 패키지를 설치하도록 합니다. 이 설정은 App Service에 배포할 때마다 Oryx에서 패키지를 강제로 설치합니다. 자세한 내용은 가상 환경 이식성에 대한 이 문서를 참조하세요.
데이터베이스가 잠겼습니다.
Django 앱을 사용하여 데이터베이스 마이그레이션을 실행하려고 하면 "sqlite3"이 표시될 수 있습니다. OperationalError: 데이터베이스가 잠겼습니다."가 표시될 수 있습니다. 이 오류는 애플리케이션이 Azure Database for PostgreSQL과 같은 클라우드 데이터베이스를 사용하는 대신 Django가 기본적으로 구성된 SQLite 데이터베이스를 사용하고 있음을 나타냅니다.
DATABASES
앱의 settings.py 파일에서 변수를 확인하여 앱이 SQLite 대신 클라우드 데이터베이스를 사용하고 있는지 확인합니다.
자습서: PostgreSQL을 사용하여 Django 웹앱 배포의 샘플에서 이 오류가 발생하는 경우 연결 확인 설정의 단계를 완료했는지 확인합니다.
기타 문제
입력할 때 SSH 세션에 암호가 표시되지 않습니다. 보안상의 이유로 SSH 세션은 입력할 때 암호를 숨깁니다. 그러나 문자가 기록되므로 평소와 같이 암호를 입력하고 완료되면 Enter 키를 선택합니다.
SSH 세션의 명령어가 잘린 것처럼 보입니다: 편집기가 명령어의 자동 줄 바꿈을 처리하지 않을 수도 있지만, 명령어는 여전히 올바르게 실행되어야 합니다.
정적 자산은 Django 앱에 표시되지 않습니다. WhiteNoise 모듈을 사용하도록 설정했는지 확인합니다.
"치명적인 SSL 연결이 필요합니다."라는 메시지가 표시됩니다. 앱 내에서 리소스(예: 데이터베이스)에 액세스하는 데 사용되는 사용자 이름 및 암호를 확인합니다.