Files
TechradarDev/Dockerfile.business
syoul 4b9073b8ee fix: corriger le script Python pour gérer les fins de ligne et les erreurs
- vérification de l'existence du fichier avant lecture
- utilisation de splitlines(keepends=True) pour préserver les fins de ligne
- gestion d'encodage UTF-8 explicite
- amélioration de la gestion des erreurs dans le Dockerfile
2025-12-09 10:03:55 +01:00

274 lines
12 KiB
Docker
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Utiliser une image Node.js légère
FROM node:20-alpine
# Build arguments pour invalider le cache si nécessaire
ARG BUILD_DATE=unknown
ARG BUILD_VERSION=unknown
ARG CACHE_BUST=1
LABEL build.date="${BUILD_DATE}" \
build.version="${BUILD_VERSION}" \
cache.bust="${CACHE_BUST}"
# Invalider le cache en utilisant CACHE_BUST dans une instruction RUN
# Cela force Docker à reconstruire à partir de cette ligne si CACHE_BUST change
# Utiliser CACHE_BUST dans une variable d'environnement pour forcer l'invalidation
RUN echo "Cache bust: ${CACHE_BUST}" && \
echo "Build date: ${BUILD_DATE}" && \
date && \
echo "${CACHE_BUST}" > /tmp/cache_bust.txt
WORKDIR /app
# Variables d'environnement à définir AVANT npm install
ENV HUSKY=0
ENV HUSKY_SKIP_INSTALL=1
ENV NODE_PATH=/app/node_modules
ENV NODE_ENV=production
# Installation des dépendances système
RUN apk add --no-cache git python3
# Copie des fichiers de dépendances
COPY package.json package-lock.json* ./
# Installation des dépendances Node
RUN npm install --legacy-peer-deps --ignore-scripts
# Patch du package aoe_technology_radar pour inclure gray-matter dans les dépendances runtime
RUN node -e "const fs=require('fs');const pkgPath='./node_modules/aoe_technology_radar/package.json';const pkg=JSON.parse(fs.readFileSync(pkgPath,'utf8'));pkg.dependencies=pkg.dependencies||{};pkg.dependencies['gray-matter']='^4.0.3';pkg.dependencies['postcss']='^8.4.47';pkg.scripts=pkg.scripts||{};pkg.scripts.prepare='';fs.writeFileSync(pkgPath,JSON.stringify(pkg,null,2));"
# Copie du reste du projet
COPY . .
RUN chmod +x scripts/start-business.sh
# Préparer .techradar une fois pour toutes (évite les réinstallations au runtime)
# Le script techradar.js crée automatiquement .techradar lors de l'exécution
# Création manuelle de .techradar en copiant depuis node_modules
RUN mkdir -p .techradar && \
cp -r node_modules/aoe_technology_radar/* .techradar/
# Créer le fichier hash pour éviter la recréation (calculé séparément pour éviter les problèmes d'échappement)
RUN node -e "const crypto=require('crypto');const fs=require('fs');const hash=crypto.createHash('sha256').update(fs.readFileSync('package.json')).digest('hex');fs.writeFileSync('.techradar/hash',hash);"
RUN node -e "const fs=require('fs');const p='.techradar/package.json';if(!fs.existsSync(p)){console.error('.techradar/package.json not found');process.exit(1);}const pkg=JSON.parse(fs.readFileSync(p,'utf8'));pkg.scripts=pkg.scripts||{};pkg.scripts.prepare='';fs.writeFileSync(p,JSON.stringify(pkg,null,2));"
# Installer les dépendances dans .techradar (y compris devDependencies pour tsx nécessaire à build:data)
RUN cd .techradar && npm install --legacy-peer-deps --include=dev
RUN cd .techradar && npm run build:icons
# --- CONFIGURATION BUSINESS ---
# Application de la logique Business (remplacement de la config et des données)
# Préserver la structure de dossiers par date pour que le framework puisse parser les dates
RUN cp radar-business/config-business.json config.json && \
rm -rf radar/* && \
mkdir -p radar/2025-01-15 && \
cp -r radar-business/2025-01-15/* radar/2025-01-15/
# Copier les fichiers nécessaires dans .techradar avant le build (comme le fait techradar.js)
RUN rm -rf .techradar/data/radar && \
mkdir -p .techradar/data/radar/2025-01-15 && \
cp -r radar-business/2025-01-15/* .techradar/data/radar/2025-01-15/ && \
# Supprimer toute release de démo (2017-03-01, 2024-03-01, etc.) éventuellement recopiée depuis le package
find .techradar/data/radar -mindepth 1 -maxdepth 1 ! -name '2025-01-15' -exec rm -rf {} + && \
cp radar-business/config-business.json .techradar/data/config.json && \
rm -rf .techradar/public && mkdir -p .techradar/public && \
cp -r public/* .techradar/public/ && \
cp public/team.html .techradar/public/team.html 2>/dev/null || true && \
cp public/team-visualization-data.json .techradar/public/team-visualization-data.json 2>/dev/null || true && \
cp about.md .techradar/data/about.md 2>/dev/null || echo "about.md not found, skipping" && \
cp custom.css .techradar/src/styles/custom.css 2>/dev/null || echo "custom.css not found, skipping" && \
echo "Fichiers public copiés" && \
echo "📁 Vérification des fichiers team dans .techradar/public/:" && \
ls -la .techradar/public/ | grep -E "(team\.html|team-visualization)" && echo "✅ Fichiers team trouvés" || (echo "⚠️ Fichiers team non trouvés dans .techradar/public/" && echo "📁 Contenu de public/ source:" && ls -la public/ | head -10) && \
echo "📁 Vérification que team.html existe dans public/ source:" && \
test -f public/team.html && echo "✅ public/team.html existe" || echo "❌ public/team.html n'existe pas"
# Diagnostic : compter les fichiers markdown copiés dans .techradar/data/radar
RUN echo "📊 Comptage des fichiers .md dans .techradar/data/radar" && \
find .techradar/data/radar -name "*.md" | wc -l && \
find .techradar/data/radar -name "*.md" | head -10
# Créer la page Next.js /team
RUN mkdir -p .techradar/src/pages && \
cat > .techradar/src/pages/team.tsx << 'EOF'
import Head from "next/head";
import { CustomPage } from "@/pages/_app";
const TeamPage: CustomPage = () => {
return (
<>
<Head>
<title>Équipe & Technologies - Laplank</title>
</Head>
<div style={{ width: '100%', height: '100vh', border: 'none', margin: 0, padding: 0 }}>
<iframe
src="/team.html"
style={{
width: '100%',
height: '100%',
border: 'none',
margin: 0,
padding: 0
}}
title="Équipe & Technologies"
/>
</div>
</>
);
};
export default TeamPage;
EOF
RUN echo "✅ Page team.tsx créée"
# Script Python pour ajouter le lien Équipe dans Navigation.tsx (évite les doublons)
RUN cat > /tmp/add_team_link.py << 'PYEOF'
import sys
import re
import os
f = ".techradar/src/components/Navigation/Navigation.tsx"
# Vérifier que le fichier existe
if not os.path.exists(f):
print(f"❌ Fichier {f} introuvable")
sys.exit(1)
with open(f, 'r', encoding='utf-8') as file:
content = file.read()
# Vérifier si le lien existe déjà (compter les occurrences)
team_link_count = len(re.findall(r'href=["\']/team["\']', content))
if team_link_count > 0:
print(f" Lien Équipe déjà présent ({team_link_count} occurrence(s))")
# Si plusieurs occurrences, supprimer les doublons
if team_link_count > 1:
print("⚠️ Détection de doublons, nettoyage...")
lines = content.splitlines(keepends=True)
if not lines or lines[-1] and not lines[-1].endswith('\n'):
lines[-1] = lines[-1] + '\n'
new_lines = []
in_team_link = False
team_link_added = False
skip_until_close = False
for line in lines:
if 'href="/team"' in line or "href='/team'" in line:
if not team_link_added:
# Garder la première occurrence
in_team_link = True
team_link_added = True
new_lines.append(line)
else:
# Ignorer les doublons
skip_until_close = True
continue
elif skip_until_close:
if '</li>' in line:
skip_until_close = False
continue
elif in_team_link:
new_lines.append(line)
if '</li>' in line:
in_team_link = False
else:
new_lines.append(line)
with open(f, 'w', encoding='utf-8') as file:
file.writelines(new_lines)
print("✅ Doublons supprimés")
sys.exit(0)
# Si le lien n'existe pas, l'ajouter
lines = content.splitlines(keepends=True)
if not lines or lines[-1] and not lines[-1].endswith('\n'):
lines[-1] = lines[-1] + '\n'
insert_idx = -1
for i, line in enumerate(lines):
if 'href="/overview"' in line:
for j in range(i, min(i+10, len(lines))):
if '</Link>' in lines[j] and j+1 < len(lines) and '</li>' in lines[j+1]:
insert_idx = j + 2
break
break
if insert_idx > 0:
new_lines = lines[:insert_idx] + [
' <li className={styles.item}>\n',
' <Link href="/team">\n',
' <span className={styles.label}>👥 Équipe</span>\n',
' </Link>\n',
' </li>\n'
] + lines[insert_idx:]
with open(f, 'w', encoding='utf-8') as file:
file.writelines(new_lines)
print("✅ Navigation.tsx modifié - lien Équipe ajouté")
sys.exit(0)
else:
print("❌ Impossible de trouver l'emplacement pour insérer le lien")
sys.exit(1)
PYEOF
# Modifier Navigation.tsx pour ajouter le lien Équipe (le script Python gère les doublons)
RUN echo "🔧 Modification de Navigation.tsx pour le lien Équipe..." && \
python3 /tmp/add_team_link.py || (echo "❌ Erreur lors de l'exécution du script Python" && exit 1) && \
team_count=$$(grep -c 'href="/team"' .techradar/src/components/Navigation/Navigation.tsx 2>/dev/null || echo "0") && \
if [ "$$team_count" -eq "1" ]; then \
echo "✅ Lien Équipe présent (1 occurrence)"; \
elif [ "$$team_count" -gt "1" ]; then \
echo "⚠️ Plusieurs occurrences détectées ($$team_count), relance du nettoyage..."; \
python3 /tmp/add_team_link.py || (echo "❌ Erreur lors du nettoyage" && exit 1); \
final_count=$$(grep -c 'href="/team"' .techradar/src/components/Navigation/Navigation.tsx 2>/dev/null || echo "0") && \
echo "✅ Après nettoyage: $$final_count occurrence(s)"; \
else \
echo "❌ Lien Équipe non trouvé après modification"; \
echo "📄 Contenu de Navigation.tsx:"; \
cat .techradar/src/components/Navigation/Navigation.tsx; \
exit 1; \
fi
# Builder l'application en mode production pour éviter Fast Refresh
# Utiliser WORKDIR pour changer de répertoire de manière fiable
WORKDIR /app/.techradar
RUN npm run build:data
RUN npm run build
# S'assurer que team.html et team-visualization-data.json sont copiés dans out/
# Next.js en mode export copie automatiquement les fichiers de public/, mais vérifions quand même
RUN if [ -d "out" ]; then \
echo "📁 Contenu de out/ avant copie:" && \
ls -la out/ | head -10 && \
echo "" && \
echo "🔍 Recherche de team.html..." && \
if [ -f "public/team.html" ]; then \
cp -v public/team.html out/team.html && echo "✅ team.html copié depuis public/ vers out/"; \
elif [ -f "/app/public/team.html" ]; then \
cp -v /app/public/team.html out/team.html && echo "✅ team.html copié depuis /app/public/ vers out/"; \
else \
echo "⚠️ team.html introuvable dans public/ ou /app/public/"; \
echo "📁 Contenu de public/:" && \
ls -la public/ 2>/dev/null | head -10 || echo "public/ non accessible"; \
echo "📁 Contenu de /app/public/:" && \
ls -la /app/public/ 2>/dev/null | head -10 || echo "/app/public/ non accessible"; \
fi && \
if [ -f "public/team-visualization-data.json" ]; then \
cp -v public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié dans out/"; \
else \
echo "⚠️ public/team-visualization-data.json introuvable"; \
fi && \
echo "" && \
echo "📁 Vérification finale dans out/:" && \
ls -la out/ | grep -E "(team\.html|team-visualization)" && echo "✅ Fichiers team présents dans out/" || echo "⚠️ Fichiers team non trouvés dans out/"; \
else \
echo "❌ Dossier out/ introuvable après build"; \
ls -la . | head -20; \
fi && \
echo "" && \
echo "📋 Vérification finale de Navigation.tsx après build:" && \
grep -q 'href="/team"' src/components/Navigation/Navigation.tsx && echo "✅ Lien Équipe toujours présent dans Navigation.tsx après build" || echo "❌ Lien Équipe absent de Navigation.tsx après build"
WORKDIR /app
# Exposition du port interne
EXPOSE 3000
# Démarrage du serveur via script (exporte les variables avant npm run serve)
CMD ["./scripts/start-business.sh"]