Aller au contenu principal

Publication dans Azure

Il existe cinq méthodes pour publier une application Lagoon dans Azure App Service :

  • Azure App Service Windows.
  • Azure App Service Linux.
  • Azure App Service avec Container, Linux ou Windows.
  • Azure Container Service, Linux uniquement.
  • Une machine virtuelle, avec une publication IIS ou Apache.

Avec les solutions Azure App Service, il est possible d'effectuer des tâches planifiées, ou WebJobs, dans le contexte de l'App Service.

astuce

Dans les exemples de publication suivants, az CLI est utilisé pour déployer les ressources d'infrastructure. Dans un contexte de production, il est conseillé d'utiliser des scripts Bicep pour gérer l'Infrastructure As Code.

Publication Azure App Service Windows​

Préparation du paquet de déploiement​

  • Effectuer une publication en précisant --runtime win-x64.
  • Créer un fichier ZIP contenant la publication.
SET APP_VERSION=1.0.0
SET APP_NAME=MYAPP
SET PUBLISH_PATH=C:\Temp\(Publish)\%APP_NAME%
SET PUBLISH_TEMP_PATH=%PUBLISH_PATH%\ZIP
SET PUBLISH_ZIP_FILE=%PUBLISH_PATH%\%APP_NAME%-v%APP_VERSION%.zip

REM To fix the error NETSDK1112: The runtime pack for Microsoft.NETCore.App.Runtime.Mono.browser-wasm was not downloaded. Try running a NuGet restore with the RuntimeIdentifier 'browser-wasm'
dotnet restore Client\%APP_NAME%.Client.csproj --runtime browser-wasm

REM Build and publish to a temp folder
dotnet publish Server\%APP_NAME%.Server.csproj --configuration Release -p:Version=%APP_VERSION% --runtime win-x64 --no-self-contained --output "%PUBLISH_TEMP_PATH%"

REM Create a ZIP package for deployment
"%ProgramFiles%\7-Zip\7z.exe" a "%PUBLISH_ZIP_FILE%" "%PUBLISH_TEMP_PATH%\.\*"

Déploiement​

  • Spécifier --https-only true lors de la création de l'App Service pour rediriger les requêtes HTTP vers HTTPS.
  • Définir --always-on true pour l'App Service afin qu'il ne se mette pas en pause en cas d'inactivité, pré-requis pour les WebJobs.
  • Déclarer la variable WEBSITE_TIME_ZONE à Romance Standard Time pour que le Web App Service utilise le fuseau horaire de Bruxelles, Copenhague, Madrid, Paris.
SET RESOURCEGROUP=MYAPP-TEST
SET LOCATION=northeurope
SET SITENAME=myapp-test-as
SET PLANNAME=%SITENAME%p
SET PLANSKU=B1
REM login supports device login, username/password, and service principals
call az login
REM create a resource group for your application
Echo Resource group...
call az group create --name %RESOURCEGROUP% --location %LOCATION%
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM create an appservice plan (a machine) where your site will run
Echo App plan...
call az appservice plan create --name %PLANNAME% --location %LOCATION% --sku %PLANSKU% --resource-group %RESOURCEGROUP%
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM create the web application on the plan
Echo App service...
call az webapp create --name %SITENAME% --plan %PLANNAME% --resource-group %RESOURCEGROUP% --https-only true
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM configure the app service
Echo App service configuration...
call az webapp config set --name %SITENAME% --resource-group %RESOURCEGROUP% --always-on true
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM configure environment variable for the app service
Echo Setting environment variables...
call az webapp config appsettings set --name %SITENAME% --resource-group %RESOURCEGROUP% --settings WEBSITE_TIME_ZONE="Romance Standard Time"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM Deploy zip
Echo Deploy app...
call az webapp deploy --resource-group %RESOURCEGROUP% --name %SITENAME% --type zip --src-path "%PUBLISH_ZIP_FILE%"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM Browse to the site
Echo Open website...
call az webapp browse --name %SITENAME% --resource-group %RESOURCEGROUP%

Tâches planifiées, optionnel​

  • Créer un dossier WebJobs à la racine du projet MyApp.Batch.
  • Modifier le fichier MyApp.Batch.csproj pour ajouter les lignes suivantes :
<ItemGroup>
<None Include="WebJobs\**\*">
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
<TargetPath>app_data\jobs\triggered\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</None>
</ItemGroup>
  • Créer un sous-dossier DailyTask dans le dossier WebJobs. Le nom DailyTask peut être renommé : il s'agit du nom du WebJob.
  • Créer les fichiers run.cmd et settings.job dans le dossier DailyTask.

run.cmd​

@echo off
rem -- Set current directory to "C:\home\site\wwwroot" to enable loading of "appsettings*.json".
cd /D %WEBROOT_PATH%
call myapp.exe batch --send-reminder

Adapter la commande au besoin.

settings.job​

{
// WEBSITE_TIME_ZONE environment variable must be set to 'Romance Standard Time' for Bruxelles, Copenhague, Madrid, Paris

// Runs at 4:30 AM, Monday to Friday
"schedule": "0 30 4 * * 1-5"
}
Attention

Penser à bien définir la variable d'environnement WEBSITE_TIME_ZONE lors de la création de l'App Service.

Publication Azure App Service Linux​

Préparation du paquet de déploiement​

  • Effectuer une publication en précisant --runtime linux-x64 --no-self-contained.
  • Créer un fichier ZIP contenant la publication.
SET APP_VERSION=1.0.0
SET APP_NAME=MYAPP
SET PUBLISH_PATH=C:\Temp\(Publish)\%APP_NAME%
SET PUBLISH_TEMP_PATH=%PUBLISH_PATH%\ZIP
SET PUBLISH_ZIP_FILE=%PUBLISH_PATH%\%APP_NAME%-v%APP_VERSION%.zip

REM To fix the error NETSDK1112: The runtime pack for Microsoft.NETCore.App.Runtime.Mono.browser-wasm was not downloaded. Try running a NuGet restore with the RuntimeIdentifier 'browser-wasm'
dotnet restore Client\%APP_NAME%.Client.csproj --runtime browser-wasm

REM Build and publish to a temp folder
dotnet publish Server\%APP_NAME%.Server.csproj --configuration Release -p:Version=%APP_VERSION% --runtime linux-x64 --no-self-contained --output "%PUBLISH_TEMP_PATH%"

REM Create a ZIP package for deployment
"%ProgramFiles%\7-Zip\7z.exe" a "%PUBLISH_ZIP_FILE%" "%PUBLISH_TEMP_PATH%\.\*"

Déploiement​

  • Créer un App Service Plan Linux avec --is-linux.
  • Spécifier --https-only true lors de la création de l'App Service pour rediriger les requêtes HTTP vers HTTPS.
  • Spécifier le runtime DOTNETCORE:8.0 lors de la configuration de l'App Service.
  • Définir --always-on true pour l'App Service afin qu'il ne se mette pas en pause en cas d'inactivité, pré-requis pour les WebJobs.
  • Déclarer la variable TZ à Europe/Paris pour que le Web App Service utilise le fuseau horaire de Paris.
  • Déclarer la variable WEBSITE_SKIP_RUNNING_KUDUAGENT à false pour permettre l'utilisation des WebJobs.
SET RESOURCEGROUP=MYAPP-TEST
SET LOCATION=northeurope
SET SITENAME=myapp-test-as
SET PLANNAME=%SITENAME%p
SET PLANSKU=B1
REM login supports device login, username/password, and service principals
call az login
REM create a resource group for your application
Echo Resource group...
call az group create --name %RESOURCEGROUP% --location %LOCATION%
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM create an appservice plan (a machine) where your site will run
Echo App plan...
call az appservice plan create --name %PLANNAME% --location %LOCATION% --sku %PLANSKU% --resource-group %RESOURCEGROUP% --is-linux
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM create the web application on the plan
Echo App service...
call az webapp create --name %SITENAME% --plan %PLANNAME% --resource-group %RESOURCEGROUP% --https-only true --runtime "DOTNETCORE:8.0"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM configure the app service
Echo App service configuration...
call az webapp config set --name %SITENAME% --resource-group %RESOURCEGROUP% --always-on true --startup-file="dotnet %SOLUTION_NAME%.Server.dll"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM configure environment variable for the app service
Echo Setting environment variables...
call az webapp config appsettings set --name %SITENAME% --resource-group %RESOURCEGROUP% --settings TZ="Europe/Paris" WEBSITE_SKIP_RUNNING_KUDUAGENT="false"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM Deploy zip
Echo Deploy app...
call az webapp deploy --resource-group %RESOURCEGROUP% --name %SITENAME% --type zip --src-path "%PUBLISH_ZIP_FILE%"
IF NOT %ERRORLEVEL%==0 GOTO ERROR
REM Browse to the site
Echo Open website...
call az webapp browse --name %SITENAME% --resource-group %RESOURCEGROUP%

Tâches planifiées, optionnel​

  • Créer un dossier WebJobs à la racine du projet MyApp.Batch.
  • Modifier le fichier MyApp.Batch.csproj pour ajouter les lignes suivantes :
<ItemGroup>
<None Include="WebJobs\**\*">
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
<TargetPath>app_data\jobs\triggered\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
</None>
</ItemGroup>
Attention

app_data\jobs\triggered ainsi que les fichiers du dossier doivent être en minuscules sous Linux.

  • Créer un sous-dossier DailyTask dans le dossier WebJobs. Le nom DailyTask peut être renommé : il s'agit du nom du WebJob.
  • Créer les fichiers run.sh et settings.job dans le dossier DailyTask.

run.sh​

#!/bin/bash

# WEBSITE_SKIP_RUNNING_KUDUAGENT environment variable must be set to false in order for webjobs to function on linux apps.

# Set current directory to "/home/site/wwwroot" to enable loading of "appsettings*.json".
cd $WEBROOT_PATH
myapp batch --send-reminder

Adapter la commande au besoin.

settings.job​

{
// TZ environment variable must be set to 'Europe/Paris' for Paris

// Runs at 4:30 AM, Monday to Friday
"schedule": "0 30 4 * * 1-5"
}
Attention

Penser à bien définir les variables d'environnement WEBSITE_SKIP_RUNNING_KUDUAGENT et TZ lors de la création de l'App Service.

Tâches planifiées Linux avec système de fichier en lecture seule​

Dans le cas où WEBSITE_RUN_FROM_PACKAGE=1, le système de fichier devient en lecture seule et le script de batch doit être écrit dans un autre dossier : /home/site/jobs/triggered.

La solution consiste à créer les fichiers dans le bon emplacement au démarrage de l'application.

appsettings.Development.json​

{
"WebJob": {
"Folder": "C:\\Temp\\MyApp\\WebJob",
"CronExpression": "0 0 9 * * 1-5" // Runs at 8:00 AM, Monday through Friday
}
}

appsettings.Production.json​

{
"WebJob": {
"Folder": "/home/site/jobs/triggered/Batch",
"CronExpression": "0 0 8 * * 1-5" // Runs at 8:00 AM, Monday through Friday
}
}

Server\Main.cs​

///<inheritdoc/>
protected override Task OnStartAsync(IServiceProvider scopedServiceProvider, CancellationToken cancellationToken)
{
InitializeWebJob();
return Task.CompletedTask;
}

/// <summary>
/// Create the WebJob from the app_settings.
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void InitializeWebJob()
{
string folder = Configuration["WebJob:Folder"];
if (string.IsNullOrEmpty(folder))
{
throw new NotImplementedException("WebJob folder is not configured in appsettings.json");
}
Directory.CreateDirectory(folder);
// run.sh script is copied from the WebJob folder in the WebJob directory
string runSourcePath = Path.Join(Path.GetDirectoryName(typeof(Main).Assembly.Location), "WebJob", "run.sh");
string runPath = Path.Join(folder, "run.sh");
if (!File.Exists(runPath) || File.GetLastWriteTime(runSourcePath) > File.GetLastWriteTime(runPath))
{
File.Copy(runSourcePath, runPath, true);
}
// settings.job file is created in the WebJob directory
string settingsPath = Path.Join(folder, "settings.job");
string cronExpression = Configuration["WebJob:CronExpression"];
if (string.IsNullOrEmpty(cronExpression))
{
if (File.Exists(settingsPath))
{
File.Delete(settingsPath);
}
}
else
{
string content = $"{{\"schedule\": \"{cronExpression}\"}}";
if (!File.Exists(settingsPath) || File.ReadAllText(settingsPath) != content)
{
File.WriteAllText(settingsPath, content);
}
}
}

run.sh​

#!/bin/bash

# Set current directory to "/home/site/wwwroot" to enable loading of "appsettings*.json".
cd $WEBROOT_PATH
myapp batch --mySampleArgument
Attention

Le flag d'exécution +x doit être positionné sur le fichier.

# Preparing linux build
- bash: |
dotnet tool update --global LGN --version $(lgnVersion)
lgn fix-charset
ls -al "Server/WebJob"
chmod +x "Server/WebJob/run.sh"
ls -al "Server/WebJob"
displayName: Preparing linux build

MyApp.csproj​

<None Update="WebJob\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>