diff --git a/CHANGELOG.md b/CHANGELOG.md index aee7d2d..3001c2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Toutes les versions notables de TechIBase sont documentées ici. Le projet est e ## [Non publié] +- Les images multi-architectures sont construites sans émulation pour l'étape de construction de l'interface (npm et Vite tournent sur l'architecture native du serveur de construction) : une publication pouvait rester bloquée pendant des dizaines de minutes sous émulation QEMU (version 0.0.10). ## [0.0.13] - Mises à jour en un clic - **Mises à jour en un clic (facultatif)** : un nouveau conteneur « updater » (image `ghcr.io/installation-04/techbase-updater`) permet de mettre à jour TechIBase depuis l'onglet Système du panneau d'administration : sauvegarde d'abord, changement de `TECHIBASE_VERSION`, téléchargement et redémarrage, vérification, **retour automatique** à l'ancienne version si la nouvelle ne démarre pas, et bouton « Revenir à vX.Y.Z ». Désactivé par défaut ; activé par `./install.sh --with-updater` ; réservé aux installations par images publiées. Il reçoit l'accès au socket Docker (équivalent à root sur le serveur) : il est isolé, protégé par un secret, n'accepte que trois actions fixes et l'administrateur doit retaper son mot de passe. Chaque demande et son résultat sont inscrits dans un journal d'audit (`audit_log`). Testé de bout en bout avec Docker réel en CI (`scripts/updater-e2e.sh`). diff --git a/Dockerfile b/Dockerfile index b7e6c6f..4eaa8b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,13 +6,18 @@ # The base is the official Debian-based postgres:15 image on purpose: existing # TechIBase databases were created by it, so the same glibc collation applies # and a data directory moves over unchanged. -FROM node:20-bookworm-slim AS web-build +# The web build only produces static files: run it on the builder's own architecture (never +# under QEMU emulation, where npm/esbuild can be very slow or hang). +FROM --platform=$BUILDPLATFORM node:20-bookworm-slim AS web-build WORKDIR /app COPY frontend/package*.json ./ RUN npm ci COPY frontend/ ./ RUN npm run build +# Node itself, for the target architecture (the web build above may run on another one). +FROM node:20-bookworm-slim AS node-bin + FROM node:20-bookworm-slim AS api-deps WORKDIR /app COPY backend/package*.json ./ @@ -32,7 +37,7 @@ RUN apt-get update \ && sed -i '/^[[:space:]]*gzip on;/d' /etc/nginx/nginx.conf # our conf.d file turns gzip on itself # Node comes from the official image rather than a distribution package. -COPY --from=web-build /usr/local/bin/node /usr/local/bin/node +COPY --from=node-bin /usr/local/bin/node /usr/local/bin/node WORKDIR /app COPY --from=api-deps /app/node_modules ./node_modules diff --git a/backend/test/single-container.test.js b/backend/test/single-container.test.js index 086bea4..3ce9f17 100644 --- a/backend/test/single-container.test.js +++ b/backend/test/single-container.test.js @@ -137,3 +137,15 @@ test('backup then restore brings back the database AND the uploaded documents', await db.drop(); } }); + +test('multi-arch builds never run npm/vite under QEMU, and never copy a build-platform node into the image', () => { + const root = read('Dockerfile'); + const front = read('frontend/Dockerfile'); + assert.match(root, /FROM --platform=\$BUILDPLATFORM node:[^\n]* AS web-build/); + assert.match(front, /FROM --platform=\$BUILDPLATFORM node:[^\n]* AS build/); + // The web build may run on another architecture than the image, so the node binary of the + // final image must come from a stage on the TARGET platform, not from web-build. + assert.match(root, /COPY --from=node-bin \/usr\/local\/bin\/node/); + assert.doesNotMatch(root, /COPY --from=web-build \/usr\/local\/bin\/node/); + assert.match(root, /FROM node:[^\n]* AS node-bin/); +}); diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 3be769a..176be48 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,5 +1,7 @@ # TechIBase web front end: React build served by nginx, which also proxies /api to the backend. -FROM node:20-alpine AS build +# The build only produces static files: run it on the builder's own architecture (never under +# QEMU emulation, where npm/esbuild can be very slow or hang); only the nginx stage is per-platform. +FROM --platform=$BUILDPLATFORM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci