fix: run OG image generation in subprocess to prevent OOM kill

The OG generation in the eleventy.before hook consumed too much memory
alongside Eleventy's data cascade, causing the Eleventy process to be
OOM-killed on Cloudron. Fix by running OG generation in a separate
child process with its own 768MB heap limit. Also write the manifest
incrementally (every 10 images) to preserve progress if interrupted.
This commit is contained in:
Ricardo
2026-02-18 08:49:11 +01:00
parent afc394525b
commit 86cbc1ee5d
3 changed files with 35 additions and 3 deletions

19
lib/og-cli.js Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env node
/**
* CLI entry point for OG image generation.
* Runs as a separate process to isolate memory from Eleventy.
*
* Usage: node lib/og-cli.js <contentDir> <cacheDir> <siteName>
*/
import { generateOgImages } from "./og.js";
const [contentDir, cacheDir, siteName] = process.argv.slice(2);
if (!contentDir || !cacheDir || !siteName) {
console.error("[og] Usage: node og-cli.js <contentDir> <cacheDir> <siteName>");
process.exit(1);
}
await generateOgImages(contentDir, cacheDir, siteName);

View File

@@ -288,6 +288,7 @@ export async function generateOgImages(contentDir, cacheDir, siteName) {
let generated = 0;
let skipped = 0;
const newManifest = {};
const SAVE_INTERVAL = 10;
for (const filePath of mdFiles) {
const raw = readFileSync(filePath, "utf8");
@@ -320,6 +321,11 @@ export async function generateOgImages(contentDir, cacheDir, siteName) {
writeFileSync(join(ogDir, `${slug}.png`), pngBuffer);
newManifest[slug] = { title: slug, hash };
generated++;
// Save manifest periodically to preserve progress
if (generated % SAVE_INTERVAL === 0) {
writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2));
}
}
writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2));