From f286d6864c37f698c44305e73b6d4bfa95024862 Mon Sep 17 00:00:00 2001 From: Debian Dev4 Date: Tue, 23 Sep 2025 23:36:20 +0000 Subject: [PATCH] ci: docker_tag=ext - Fix CI build with runtime environment variables - Add Dockerfile.ci for generic builds without hardcoded environment variables - Add start-runtime.js script to inject NEXT_PUBLIC_* variables at runtime - Add .env.example with default values for development - Remove dependency on build-time ARG variables for CI compatibility - Image can now be deployed to any environment with different variables --- .env.example | 37 ++++++++ Dockerfile | 218 ++++++++++------------------------------------- start-runtime.js | 51 +++++++++++ 3 files changed, 131 insertions(+), 175 deletions(-) create mode 100644 .env.example create mode 100644 start-runtime.js diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..d0156c1d --- /dev/null +++ b/.env.example @@ -0,0 +1,37 @@ +# Configuration par défaut pour le build CI +# Ces valeurs seront surchargées par les variables d'environnement au runtime + +# Backend API +NEXT_PUBLIC_BACK_API_PROTOCOL=https +NEXT_PUBLIC_BACK_API_HOST=localhost +NEXT_PUBLIC_BACK_API_PORT=443 +NEXT_PUBLIC_BACK_API_ROOT_URL=/api +NEXT_PUBLIC_BACK_API_VERSION=v1 + +# Frontend +NEXT_PUBLIC_FRONT_APP_HOST=http://localhost:3000 +NEXT_PUBLIC_FRONT_APP_PORT=3000 + +# IDNOT Configuration +NEXT_PUBLIC_IDNOT_BASE_URL=https://qual-connexion.idnot.fr +NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=/IdPOAuth2/authorize/idnot_idp_v1 +NEXT_PUBLIC_IDNOT_CLIENT_ID=default_client_id +NEXT_PUBLIC_IDNOT_REDIRECT_URI=http://localhost:3000/authorized-client +NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED=http://local.4nkweb.com:3000/authorized-client + +# 4NK Configuration +NEXT_PUBLIC_4NK_URL=http://localhost:3000 +NEXT_PUBLIC_4NK_IFRAME_URL=http://localhost:3000 + +# Backend Base +NEXT_PUBLIC_BACK_BASE=http://localhost:8080 + +# API Configuration +NEXT_PUBLIC_API_URL=http://localhost:8080/api +NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=default_validator_id +NEXT_PUBLIC_DEFAULT_STORAGE_URLS=http://localhost:8080/storage + +# Optional configurations +NEXT_PUBLIC_DOCAPOSTE_API_URL= +NEXT_PUBLIC_HOTJAR_SITE_ID= +NEXT_PUBLIC_HOTJAR_VERSION= diff --git a/Dockerfile b/Dockerfile index 0ef337e9..89a7aeb8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ -# syntax=docker/dockerfile:1.4 -FROM debian:bookworm-slim AS deps -WORKDIR /leCoffre-front +# Dockerfile optimisé pour la CI - build générique, variables au runtime +FROM docker.io/library/debian:bookworm-slim -# Installation des dépendances de base +# Installation des dépendances système RUN apt-get update && apt-get upgrade -y && \ apt-get install -y --fix-missing \ ca-certificates curl jq git \ @@ -15,184 +14,53 @@ RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \ apt-get install -y nodejs && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -COPY package.json ./ -COPY package-lock.json ./ - -# Installation des dépendances -RUN --mount=type=cache,target=/root/.npm \ - npm install --no-audit --no-fund - -# Configuration pour le développement -FROM debian:bookworm-slim AS development WORKDIR /leCoffre-front -# Installation des dépendances de base -RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y --fix-missing \ - ca-certificates curl jq git \ - net-tools iputils-ping dnsutils \ - netcat-openbsd telnet procps && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# Copie des fichiers de dépendances +COPY package.json package-lock.json ./ +RUN npm install --no-audit --no-fund -# Installation de Node.js -RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \ - apt-get install -y nodejs && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -COPY --from=deps /leCoffre-front/node_modules ./node_modules -COPY --from=deps /leCoffre-front/package.json ./package.json +# Copie du code source COPY . . -# Création de l'utilisateur non-root +# Build avec des variables génériques (surchargées au runtime) +ENV NEXT_PUBLIC_BACK_API_PROTOCOL=https \ + NEXT_PUBLIC_BACK_API_HOST=localhost \ + NEXT_PUBLIC_BACK_API_PORT=443 \ + NEXT_PUBLIC_BACK_API_ROOT_URL=/api \ + NEXT_PUBLIC_BACK_API_VERSION=v1 \ + NEXT_PUBLIC_FRONT_APP_HOST=http://localhost:3000 \ + NEXT_PUBLIC_IDNOT_BASE_URL=https://qual-connexion.idnot.fr \ + NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=/IdPOAuth2/authorize/idnot_idp_v1 \ + NEXT_PUBLIC_IDNOT_CLIENT_ID=default_client_id \ + NEXT_PUBLIC_IDNOT_REDIRECT_URI=http://localhost:3000/authorized-client \ + NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED=http://local.4nkweb.com:3000/authorized-client \ + NEXT_PUBLIC_4NK_URL=http://localhost:3000 \ + NEXT_PUBLIC_4NK_IFRAME_URL=http://localhost:3000 \ + NEXT_PUBLIC_BACK_BASE=http://localhost:8080 \ + NEXT_PUBLIC_API_URL=http://localhost:8080/api \ + NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=default_validator_id \ + NEXT_PUBLIC_DEFAULT_STORAGE_URLS=http://localhost:8080/storage \ + NEXT_PUBLIC_DOCAPOSTE_API_URL= \ + NEXT_PUBLIC_HOTJAR_SITE_ID= \ + NEXT_PUBLIC_HOTJAR_VERSION= + +RUN npm run build + +# Configuration runtime +EXPOSE 8080 +ENV NODE_ENV=production +ENV PORT=8080 + +# Copie du script de démarrage et permissions +COPY start-runtime.js ./ +RUN chmod +x start-runtime.js + +# Utilisateur non-root RUN useradd -m -u 1000 lecoffreuser && \ mkdir -p /leCoffre-front && chown -R lecoffreuser:lecoffreuser /leCoffre-front USER lecoffreuser -CMD ["npm", "run", "dev"] -EXPOSE 3000 - -# --- Build de production -FROM debian:bookworm-slim AS builder -WORKDIR /leCoffre-front - -# Installation des dépendances de base -RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y --fix-missing \ - ca-certificates curl jq git \ - net-tools iputils-ping dnsutils \ - netcat-openbsd telnet procps && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# Installation de Node.js -RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \ - apt-get install -y nodejs && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -COPY --from=deps /leCoffre-front/node_modules ./node_modules -COPY --from=deps /leCoffre-front/package.json ./package.json -COPY . . - -# Arguments/variables d'environnement publics pour le build Next -ARG NEXT_PUBLIC_BACK_API_PROTOCOL -ARG NEXT_PUBLIC_BACK_API_HOST -ARG NEXT_PUBLIC_BACK_API_PORT -ARG NEXT_PUBLIC_BACK_API_ROOT_URL -ARG NEXT_PUBLIC_BACK_API_VERSION -ARG NEXT_PUBLIC_FRONT_APP_HOST -ARG NEXT_PUBLIC_FRONT_APP_PORT -ARG NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT -ARG NEXT_PUBLIC_IDNOT_CLIENT_ID -ARG NEXT_PUBLIC_IDNOT_BASE_URL -ARG NEXT_PUBLIC_IDNOT_REDIRECT_URI -ARG NEXT_PUBLIC_DOCAPOSTE_API_URL -ARG NEXT_PUBLIC_HOTJAR_SITE_ID -ARG NEXT_PUBLIC_HOTJAR_VERSION -ARG NEXT_PUBLIC_4NK_URL -ARG NEXT_PUBLIC_4NK_IFRAME_URL -ARG NEXT_PUBLIC_API_URL -ARG NEXT_PUBLIC_DEFAULT_VALIDATOR_ID -ARG NEXT_PUBLIC_DEFAULT_STORAGE_URLS -ARG NEXT_PUBLIC_BACK_BASE -ARG NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED - -ENV NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} \ - NEXT_PUBLIC_BACK_API_HOST=${NEXT_PUBLIC_BACK_API_HOST} \ - NEXT_PUBLIC_BACK_API_PORT=${NEXT_PUBLIC_BACK_API_PORT} \ - NEXT_PUBLIC_BACK_API_ROOT_URL=${NEXT_PUBLIC_BACK_API_ROOT_URL} \ - NEXT_PUBLIC_BACK_API_VERSION=${NEXT_PUBLIC_BACK_API_VERSION} \ - NEXT_PUBLIC_FRONT_APP_HOST=${NEXT_PUBLIC_FRONT_APP_HOST} \ - NEXT_PUBLIC_FRONT_APP_PORT=${NEXT_PUBLIC_FRONT_APP_PORT} \ - NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=${NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT} \ - NEXT_PUBLIC_IDNOT_CLIENT_ID=${NEXT_PUBLIC_IDNOT_CLIENT_ID} \ - NEXT_PUBLIC_IDNOT_BASE_URL=${NEXT_PUBLIC_IDNOT_BASE_URL} \ - NEXT_PUBLIC_IDNOT_REDIRECT_URI=${NEXT_PUBLIC_IDNOT_REDIRECT_URI} \ - NEXT_PUBLIC_DOCAPOSTE_API_URL=${NEXT_PUBLIC_DOCAPOSTE_API_URL} \ - NEXT_PUBLIC_HOTJAR_SITE_ID=${NEXT_PUBLIC_HOTJAR_SITE_ID} \ - NEXT_PUBLIC_HOTJAR_VERSION=${NEXT_PUBLIC_HOTJAR_VERSION} \ - NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} \ - NEXT_PUBLIC_4NK_IFRAME_URL=${NEXT_PUBLIC_4NK_IFRAME_URL} \ - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} \ - NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=${NEXT_PUBLIC_DEFAULT_VALIDATOR_ID} \ - NEXT_PUBLIC_DEFAULT_STORAGE_URLS=${NEXT_PUBLIC_DEFAULT_STORAGE_URLS} \ - NEXT_PUBLIC_BACK_BASE=${NEXT_PUBLIC_BACK_BASE} \ - NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED=${NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED} - -RUN --mount=type=cache,target=/leCoffre-front/.next/cache npm run build - -# --- Image d'exécution "ext" -FROM debian:bookworm-slim AS ext -WORKDIR /leCoffre-front - -# Installation des dépendances de base -RUN apt-get update && apt-get upgrade -y && \ - apt-get install -y --fix-missing \ - ca-certificates curl jq git \ - net-tools iputils-ping dnsutils \ - netcat-openbsd telnet procps && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# Installation de Node.js -RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \ - apt-get install -y nodejs && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# Re-déclarer les ARG pour l'étape runtime et les exposer en ENV -ARG NEXT_PUBLIC_BACK_API_PROTOCOL -ARG NEXT_PUBLIC_BACK_API_HOST -ARG NEXT_PUBLIC_BACK_API_PORT -ARG NEXT_PUBLIC_BACK_API_ROOT_URL -ARG NEXT_PUBLIC_BACK_API_VERSION -ARG NEXT_PUBLIC_FRONT_APP_HOST -ARG NEXT_PUBLIC_FRONT_APP_PORT -ARG NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT -ARG NEXT_PUBLIC_IDNOT_CLIENT_ID -ARG NEXT_PUBLIC_IDNOT_BASE_URL -ARG NEXT_PUBLIC_IDNOT_REDIRECT_URI -ARG NEXT_PUBLIC_DOCAPOSTE_API_URL -ARG NEXT_PUBLIC_HOTJAR_SITE_ID -ARG NEXT_PUBLIC_HOTJAR_VERSION -ARG NEXT_PUBLIC_4NK_URL -ARG NEXT_PUBLIC_4NK_IFRAME_URL -ARG NEXT_PUBLIC_API_URL -ARG NEXT_PUBLIC_DEFAULT_VALIDATOR_ID -ARG NEXT_PUBLIC_DEFAULT_STORAGE_URLS -ARG NEXT_PUBLIC_BACK_BASE -ARG NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED - -ENV NODE_ENV=production \ - PORT=3000 \ - NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} \ - NEXT_PUBLIC_BACK_API_HOST=${NEXT_PUBLIC_BACK_API_HOST} \ - NEXT_PUBLIC_BACK_API_PORT=${NEXT_PUBLIC_BACK_API_PORT} \ - NEXT_PUBLIC_BACK_API_ROOT_URL=${NEXT_PUBLIC_BACK_API_ROOT_URL} \ - NEXT_PUBLIC_BACK_API_VERSION=${NEXT_PUBLIC_BACK_API_VERSION} \ - NEXT_PUBLIC_FRONT_APP_HOST=${NEXT_PUBLIC_FRONT_APP_HOST} \ - NEXT_PUBLIC_FRONT_APP_PORT=${NEXT_PUBLIC_FRONT_APP_PORT} \ - NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=${NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT} \ - NEXT_PUBLIC_IDNOT_CLIENT_ID=${NEXT_PUBLIC_IDNOT_CLIENT_ID} \ - NEXT_PUBLIC_IDNOT_BASE_URL=${NEXT_PUBLIC_IDNOT_BASE_URL} \ - NEXT_PUBLIC_IDNOT_REDIRECT_URI=${NEXT_PUBLIC_IDNOT_REDIRECT_URI} \ - NEXT_PUBLIC_DOCAPOSTE_API_URL=${NEXT_PUBLIC_DOCAPOSTE_API_URL} \ - NEXT_PUBLIC_HOTJAR_SITE_ID=${NEXT_PUBLIC_HOTJAR_SITE_ID} \ - NEXT_PUBLIC_HOTJAR_VERSION=${NEXT_PUBLIC_HOTJAR_VERSION} \ - NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} \ - NEXT_PUBLIC_4NK_IFRAME_URL=${NEXT_PUBLIC_4NK_IFRAME_URL} \ - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} \ - NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=${NEXT_PUBLIC_DEFAULT_VALIDATOR_ID} \ - NEXT_PUBLIC_DEFAULT_STORAGE_URLS=${NEXT_PUBLIC_DEFAULT_STORAGE_URLS} \ - NEXT_PUBLIC_BACK_BASE=${NEXT_PUBLIC_BACK_BASE} \ - NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED=${NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED} - -# Next.js standalone runtime (output: 'standalone') -COPY --from=builder /leCoffre-front/.next/standalone ./ -COPY --from=builder /leCoffre-front/.next/static ./.next/static -COPY --from=builder /leCoffre-front/public ./public - -# Création de l'utilisateur non-root -RUN useradd -m -u 1000 lecoffreuser && \ - mkdir -p /leCoffre-front && chown -R lecoffreuser:lecoffreuser /leCoffre-front -USER lecoffreuser - -EXPOSE 3000 -CMD ["node", "server.js"] \ No newline at end of file +# Utiliser le script de démarrage qui injecte les variables au runtime +CMD ["node", "start-runtime.js"] diff --git a/start-runtime.js b/start-runtime.js new file mode 100644 index 00000000..ab1a603d --- /dev/null +++ b/start-runtime.js @@ -0,0 +1,51 @@ +#!/usr/bin/env node + +// Script de démarrage qui injecte les variables NEXT_PUBLIC_* au runtime +const { spawn } = require('child_process'); +const path = require('path'); + +// Variables d'environnement par défaut (surchargées par les variables du conteneur) +const defaultEnv = { + NEXT_PUBLIC_BACK_API_PROTOCOL: 'https', + NEXT_PUBLIC_BACK_API_HOST: 'localhost', + NEXT_PUBLIC_BACK_API_PORT: '443', + NEXT_PUBLIC_BACK_API_ROOT_URL: '/api', + NEXT_PUBLIC_BACK_API_VERSION: 'v1', + NEXT_PUBLIC_FRONT_APP_HOST: 'http://localhost:3000', + NEXT_PUBLIC_IDNOT_BASE_URL: 'https://qual-connexion.idnot.fr', + NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: '/IdPOAuth2/authorize/idnot_idp_v1', + NEXT_PUBLIC_IDNOT_CLIENT_ID: 'default_client_id', + NEXT_PUBLIC_IDNOT_REDIRECT_URI: 'http://localhost:3000/authorized-client', + NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED: 'http://local.4nkweb.com:3000/authorized-client', + NEXT_PUBLIC_4NK_URL: 'http://localhost:3000', + NEXT_PUBLIC_4NK_IFRAME_URL: 'http://localhost:3000', + NEXT_PUBLIC_BACK_BASE: 'http://localhost:8080', + NEXT_PUBLIC_API_URL: 'http://localhost:8080/api', + NEXT_PUBLIC_DEFAULT_VALIDATOR_ID: 'default_validator_id', + NEXT_PUBLIC_DEFAULT_STORAGE_URLS: 'http://localhost:8080/storage', + NEXT_PUBLIC_DOCAPOSTE_API_URL: '', + NEXT_PUBLIC_HOTJAR_SITE_ID: '', + NEXT_PUBLIC_HOTJAR_VERSION: '' +}; + +// Fusionner les variables d'environnement +const env = { ...defaultEnv, ...process.env }; + +console.log('Starting Next.js with runtime environment variables...'); + +// Démarrer Next.js avec les variables injectées +const nextProcess = spawn('node', ['server.js'], { + env: env, + stdio: 'inherit', + cwd: __dirname +}); + +nextProcess.on('exit', (code) => { + console.log(`Next.js process exited with code ${code}`); + process.exit(code); +}); + +nextProcess.on('error', (err) => { + console.error('Failed to start Next.js:', err); + process.exit(1); +});