diff --git a/Dockerfile b/Dockerfile index 0b09099..2c58346 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,7 +63,14 @@ ENV NODE_OPTIONS="--max-old-space-size=4096" RUN npm run build # Nettoyer les fichiers inutiles pour réduire la taille -RUN rm -rf client node_modules/.cache +# On garde client/src/remotion car le serveur en a besoin au runtime pour le bundling +RUN rm -rf client/node_modules \ + client/.vite \ + node_modules/.cache \ + /tmp/remotion-* + +# Pré-bundler la composition Remotion pendant le build (speedup au premier rendu) +RUN node scripts/prebundle-remotion.js || true # Exposer le port de l'application EXPOSE 5555 diff --git a/scripts/prebundle-remotion.js b/scripts/prebundle-remotion.js new file mode 100644 index 0000000..e796457 --- /dev/null +++ b/scripts/prebundle-remotion.js @@ -0,0 +1,9 @@ +#!/usr/bin/env node +// Pre-bundle Remotion composition during Docker build. +// This warms up the Webpack cache so the first user render is fast. +const { bundle } = require('@remotion/bundler'); +const path = require('path'); + +bundle({ entryPoint: path.resolve(__dirname, '../client/src/remotion/index.ts') }) + .then(loc => console.log('✅ Remotion pre-bundle OK:', loc)) + .catch(e => { console.warn('⚠️ Remotion pre-bundle skipped:', e.message); process.exit(0); }); diff --git a/server/routes/remotion.ts b/server/routes/remotion.ts index 434f25b..a43727f 100644 --- a/server/routes/remotion.ts +++ b/server/routes/remotion.ts @@ -23,6 +23,20 @@ const storage = multer.diskStorage({ const upload = multer({ storage }); +/** Cached Remotion bundle URL — only bundle once per process lifecycle */ +let remotionBundleCache: string | null = null; + +async function getBundle(): Promise { + if (remotionBundleCache) return remotionBundleCache; + // Resolve relative to this file so it works in Docker and locally + // __dirname = server/routes, so ../.. → project root → client/src/remotion/index.ts + const entryPoint = path.resolve(__dirname, "../../client/src/remotion/index.ts"); + console.log("📦 Bundling Remotion from:", entryPoint); + remotionBundleCache = await bundle({ entryPoint }); + console.log("📦 Bundle cached at:", remotionBundleCache); + return remotionBundleCache; +} + /** * Strips hashtags and emojis from text for TTS synthesis. * Visual display keeps the full text. @@ -138,10 +152,8 @@ remotionRouter.post("/render", upload.array("images", 4), async (req, res) => { } } - console.log("🎬 Bundling Remotion project..."); - const bundleLocation = await bundle({ - entryPoint: path.resolve(process.cwd(), "client/src/remotion/index.ts"), - }); + console.log("🎬 Getting Remotion bundle (cached)..."); + const bundleLocation = await getBundle(); const inputProps = { images: imageUrls, overlayText, audioUrl, wordTimings };