Table of Contents

Docker et Linux

Exécuter la signature numérique du SDK .NET 8 sous Linux et en conteneur. Le module SecureExchanges.Signature.NetCore certifie les PDF avec Chromium sans interface, piloté par PuppeteerSharp ; sous Linux, Chromium a besoin de bibliothèques système que l'image doit fournir.

Cette configuration vaut pour tout hôte de conteneurs Linux : Azure Functions, Azure Container Apps, Azure App Service (Linux), Kubernetes.

Prérequis

  • Un projet .NET 8 ou plus qui référence SecureExchanges.Signature.NetCore.
  • Docker, ou un service de construction d'images comme az acr build.
  • La version de Chrome for Testing attendue par votre version du SDK (voir plus bas).

Où le SDK cherche Chromium

Ordre Emplacement
1 Un Chromium placé à côté de l'application : chromium/chrome-linux64/chrome sous Linux, chromium/chrome-win64/chrome.exe sous Windows
2 Le chemin donné par la variable d'environnement SE_PUPPETEER_EXECUTABLE_PATH
3 Le cache local de PuppeteerSharp, qui télécharge Chromium au premier usage, sauf si SE_DISABLE_AUTO_DOWNLOAD vaut 1 ou true

En production, placez Chromium dans l'image et bloquez le téléchargement : le démarrage ne dépend plus du réseau, et vous savez exactement quel binaire s'exécute.

Dockerfile

Construction en deux étapes : la première compile le projet, la seconde installe les dépendances de Chromium, ajoute Chrome for Testing à côté de l'application et copie le résultat.

Note

Ce Dockerfile vise Azure Functions (image de base et variables propres à Functions). Pour un autre hôte, remplacez l'image d'exécution par mcr.microsoft.com/dotnet/aspnet:8.0 ou équivalent, et adaptez le point d'entrée. Un projet complet est disponible sur GitHub : AzureFunctionsSignature.netCore.

# Azure Functions .NET 8 (worker isolé) avec Chromium sans interface.
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

COPY ["AzureFunctionsSignature.netCore.csproj", "./"]
RUN dotnet restore "AzureFunctionsSignature.netCore.csproj"
COPY . .
RUN dotnet publish "AzureFunctionsSignature.netCore.csproj" \
      -c Release \
      -o /app/publish \
      --no-restore \
      /p:UseAppHost=false


FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0 AS runtime

# Dépendances de Chromium pour Debian bookworm.
# Si une future version de Chrome échoue avec « error while loading shared libraries: libXXX.so »,
# ajoutez la bibliothèque ici et reconstruisez l'image.
RUN apt-get update && apt-get install -y --no-install-recommends \
      ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 \
      libcairo2 libcups2 libdbus-1-3 libdrm2 libexpat1 libfontconfig1 libgbm1 \
      libglib2.0-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 \
      libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 \
      libxfixes3 libxi6 libxkbcommon0 libxrandr2 libxrender1 libxshmfence1 libxss1 libxtst6 \
      wget unzip \
    && rm -rf /var/lib/apt/lists/*

# Chrome for Testing : version alignée sur celle de PuppeteerSharp (voir le tableau ci-dessous).
ARG CHROME_VERSION=146.0.7680.153
# Empreinte SHA-256 du fichier, obligatoire : l'image ne se construit pas si le fichier téléchargé
# ne correspond pas.
ARG CHROME_SHA256
RUN test -n "$CHROME_SHA256" \
    && wget -q "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chrome-linux64.zip" \
         -O /tmp/chrome.zip \
    && echo "${CHROME_SHA256}  /tmp/chrome.zip" | sha256sum -c - \
    && mkdir -p /home/site/wwwroot/chromium \
    && unzip -q /tmp/chrome.zip -d /home/site/wwwroot/chromium \
    && chmod +x /home/site/wwwroot/chromium/chrome-linux64/chrome \
    && rm /tmp/chrome.zip

# Chromium est dans l'image : pas de téléchargement à l'exécution.
# Un seul worker par instance : un seul processus Chromium, moins de mémoire.
ENV SE_DISABLE_AUTO_DOWNLOAD=1 \
    FUNCTIONS_WORKER_PROCESS_COUNT=1

COPY --from=build /app/publish /home/site/wwwroot

Construisez l'image en donnant l'empreinte du fichier :

docker build --build-arg CHROME_SHA256=<empreinte SHA-256 de chrome-linux64.zip> -t signature-pki .

Pour obtenir l'empreinte : téléchargez une fois le fichier depuis l'adresse officielle de Chrome for Testing, calculez-la (sha256sum chrome-linux64.zip, ou Get-FileHash sous Windows), puis fixez-la dans votre pipeline. Elle change à chaque changement de CHROME_VERSION.

Version de Chrome for Testing

PuppeteerSharp attend une version précise de Chrome for Testing ; l'image doit installer celle-là.

Version de SecureExchanges.Signature.NetCore Chrome for Testing
26.4.23.1 et suivantes 146.0.7680.153

Pour une version du SDK plus récente que ce tableau :

  1. Repérez la version attendue par PuppeteerSharp : au premier lancement sans Chromium, il la télécharge dans /tmp/Chrome/Linux-<version>/.
  2. Choisissez la même version sur le tableau de bord de Chrome for Testing.
  3. Mettez à jour CHROME_VERSION et CHROME_SHA256.

Un écart de version peut empêcher Chromium de démarrer ou modifier subtilement le rendu.

Variables d'environnement

Variable Rôle
SE_PUPPETEER_EXECUTABLE_PATH Chemin absolu d'un binaire Chromium, utilisé si aucun Chromium n'est placé à côté de l'application.
SE_DISABLE_AUTO_DOWNLOAD 1 ou true : interdit à PuppeteerSharp de télécharger Chromium à l'exécution. Recommandé dès que l'image contient Chromium.
FUNCTIONS_WORKER_PROCESS_COUNT Propre à Azure Functions : voir Azure Functions.
Attention

Sécurité.

  • Intégrité : ne retirez pas la vérification SHA-256 du téléchargement de Chrome ; elle garantit que l'image contient le binaire attendu.
  • Mises à jour : une version de Chrome figée ne reçoit plus de correctifs. Mettez-la à jour avec le SDK, et reconstruisez l'image régulièrement pour les correctifs du système.
  • Images de base : pour des constructions reproductibles, figez les images par leur empreinte (image@sha256:...) plutôt que par leur étiquette.
  • Identifiants : ne les placez jamais dans l'image ni dans le Dockerfile ; lisez-les à l'exécution depuis votre gestionnaire de secrets.

Et ensuite