Tutoriels

Déployer une API .NET et une app Angular sur Raspberry Pi avec Docker

ParQuentin Destrade

image d’illustration de l’article

Contenu détaillé de l’article: Déployer une API .NET et une app Angular sur Raspberry Pi avec Docker

Dans cet article, découvrez le déploiement d'une API .NET et d'une application Angular dans des conteneurs Docker sur Raspberry Pi 4 et 5, connectés à un IBM i. Création des Dockerfiles, configuration NGINX, CORS, build multi-architecture et déploiement pas à pas sur chaque machine.

Déployer des applications de manière efficace, rapide et reproductible dans des environnements hétérogènes peut sembler complexe. Dans cet article, nous allons déployer dans des conteneurs Docker une API .NET introduite dans un précédent article, couplée à une application Angular.

L'API .NET, via le connecteur NTi Data Provider, expose les données depuis DB2 for i. L'application Angular les consomme pour fournir l'interface utilisateur.

Prérequis et environnement de développement

  • IDE : l'API .NET est développée avec Visual Studio, qui intègre nativement la gestion des conteneurs Docker. L'application Angular est développée sous Visual Studio Code.
  • Système cible : les applications sont destinées à être déployées sur des Raspberry Pi 4 et 5, des nano-ordinateurs à processeur ARM connectés à un IBM i.
  • Docker : Docker desktop installé sur la machine de développement, va me permettre de conteneuriser les applications, facilitant leur déploiement sur différentes architectures matérielles, notamment celles des Raspberry Pi.

Partie 1 - Déploiement de l’API .NET

Étape 1 - Création du Dockerfile avec Visual Studio

La première étape consiste à créer un Dockerfile pour l’API .NET.
Visual Studio facilite ce processus grâce à son intégration native Docker:

clic droit sur le projet > Ajouter > Prise en charge avec Docker

Visual Studio génère un Dockerfile multi-étapes adapté à l'application .NET :

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081


FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["AccessDataAPI.csproj", "."]
RUN dotnet restore "./././AccessDataAPI.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./AccessDataAPI.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./AccessDataAPI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AccessDataAPI.dll"]
  • Base: image ASP.NET officielle avec les ports 8080 (HTTP) et 8081 (HTTPS) exposés.
  • Build: compilation de l'application avec le SDK .NET.
  • Publish: publication de l'application compilée, prête pour le déploiement.
  • Final: image d'exécution finale avec uniquement les fichiers publiés.

Étape 2 - Ajout des CORS ( Cross Origin Resource Sharing )

Afin de permettre à l'API d’accepter les requêtes provenant de l'application Angular hébergée sur un serveur différent, les CORS sont configurés dans le program.cs.

using AccessDataAPI.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;

var builder = WebApplication.CreateBuilder(args);

// Add the CORS configuration to authorise requests from the Angular HotelAppManager application. 

builder.Services.AddCors(options =>
{
    options.AddPolicy("MyCorsPolicy", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

Étape 3 - Configuration du LaunchSettings.json

Ce fichier définit les profils de lancement de l’application: développement local en HTTP ou HTTPS, et Docker.

{
  "profiles": {
    "http": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "dotnetRunMessages": true,
      "applicationUrl": "http://localhost:7245"
    },
    "https": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "dotnetRunMessages": true,
      "applicationUrl": "https://localhost:7246;http://localhost:7245"
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
      "environmentVariables": {
        "ASPNETCORE_HTTPS_PORTS": "8081",
        "ASPNETCORE_HTTP_PORTS": "8080"
      },
      "publishAllPorts": true,
      "useSSL": true
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:24909",
      "sslPort": 44315
    }
  }
}
  • Profils HTTP & HTTPS: lancent l'application localement avec les ports 7245 et 7246.
  • Le Profil Docker: indique à Visual Studio comment lancer l'application dans Docker, avec le mappage des ports et les variables d'environnement correspondant aux ports exposés dans le Dockerfile.

Étape 4 - Construction de l'image Docker

Une fois le Dockerfile, le launchSettings et les CORS configurés, on utilise Docker Buildx pour créer une image multi-architecture, essentielle pour le déploiement sur Raspberry Pi :

docker buildx build --platform linux/arm64/v8,linux/amd64 -t quentindaumerial/accessdataapi:latest --push -f Dockerfile .

L'image est directement poussée sur Docker Hub.

Docker Hub après build de l’image API .NET

Pour valider le fonctionnement avant déploiement, on exécute l'image localement avec docker run :

docker run --rm -it -p 7245:8080 -p 7246:8081 \
  -e ASPNETCORE_HTTPS_PORTS=8081 \
  -e ASPNETCORE_HTTP_PORTS=8080 \
  -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" \
  -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx \
  -v %USERPROFILE%\.aspnet\https:/https/ accessdataapi

En se rendant sur https://localhost:7246/HotelCustomer/clients les données exposées depuis DB2 for i sont bien accessibles.

API .NET exécutée localement dans Docker

Étape 5 - Envoyer l’image sur le Raspberry Pi 5

Après avoir poussé l'image sur Docker Hub, on se connecte au Raspberry Pi en SSH et on télécharge l'image :

Connexion SSH au RaspberryPi 5

docker image pull quentindaumerial/accessdataapi:latest

Étape 6 - Lancement du conteneur sur le Raspberry Pi 5

On lance le conteneur en mappant le port 8080 du conteneur au port 5040 du Raspberry Pi :

docker run -it -p 5040:8080 quentindaumerial/accessdataapi:latest

L'API est accessible à l'adresse http://192.168.46.34:5040/hotelcustomer/clients.

API .NET déployée sur Raspberry Pi 5

Partie 2 - Déploiement de l’application Angular

Étape 1 - Préparation du Dockerfile

Le Dockerfile Angular se compose de deux étapes : construction et exécution.

### STAGE 1:BUILD ###

FROM node:latest AS build

WORKDIR /app

COPY package.json ./

RUN npm install

RUN npm build --configuration=production

### STAGE 2:RUN ###

FROM nginx:latest
COPY dist/app-data-manager /usr/share/nginx/html

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
  • Build : utilise l'image node pour installer les dépendances et compiler l'application en mode production.
  • Run : utilise nginxpour servir les fichiers compilés depuis /usr/share/nginx/html.

Étape 2 - Création du fichier nginx.conf

Ce fichier configure NGINX pour servir l'application Angular et gérer le routage côté client :

events{}

http {
    include /etc/nginx/mime.types; 
    server {        
        root /usr/share/nginx/html/browser;
        index /index.html;
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

La directive try_files indique à NGINX de renvoyer index.html pour toutes les routes gérées côté client, ce qui est indispensable pour le routage Angular.

Étape 3 - Configuration des environnements

Angular gère nativement les configurations de développement et de production, ce qui permet de pointer vers la bonne URL d'API selon le contexte.

  • Développement src/environments/environment.ts
export const environment = {
    production: false,
    apiBaseUrl: 'https://localhost:7246/'
};
  • Production src/environments/environment.prod.ts
export const environment = {
  production: true,
  apiBaseUrl: 'http://192.168.46.34:5040/'
};

La commande ng serve utilise automatiquement la configuration de développement sur localhost:4200.

Application Angular en développement local avec ng serve

Application Angular affichant les données DB2 for i

Étape 4 - Construction de l’image Docker

Comme pour l'API, on utilise Docker Buildx pour une image multi-architecture :

docker buildx build --platform linux/amd64,linux/arm64,linux/arm64/v8 -t quentindaumerial/appdatamanager:latest --push --no-cache .

Build multi-architecture de l’application Angular avec Docker Buildx

Image Angular mise à jour sur Docker Hub

Étape 5 - Déploiement sur le Raspberry Pi 4

Connexion en SSH au Raspberry Pi 4 :

Connexion SSH au Raspberry Pi 4

Téléchargement de l'image depuis Docker Hub :

docker image pull quentindaumerial/appdatamanager:latest

Téléchargement de l’image Angular sur Raspberry Pi 4

Étape 6 - Lancement du conteneur sur le Raspberry Pi 4

On mappe le port 80 du conteneur au port 5000 du Raspberry Pi :

docker run -it --platform linux/arm64/v8 -p 5000:80 quentindaumerial/appdatamanager:latest

Exécution de l’application Angular sur Raspberry Pi 4 avec Docker

L'application est accessible à l'adresse http://192.168.46.31:5000 et les données remontent bien depuis l'API, qui consomme DB2 for i via NTi :

Application Angular accessible depuis le navigateur sur Raspberry Pi 4

Application Angular consommant l’API .NET et affichant les données DB2 for i

Conclusion

Grâce à des Dockerfiles adaptés, à la configuration de NGINX pour Angular, et à l'ajustement des CORS et des profils de lancement de l'API .NET, les deux applications fonctionnent de manière isolée et communiquent sans problème dans un environnement conteneurisé.

Le connecteur NTi Data Provider joue ici un rôle central : il permet à une API .NET Core de dialoguer nativement avec DB2 for i, même depuis un conteneur Docker tournant sur un Raspberry Pi. Finalement, peu importe la machine sur laquelle tourne l'application, ce qui compte, c'est que les données arrivent au bon endroit, de manière fiable.


Quentin Destrade

Démarrez dès maintenant

Récupérez votre licence d’essai gratuite en ligne
et connectez vos applications .NET à votre IBM i en quelques minutes.

Créez votre compte

Connectez-vous au portail Aumerial, générez votre licence d’essai et activez NTi sur votre IBM i en quelques instants.

Démarrer l’essai

Ajouter NTi à votre projet

Installez NTi Data Provider depuis NuGet dans Visual Studio et référencez-le dans votre projet .NET.

Voir la documentation

Besoin d’aide ?

Si vous avez des questions sur nos outils ou sur les options de licence, notre équipe est disponible pour vous aider.

Nous contacter
30 jours d’essai gratuit activation immédiate sans engagement aucun composant à installer côté IBM i