Azure App Service용 PHP 앱 구성

이 가이드에서는 Azure App Service에서 PHP 웹앱, 모바일 백 엔드, API 앱을 구성하는 방법을 보여 줍니다.

또한 App Service에 앱을 배포하는 PHP 개발자를 위한 주요 개념과 지침을 제공합니다. Azure App Service를 처음 사용하는 경우 먼저 PHP 빠른 시작MySQL을 사용하는 PHP 자습서를 따라하세요.

PHP 버전 표시

현재 PHP 버전을 표시하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp config show --resource-group <resource-group-name> --name <app-name> --query phpVersion

참고

개발 슬롯의 주소를 지정하려면 매개 변수 --slot 뒤에 슬롯 이름을 포함합니다.

지원되는 PHP 버전을 모두 표시하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp list-runtimes | grep php

현재 PHP 버전을 표시하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

참고

개발 슬롯의 주소를 지정하려면 매개 변수 --slot 뒤에 슬롯 이름을 포함합니다.

지원되는 PHP 버전을 모두 표시하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp list-runtimes --linux | grep PHP

PHP 버전 설정

PHP 버전을 7.4로 설정하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp config set --resource-group <resource-group-name> --name <app-name> --php-version 7.4

PHP 버전을 7.2로 설정하려면 Cloud Shell에서 다음 명령을 실행합니다.

az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "PHP|7.2"

Composer 실행

배포 시 App Service에서 Composer를 실행하려는 경우 가장 쉬운 방법은 리포지토리에 Composer를 포함하는 것입니다.

로컬 터미널 창에서 디렉터리를 리포지토리 루트로 변경하고, Composer 다운로드의 지침에 따라 composer.phar 을 디렉터리 루트에 다운로드합니다.

다음 명령을 실행합니다(npm이 설치되어 있어야 함).

npm install kuduscript -g
kuduscript --node --scriptType bash --suppressPrompt

이제 리포지토리 루트에 .deploymentdeploy.sh 라는 두 개의 추가 파일이 있습니다.

deploy.sh 를 열고 다음과 같은 Deployment 섹션을 찾습니다.

##################################################################################################################################
# Deployment
# ----------

필요한 도구를 실행하는 데 필요한 코드 섹션을 Deployment 섹션의 ‘끝’에 추가합니다.

# 4. Use composer
echo "$DEPLOYMENT_TARGET"
if [ -e "$DEPLOYMENT_TARGET/composer.json" ]; then
  echo "Found composer.json"
  pushd "$DEPLOYMENT_TARGET"
  php composer.phar install $COMPOSER_ARGS
  exitWithMessageOnError "Composer install failed"
  popd
fi

모든 변경 내용을 커밋하고 빌드 자동화를 사용하도록 설정하여 Git 또는 Zip 배포를 통해 코드를 배포합니다. 이제 Composer가 배포 자동화의 일부로 실행됩니다.

Grunt/Bower/Gulp 실행

배포 시 App Service에서 Grunt, Bower 또는 Gulp와 같은 인기 자동화 도구를 실행하려면 사용자 지정 배포 스크립트를 제공해야 합니다. 빌드 자동화를 사용하도록 설정하여 Git 또는 Zip 배포를 통해 배포하면 App Service에서 이 스크립트를 실행합니다.

리포지토리가 해당 도구를 실행할 수 있게 하려면 package.json 의 종속성에 도구를 추가해야 합니다. 예를 들면 다음과 같습니다.

"dependencies": {
  "bower": "^1.7.9",
  "grunt": "^1.0.1",
  "gulp": "^3.9.1",
  ...
}

로컬 터미널 창에서 디렉터리를 리포지토리 루트로 변경하고 다음 명령을 실행합니다(npm이 설치 되어 있어야 함).

npm install kuduscript -g
kuduscript --node --scriptType bash --suppressPrompt

이제 리포지토리 루트에 .deploymentdeploy.sh 라는 두 개의 추가 파일이 있습니다.

deploy.sh 를 열고 다음과 같은 Deployment 섹션을 찾습니다.

##################################################################################################################################
# Deployment
# ----------

이 섹션은 npm install --production 실행으로 끝납니다. 필요한 도구를 실행하는 데 필요한 코드 섹션을 Deployment 섹션의 ‘끝’에 추가합니다.

배포 스크립트가 사용자 지정 npm install 명령도 실행하는 MEAN.js 샘플의 예제를 참조하세요.

Bower

이 코드 조각은 bower install을 실행합니다.

if [ -e "$DEPLOYMENT_TARGET/bower.json" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/bower install
  exitWithMessageOnError "bower failed"
  cd - > /dev/null
fi

Gulp

이 코드 조각은 gulp imagemin을 실행합니다.

if [ -e "$DEPLOYMENT_TARGET/gulpfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/gulp imagemin
  exitWithMessageOnError "gulp failed"
  cd - > /dev/null
fi

Grunt

이 코드 조각은 grunt를 실행합니다.

if [ -e "$DEPLOYMENT_TARGET/Gruntfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/grunt
  exitWithMessageOnError "Grunt failed"
  cd - > /dev/null
fi

빌드 자동화 사용자 지정

빌드 자동화가 설정된 상태에서 Git 또는 zip 패키지를 사용하여 앱을 배포하는 경우 App Service는 다음 시퀀스를 통해 자동화 단계를 빌드합니다.

  1. PRE_BUILD_SCRIPT_PATH에 지정된 경우 사용자 지정 스크립트를 실행합니다.
  2. php composer.phar install을 실행합니다.
  3. POST_BUILD_SCRIPT_PATH에 지정된 경우 사용자 지정 스크립트를 실행합니다.

PRE_BUILD_COMMANDPOST_BUILD_COMMAND는 기본적으로 비어 있는 환경 변수입니다. 빌드 전 명령을 실행하려면 PRE_BUILD_COMMAND를 정의합니다. 빌드 후 명령을 실행하려면 POST_BUILD_COMMAND를 정의합니다.

다음 예제에서는 일련의 명령에 대한 두 변수를 쉼표로 구분하여 지정합니다.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/prebuild.sh"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/postbuild.sh"

빌드 자동화를 사용자 지정하는 추가 환경 변수는 Oryx 구성을 참조하세요.

App Service를 실행하고 Linux에서 PHP 앱을 빌드하는 방법에 대한 자세한 내용은 Oryx 설명서: PHP 앱을 인식하고 구축하는 방법을 참조하세요.

시작 사용자 지정

기본적으로 내장된 PHP 컨테이너는 Apache 서버를 실행합니다. 먼저 apache2ctl -D FOREGROUND"이 실행됩니다. 원하는 경우 Cloud Shell에서 다음의 명령을 실행하여 시작 시 다른 명령을 실행할 수 있습니다.

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<custom-command>"

환경 변수 액세스

App Service에서, 앱 코드 외부에서 앱 설정을 지정할 수 있습니다. 그런 다음, 표준적인 getenv() 패턴으로 액세스합니다. 예를 들어 앱 설정 DB_HOST에 액세스하려면 다음 코드를 사용합니다.

getenv("DB_HOST")

사이트 루트 변경

원하는 웹 프레임워크에서 하위 디렉터리를 사이트 루트로 사용할 수 있습니다. 예를 들어 Laravelpublic/ 하위 디렉터리를 사이트 루트로 사용합니다.

사이트 루트를 사용자 지정하려면 az resource update 명령을 사용하여 앱의 가상 애플리케이션 경로를 설정합니다. 다음 예제에서는 사이트 루트를 리포지토리의 public/ 하위 디렉터리로 설정합니다.

az resource update --name web --resource-group <group-name> --namespace Microsoft.Web --resource-type config --parent sites/<app-name> --set properties.virtualApplications[0].physicalPath="site\wwwroot\public" --api-version 2015-06-01

기본적으로 Azure App Service에서는 루트 가상 애플리케이션 경로( / )가 배포된 애플리케이션 파일의 루트 디렉터리(sites\wwwroot)를 가리킵니다.

원하는 웹 프레임워크에서 하위 디렉터리를 사이트 루트로 사용할 수 있습니다. 예를 들어 Laravelpublic/ 하위 디렉터리를 사이트 루트로 사용합니다.

App Service용 기본 PHP 이미지는 Apache를 사용하며 앱에 맞게 사이트 루트를 사용자 지정할 수 없습니다. 이 제한을 해결하려면 다음 내용을 포함하여 .htaccess 파일을 리포지토리 루트에 추가하세요.

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_URI} ^(.*)
    RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]
</IfModule>

.htaccess 다시 쓰기를 사용하지 않으려면 사용자 지정 Docker 이미지를 대신 사용하여 Laravel 애플리케이션을 배포할 수 있습니다.

HTTPS 세션 검색

App Service에서, SSL 종료는 네트워크 부하 분산 장치에서 발생하므로 모든 HTTPS 요청은 암호화되지 않은 HTTP 요청으로 앱에 도달합니다. 앱 논리에서 사용자 요청의 암호화 여부를 확인해야 하는 경우 X-Forwarded-Proto 헤더를 검사합니다.

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
// Do something when HTTPS is used
}

인기 있는 웹 프레임워크를 사용하여 표준 앱 패턴의 X-Forwarded-* 정보에 액세스할 수 있습니다. CodeIgniter에서, is_https()는 기본적으로 X_FORWARDED_PROTO 값을 확인합니다.

php.ini 설정 사용자 지정

PHP 설치를 변경해야 할 경우 다음 단계에 따라 모든 php.ini 지시문을 변경할 수 있습니다.

참고

PHP 버전과 현재의 php.ini 구성을 확인하는 가장 좋은 방법은 앱에서 phpinfo()를 호출하는 것입니다.

PHP_INI_SYSTEM 외의 지시문 사용자 지정

PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL 지시문(php.ini 지시문 참조)을 사용자 지정하려면 앱의 루트 디렉터리에 .user.ini 파일을 추가합니다.

php.ini 파일에 사용한 것과 동일한 구문을 사용하여 구성 설정을 .user.ini 파일에 추가합니다. 예를 들어, display_errors 설정을 켜고 upload_max_filesize 설정을 10M로 설정하려면 .user.ini 파일에 다음 텍스트를 포함합니다.

 ; Example Settings
 display_errors=On
 upload_max_filesize=10M

 ; Write errors to d:\home\LogFiles\php_errors.log
 ; log_errors=On

변경 내용을 적용해 앱을 다시 배포하고 재시작합니다.

.user.ini 파일을 사용하는 대신 앱에서 ini_set()을 사용하여 PHP_INI_SYSTEM 이외의 지시문을 사용자 지정할 수 있습니다.

PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL 지시문(php.ini 지시문 참조)을 사용자 지정하려면 .htaccess 파일을 앱의 루트 디렉터리에 추가합니다.

.htaccess 파일에서 php_value <directive-name> <value> 구문을 사용하여 지시문을 추가합니다. 예를 들면 다음과 같습니다.

php_value upload_max_filesize 1000M
php_value post_max_size 2000M
php_value memory_limit 3000M
php_value max_execution_time 180
php_value max_input_time 180
php_value display_errors On
php_value upload_max_filesize 10M

변경 내용을 적용해 앱을 다시 배포하고 재시작합니다. Kudu로 배포하는 경우(예: Git 사용) 배포 후에 자동으로 다시 시작됩니다.

.htaccess 를 사용하는 대신 앱에서 ini_set()를 사용하여 이런 PHP_INI_SYSTEM 외의 지시문을 사용자 지정할 수 있습니다.

PHP_INI_SYSTEM 지시문 사용자 지정

PHP_INI_SYSTEM 지시문(php.ini 지시문 참조)을 사용자 지정할 때는 .htaccess 방법을 사용할 수 없습니다. App Service가 PHP_INI_SCAN_DIR 앱 설정을 사용하는 별도의 메커니즘을 제공합니다.

먼저 Cloud Shell에서 다음 명령을 실행하여 PHP_INI_SCAN_DIR이라는 앱 설정을 추가합니다.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PHP_INI_SCAN_DIR="d:\home\site\ini"

Kudu 콘솔(https://<app-name>.scm.azurewebsites.net/DebugConsole)로 이동한 다음, d:\home\site로 이동합니다.

d:\home\site에서 ini라는 디렉터리를 만든 다음, d:\home\site\ini 디렉터리에서 사용자 지정할 지시문을 포함하여 .ini 파일(예: settings.ini) 을 생성합니다. php.ini 파일에서와 동일한 구문을 사용합니다.

예를 들어 expose_php의 값을 변경하려면 다음의 명령을 실행하세요.

cd /home/site
mkdir ini
echo "expose_php = Off" >> ini/setting.ini

변경 사항을 적용하려면 앱을 다시 시작해야 합니다.

PHP_INI_SYSTEM 지시문(php.ini 지시문 참조)을 사용자 지정할 때는 .htaccess 방법을 사용할 수 없습니다. App Service가 PHP_INI_SCAN_DIR 앱 설정을 사용하는 별도의 메커니즘을 제공합니다.

먼저 Cloud Shell에서 다음 명령을 실행하여 PHP_INI_SCAN_DIR이라는 앱 설정을 추가합니다.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PHP_INI_SCAN_DIR="/usr/local/etc/php/conf.d:/home/site/ini"

/usr/local/etc/php/conf.dphp.ini 가 있는 기본 디렉터리입니다. /home/site/ini은 사용자 지정 .ini 파일을 추가할 사용자 지정 디렉터리입니다. 값은 :로 구분합니다.

Linux 컨테이너(https://<app-name>.scm.azurewebsites.net/webssh/host)를 사용하여 웹 SSH 세션으로 이동합니다.

/home/site에서 ini라는 디렉터리를 만든 다음, /home/site/ini 디렉터리에서 사용자 지정할 지시문을 포함하여 .ini 파일(예: settings.ini) 을 생성합니다. php.ini 파일에서와 동일한 구문을 사용합니다.

App Service에 내장된 Linux 컨테이너에서 /home 은 영구 공유 스토리지로 사용됩니다.

예를 들어 expose_php의 값을 변경하려면 다음의 명령을 실행하세요.

cd /home/site
mkdir ini
echo "expose_php = Off" >> ini/setting.ini

변경 사항을 적용하려면 앱을 다시 시작해야 합니다.

PHP 확장 활성화

내장된 PHP 설치에는 가장 일반적으로 사용하는 확장이 포함됩니다. php.ini 지시문을 사용자 지정하는 것과 동일한 방식으로 추가 확장을 활성화할 수 있습니다.

참고

PHP 버전과 현재의 php.ini 구성을 확인하는 가장 좋은 방법은 앱에서 phpinfo()를 호출하는 것입니다.

추가 확장을 사용하도록 설정하려면 다음 단계를 따릅니다.

앱의 루트 디렉터리에 bin 디렉터리를 추가하고 .dll 확장 파일(예: mongodb.dll)을 디렉터리에 넣습니다. 확장이 Azure의 PHP 버전과 호환되고 VC9 및 nts(non-thread-safe)와 호환되는지 확인하세요.

변경 내용을 배포합니다.

PHP_INI_SYSTEM 지시문 사용자 지정의 단계에 따라 extension 또는 zend_extension 지시문으로 사용자 지정 .ini 파일에 확장을 추가합니다.

extension=d:\home\site\wwwroot\bin\mongodb.dll
zend_extension=d:\home\site\wwwroot\bin\xdebug.dll

변경 사항을 적용하려면 앱을 다시 시작해야 합니다.

내장된 PHP 설치에는 가장 일반적으로 사용하는 확장이 포함됩니다. php.ini 지시문을 사용자 지정하는 것과 동일한 방식으로 추가 확장을 활성화할 수 있습니다.

참고

PHP 버전과 현재의 php.ini 구성을 확인하는 가장 좋은 방법은 앱에서 phpinfo()를 호출하는 것입니다.

추가 확장을 사용하도록 설정하려면 다음 단계를 따릅니다.

bin 디렉터리를 앱의 루트 디렉터리에 추가하고 .so 확장 파일(예: mongodb.so)을 넣습니다. 확장이 Azure의 PHP 버전과 호환되고 VC9 및 nts(non-thread-safe)와 호환되는지 확인하세요.

변경 내용을 배포합니다.

PHP_INI_SYSTEM 지시문 사용자 지정의 단계에 따라 extension 또는 zend_extension 지시문으로 사용자 지정 .ini 파일에 확장을 추가합니다.

extension=/home/site/wwwroot/bin/mongodb.so
zend_extension=/home/site/wwwroot/bin/xdebug.so

변경 사항을 적용하려면 앱을 다시 시작해야 합니다.

진단 로그 액세스

표준 error_log() 유틸리티를 사용하여 Azure App Service에서 진단 로그를 표시할 수 있습니다.

App Service의 애플리케이션 코드 내부에서 생성된 콘솔 로그에 액세스하려면 Cloud Shell에서 다음 명령을 실행하여 진단 로깅을 켭니다.

az webapp log config --resource-group <resource-group-name> --name <app-name> --application-logging true --level Verbose

--level에 대한 가능한 값은 Error, Warning, InfoVerbose입니다. 각 후속 수준에는 이전 수준이 포함됩니다. 예를 들어 Error에는 오류 메시지만 포함하고 Verbose에는 모든 메시지를 포함합니다.

진단 로깅이 설정되면 다음 명령을 실행하여 로그 스트림을 확인합니다.

az webapp log tail --resource-group <resource-group-name> --name <app-name>

콘솔 로그가 즉시 표시되지 않으면 30초 후에 다시 확인합니다.

참고

https://<app-name>.scm.azurewebsites.net/api/logs/docker의 브라우저에서 로그 파일을 검사할 수도 있습니다.

언제든지 로그 스트리밍을 중지하려면 Ctrl+C를 입력합니다.

컨테이너 내부에서 생성된 콘솔 로그에 액세스할 수 있습니다.

먼저 다음 명령을 실행하여 컨테이너 로깅을 설정합니다.

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+C 를 입력합니다.

https://<app-name>.scm.azurewebsites.net/api/logs/docker의 브라우저에서 로그 파일을 검사할 수도 있습니다.

문제 해결

작동하는 PHP 앱이 App Servce에서 다르게 동작하거나 오류가 발생할 경우 다음의 방법을 시도해보세요.

  • 로그 스트림에 액세스합니다.
  • 프로덕션 모드에서 로컬 상태로 앱을 테스트합니다. App Service는 프로덕션 모드로 앱을 실행하므로 프로젝트가 프로덕션 모드로 로컬에서 예상대로 작동하는지 확인해야 합니다. 예를 들면 다음과 같습니다.
    • composer.json 에 따라, 프로덕션 모드에서 다른 패키지가 설치될 수 있습니다(require vs. require-dev).
    • 특정 웹 프레임워크는 프로덕션 모드에서 다른 고정 파일을 배포할 수 있습니다.
    • 특정 웹 프레임워크는 프로덕션 모드에서 실행될 때 사용자 지정 시작 스크립트를 사용합니다.
  • 디버그 모드에서 App Service의 앱을 실행합니다. 예를 들어 Laravel에서는 앱 설정APP_DEBUGtrue으로 설정하여 프로덕션 모드에서 디버그 메시지를 출력하도록 앱을 구성할 수 있습니다.

로그의 robots933456

컨테이너 로그에 다음 메시지가 표시될 수 있습니다.

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

이 메시지는 무시해도 괜찮습니다. /robots933456.txt는 App Service에서 컨테이너가 요청을 처리할 수 있는지 확인하기 위해 사용하는 더미 URL 경로입니다. 404 응답은 단순히 경로가 존재하지 않는다는 것을 나타내지만 컨테이너가 정상 상태이고 요청에 응답할 준비가 되었음을 App Service에 알려줍니다.

다음 단계