From 43152351faecea9ef03e2e393ad071c6ed650971 Mon Sep 17 00:00:00 2001 From: alexz Date: Sat, 11 Apr 2026 14:59:50 +0000 Subject: [PATCH] fix: prevent Chromium zombie leak in htmlToPdf - Wrap browser lifecycle in try/finally so browser.close() always runs - Fall back to SIGKILL of browser.process() if close() fails - Add --disable-dev-shm-usage to launch args (container stability) - Add tini as ENTRYPOINT in Dockerfile for defense in depth - Bump version to 1.0.2 --- Dockerfile | 2 ++ convert.js | 75 +++++++++++++++++++++++++++++----------------------- package.json | 2 +- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/Dockerfile b/Dockerfile index b62f3b3..f53f051 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ chromium \ fonts-freefont-ttf \ fonts-noto-cjk \ + tini \ && rm -rf /var/lib/apt/lists/* WORKDIR /app @@ -21,4 +22,5 @@ EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1))" +ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["node", "server.js"] diff --git a/convert.js b/convert.js index 0ceabfd..63ff6f8 100644 --- a/convert.js +++ b/convert.js @@ -235,43 +235,52 @@ async function htmlToPdf(html) { const browser = await puppeteer.launch({ executablePath: process.env.CHROME_PATH || "/usr/bin/google-chrome-stable", - args: ["--no-sandbox", "--disable-setuid-sandbox"], + args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"], }); - const page = await browser.newPage(); + try { + const page = await browser.newPage(); - const htmlForPdf = html.replace( - /