Loupe

Blazor - partie 3 : Où héberger une application Blazor ?

C'est parti pour notre 3e opus de la suite d'articles sur Blazor avec au programme du jour : l'hébergement de notre application.

En prérequis, nous aurons besoin d'une application Blazor webassembly (n'hésitez pas à jeter un coup d'œil sur comment obtenir une application Blazor la plus simple possible si vous n'aviez pas encore eu le temps)

Note : Par soucis de simplicité et de lisibilité de l'article, j'utiliserai dorénavant plus souvent le mot Blazor en lieu et place de Blazor webassembly (et j'utiliserai Blazor Server pour le différencier de Blazor webassembly)

Concernant l'hébergement, en fait la documentation officielle décrit plutôt bien les différentes possibilités qui s'offrent à nous, mais j'aimerais revenir rapidement sur ces options et bien sûr y apporter mon grain de sel :)

Restons simple : Hébergement Blazor sur un serveur web de site statique

Si vous êtes déjà familier avec le bon vieux serveur IIS, Blazor offre une intégration "out-of-the-box", et fournit le fichier web.config nécessaire pour l'hébergement, retrouvable directement parmi les fichiers de publication de notre application.

Par contre comme notre application Blazor est une SPA, nous aurons besoin d'installer le URL Rewrite module afin de rediriger nos requêtes http vers notre application (e.g.: rediriger la requête /about vers le fichier index.html contenant notre SPA plutôt que d'essayer de trouver des fichiers dans un potentiel dossier IIS about)

Et si vous avez plus l'habitude de manipuler des serveurs Nginx ou Apache, vous pouvez bien évidemment héberger votre application Blazor dessus. Vous pourrez trouver des exemples de configuration simple de fichier nginx.conf ou de configuration Apache sur la documentation officielle.

Mais poursuivons un peu plus en détail cet hébergement Nginx, notamment à l'intérieur d'un conteneur Docker.

Héberger votre SPA dans un simple conteneur Nginx

En fait, vous avez déjà un exemple de Dockerfile sur la documentation officielle (du bon boulot cette doc, vraiment :), mais, probablement pour des raisons de simplicité, le fichier Dockerfile assume que vous êtes déjà en possession d'un package prêt à être déployé, pour lequel il ne resterait plus qu'à être copié dans le conteneur.

Si cette approche va fonctionner techniquement, je préfère beaucoup plus l'idée d'avoir un fichier Dockerfile à côté de ma solution, capable de le builder et de générer les fichiers nécessaires pour exécuter mon application.

Pour arriver à ce scénario, nous allons reproduire le même mécanisme qui est fourni par Visual Studio pour conteneuriser une application aspnetcore : utiliser une Build Docker multi-stage qui se basera sur l'image du sdk dotnetcore et sur une petite image Nginx.

Note : Étant donné que Blazor n'est apparu que depuis la version 3 du framework dotnet core, il est évidemment nécessaire de récupérer une image possédant au minimum cette version.

Voilà à quoi ressemble notre Dockerfile :

FROM nginx:alpine AS base

FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS publish
WORKDIR /src

COPY ["SimpleStaticBlazor.csproj", ""]
RUN dotnet restore

COPY . .
RUN dotnet publish -c release -o /app

FROM base AS final
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=publish /app/SimpleStaticBlazor/dist /usr/share/nginx/html/

Plutôt simple et concis non ?

On a ensuite besoin d'effectuer les commandes docker build -t simplestaticblazor . (ne pas oublier le "." à la fin) pour builder notre image, ainsi que la commande docker run -it --rm -p 5000:80 simplestaticblazor pour le démarrer et pouvoir y accéder à l'url http://localhost:5000

Exposer votre SPA Blazor depuis Azure Blob Storage

Si vous êtes déjà habitué à travailler avec Azure, ce mode de fonctionnement devrait être des plus simple : sur le service Azure Blob storage, il existe une fonctionnalité de Static website qui permet d'exposer les fichiers contenus dans le stockage en http :

01-blazor-webassembly-on-azure-storage.png

Une fois activée, il suffit juste de copier nos fichiers statiques dans le compte de stockage via notre outil préféré tel qu'Azure Storage Explorer ou encore la tâche Azure Devops Azure File Copy, etc.

Et voilà, vous obtenez une application plutôt scalable sans avoir besoin de gérer un service plus complet/complexe, tel qu'Azure app service, juste pour héberger une poignée de fichiers statiques.

Et pour aller jusqu'au bout, il ne faudra pas oublier d'utiliser un Azure CDN afin d'y associer un nom de domaine custom exposé en https.

Héberger notre SPA sur Github pages

Pour héberger notre SPA Blazor sur Github pages, nous avons besoin d'une petite astuce que j'ai trouvée tellement sympa que je ne pouvais pas ne pas en parler :)

Le problème sur Github pages étant qu'il n'est pas possible de rediriger toutes les requêtes vers un seul et même fichier, car le service ne propose que 2 manières de gérer la redirection lorsque le visiteur tente d'accéder à une url ne correspondant pas à un fichier :

  • Soit l'utilisateur tente d'accéder à la l'Url racine du site web, et c'est la page par défaut index.html qui est retournée.
  • Soit un fichier 404.html est renvoyé à l'utilisateur plutôt que de lui retourner une erreur 404 not found.

Heureusement, cette limitation est bien connue par la communauté qui a rendu disponible 2 petits hacks JavaScript : Ceux-ci permettent de rediriger depuis la page 404 vers la page index.html avec les information de routage, et permettent d'avoir une application Blazor fonctionnelle sur Github pages :)

Je ne m'attarde pas plus sur cette méthode, mais je pense qu'elle valait le coup d'être mentionnée !

ASP.NET Core loves Blazor

Malgré tout, notre meilleure option pour héberger notre app Blazor reste depuis une application aspnetcore (et donc par dessus un serveur Kestrel)

En effet, aspnetcore possède déjà tout un tas de petites extensions qui permettent d'héberger notre application Blazor, de la déboguer, lui rediriger les requêtes, etc.

Exemple du Startup.cs de notre application aspnetcore hébergeant une application Blazor :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseResponseCompression();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBlazorDebugging();
    }

    app.UseStaticFiles();
    app.UseClientSideBlazorFiles<Client.Startup>();

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
        endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
    });
}

Ce type d'hébergement permet également des scénarios plus avancés tel que le Server Prerendering :

Le html de notre application Blazor est pré-calculé directement depuis le serveur, ce qui permet de renvoyer une simple page html lors de l'arrivée d'un premier visiteur, accompagnée d'un petit fichier JavaScript. Ce petit fichier Javascript permettra ensuite de "réhydrater" notre fichier html (i.e. reconnecter le html affiché et le dom virtuel) pour que notre visiteur obtienne au bout de quelques millisecondes une SPA Blazor complètement fonctionnelle !

Daniel Roth, Principal Program Manager sur Blazor, a déjà publié sur son Github une démo fonctionnelle de cette partie.

En conclusion

J'espère que cet article vous aura donné une vue d'ensemble des différentes possibilités pour héberger votre application Blazor

Vous pouvez jeter un coup d'oeil au hosting que j'ai rajouté sur ma SimpleStaticBlazor, basé sur du nginx dans un conteneur.

N'hésitez pas à me contacter sur Twitter @vivienfabing ou dans les commentaires, et que le code soit avec vous !

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus