Данная запись посвящена решению следующей задачи: автоматически развернуть веб приложение, основанное на Drupal, с компиляцией фронтэнда, использующей Grunt, при помощи Continuous Deployments фичи Azure Web app (то есть, без выделенного билд сервера), при том, что доступ к серверу должен быть ограничен по IP.
Azure Web app использует kudu для чекаута и доставки контента их репозитория в папку сайта (d:\home\site\wwwroot\), причём он достаточно умён, чтобы обнаружить, например, sln файл и вызвать msbuild для компиляции. Помимо этого, мы можем самостоятельно формировать файл-инструкцию для Kudu при помощи файла .deployment в корне репозитория и инструкций в этом файле.
Самый простой способ, чтобы сформировать этот файл и стартовый набор инструкций в нём - это использовать azure-cli.
Устанавливаем azure-cli при помощи команды "npm install azure-cli -g"
Далее, создаём базовую структуру, выполнив в корне репозитория следующую команду: "azure site deploymentscript --node" (для node.js). Данная команда создаст 2 файла:
- .deployment - файл инструкций для Kudu c указанием, какой файл выполнить после чекаута
- deploy.cmd (для Win)/deploy.sh (для *nix)
Рекомендую освежить свои знания по консольным командам (Kudu достаточно умён, чтобы выполнять команды bash и cmd) и приступить к оптимизации скрипта в deploy.[cmd|sh] файле.
Ход выполнения таков:
- Kudu забирает данные из репозитория в папку d:\home\site\repository
- Kudu выполняет инструкции из .deployment файла в корне репозитория (если найдётся такой)
- Билд завершен
Во время обкатки я обнаружил, что дефолтная версия node.js не подходит для моей компиляции. К счастью, это просто пофиксить:
- Идём в консоль Kudu ( https://<sitename>.scm.azurewebsites.net ), выбираем cmd в Debug Console
- Щёлкаем на изображение диска и переходим в D:\Program Files (x86)\nodejs
- Тут мы увидим все доступные для нашего Azure Web app версии Node.js
- Выбираем нужную и выставляем нужную версию в качестве значения для ключа WEBSITE_NODE_DEFAULT_VERSION
Вторая проблема, с которой я столкнулся, была в том, что grunt до сих пор использует слишком старую версию glob, что выражается в ошибке доставки: "Error: ENOTSUP: operation not supported on socket, scandir ".
Самый простой способ для меня был в том, чтобы вручную проапдейтить glob при помощи дополнительных команд в моём deploy.cmd:
pushd node_modules\grunt
call :ExecuteCmd !NPM_CMD! install glob@^6.0.4 --save
popd
pushd node_modules\grunt-modernizr\node_modules\customizr
call :ExecuteCmd !NPM_CMD! install glob@^6.0.4 --save
popd
pushd node_modules\customizr
call :ExecuteCmd !NPM_CMD! install glob@^6.0.4 --save
popd
Ограничение доступа по IP для Azure Web app делается при помощи элемента configuration/system.webServer/security/ipSecurity. Так как я пока не нашёл способа трансформировать web.config Drupal веб приложения, то я использую фичу автоматической трансформации applicationHost.config:
- Если в /site (на FTP, абсолютный путь будет d:\home\site) находиться файл applicationHost.xdt - Kudu будет пытаться трансформировать applicationHost.config вашего инстанса iis для Azure web app
- Таким образом, я создал файл applicationHost.xdt через FTP со следующим контентом:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
Данная заметка является компиляцией моего собственного опыта и следующих данных:
- http://www.cptloadtest.com/2013/12/03/Git-And-Grunt-Deploy-To-Windows-Azure.aspx
- https://blogs.msdn.microsoft.com/azureossds/2016/04/20/nodejs-and-npm-versions-on-azure-app-services/
- https://github.com/projectkudu/kudu/issues/1787
Надеюсь, поможет кому-либо в будущем 🙂