Converting to PDF times out
-
I use jsreport embedded in a nodejs application. My users install the software one their PC as a Docker container.
Today one user messaged me that report are not being generated. After some investigation I found that after restarting docker, the first report renders as normal but the second report stalls again. This happens regardless off the size or complexity of the report. Normal processing time of the reports is normally from a couple of seconds to 30 seconds for really large reports.
Below is an example of a log from the docker container when running a report.
I currently have no clue where to look for a solution for this, any hint would be welcome2022-01-29T20:54:28.352Z - info: Starting rendering request 13 (user: null) 2022-01-29T20:54:28.358Z - debug: Inline data specified. 2022-01-29T20:54:28.359Z - debug: Found 1 resources for language "fr" 2022-01-29T20:54:28.361Z - debug: Executing script custom using http-server strategy 2022-01-29T20:54:28.356Z - info: Rendering template { name: ScoreExpress, recipe: chrome-pdf, engine: handlebars, preview: false } 2022-01-29T20:54:28.426Z - debug: Base url not specified, skipping its injection. 2022-01-29T20:54:28.437Z - debug: Replaced assets ["ScoreExpressStyles.css","ranking.tpl","teamRanking.tpl","workorderMixed.tpl","workorderBlocks.tpl","workorderBlocksGroupedCategory.tpl","workorderBlocksTimed.tpl","judgePanels.tpl","participantList.tpl","awards.tpl","clubList.tpl","clubParticipantList.tpl","clubTeams.tpl","planning.tpl"] 2022-01-29T20:54:28.455Z - debug: Replaced assets ["Graphik-Medium-Cy-Gr-Web.eot","Graphik-Medium-Cy-Gr-Web.woff","Graphik-Medium-Cy-Gr-Web.woff2","Graphik-Regular-Cy-Gr-Web.eot","Graphik-Regular-Cy-Gr-Web.woff","Graphik-Regular-Cy-Gr-Web.woff2","planned.svg","planned.svg","dns.svg","dns.svg","joker.svg"] 2022-01-29T20:54:28.457Z - debug: Rendering engine handlebars using http-server strategy 2022-01-29T20:54:28.521Z - debug: Taking compiled template from engine cache 2022-01-29T20:54:28.546Z - debug: Executing recipe chrome-pdf 2022-01-29T20:54:28.559Z - debug: Starting child request to render pdf header 2022-01-29T20:54:28.561Z - info: Starting rendering request 14 (user: null) 2022-01-29T20:54:28.565Z - info: Rendering anonymous template { recipe: html, engine: handlebars } 2022-01-29T20:54:28.568Z - debug: Inline data specified. 2022-01-29T20:54:28.569Z - debug: Resources not defined for this template. 2022-01-29T20:54:28.573Z - debug: Base url not specified, skipping its injection. 2022-01-29T20:54:28.588Z - debug: Replaced assets ["ScoreExpressHeaderStyles.css"] 2022-01-29T20:54:28.600Z - debug: Replaced assets ["Graphik-Medium-Cy-Gr-Web.eot","Graphik-Medium-Cy-Gr-Web.woff","Graphik-Medium-Cy-Gr-Web.woff2","Graphik-Regular-Cy-Gr-Web.eot","Graphik-Regular-Cy-Gr-Web.woff","Graphik-Regular-Cy-Gr-Web.woff2"] 2022-01-29T20:54:28.602Z - debug: Rendering engine handlebars using http-server strategy 2022-01-29T20:54:28.694Z - debug: Taking compiled template from engine cache 2022-01-29T20:54:28.704Z - debug: Executing recipe html 2022-01-29T20:54:28.705Z - info: Rendering request 14 finished in 144 ms 2022-01-29T20:54:28.705Z - debug: Skipping storing report. 2022-01-29T20:54:28.707Z - debug: Starting child request to render pdf footer 2022-01-29T20:54:28.708Z - info: Starting rendering request 15 (user: null) 2022-01-29T20:54:28.710Z - info: Rendering anonymous template { recipe: html, engine: handlebars } 2022-01-29T20:54:28.711Z - debug: Inline data specified. 2022-01-29T20:54:28.711Z - debug: Resources not defined for this template. 2022-01-29T20:54:28.713Z - debug: Base url not specified, skipping its injection. 2022-01-29T20:54:28.716Z - debug: Replaced assets ["ScoreExpressFooterStyles.css"] 2022-01-29T20:54:28.717Z - debug: Rendering engine handlebars using http-server strategy 2022-01-29T20:54:28.725Z - debug: Taking compiled template from engine cache 2022-01-29T20:54:28.726Z - debug: Executing recipe html 2022-01-29T20:54:28.727Z - info: Rendering request 15 finished in 19 ms 2022-01-29T20:54:28.727Z - debug: Skipping storing report. 2022-01-29T20:54:28.976Z - debug: Converting with chrome HeadlessChrome/93.0.4577.82 using dedicated-process strategy 2022-01-29T20:56:58.704Z - error: Rendering request 10 finished with error in 240712 ms 2022-01-29T20:56:58.705Z - error: Error when processing render request 10 Timeout Error: pdf generation not completed after 240000ms Error: Timeout Error: pdf generation not completed after 240000ms at Timeout._onTimeout (/usr/app/node_modules/jsreport-chrome-pdf/lib/conversion.js:293:19) at listOnTimeout (internal/timers.js:557:17) at processTimers (internal/timers.js:500:7) 2022-01-29T20:56:58.707Z - error: Error during processing request at http://localhost:8080/reporting/api/report
-
It looks like the chrome hangs. Unfortunately, I don't have good hints on how to troubleshoot it.
How do you install chrome into your docker images?
We apply some additional configs to work better in docker, do you do the same?
https://github.com/jsreport/jsreport/blob/2.7.1/docker/default/Dockerfile#L58
-
Hi Jan,
Thanks for the follow up.
It certainly looks like chrome hanging, but it doesn't provide much output to go on. It seems to be a recent phenomenon, because other customers have been reporting slow report generation lately.
The strange thing is that most of the time it works just fine, and suddenly PDF rendering starts taking way more time.
jsreport and dependencies are installed through npm install, since I list jsreport as dependency of my project (^2.11.0).
However I disable chromium download by npm install and build my docker image on top of an image that has chromium preinstalled (shivjm/node-chromium-alpine:14)
For completeness, this my docker build file:
FROM node:14-alpine AS build WORKDIR /usr/app-deps RUN apk update && apk upgrade && \ apk add --no-cache bash git openssh COPY package.json ./ ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 RUN git config --global url.https://github.com/.insteadOf git://github.com/ RUN npm install COPY . . RUN npm run build && \ npm prune --quiet --production FROM shivjm/node-chromium-alpine:14 USER node WORKDIR /usr/app COPY --chown=node:node --from=build /usr/app-deps/package.json /usr/app-deps/package-lock.json ./ COPY --chown=node:node --from=build /usr/app-deps/node_modules ./node_modules COPY --chown=node:node --from=build /usr/app-deps/common ./common COPY --chown=node:node --from=build /usr/app-deps/data ./data COPY --chown=node:node --from=build /usr/app-deps/dist ./dist COPY --chown=node:node --from=build /usr/app-deps/lib ./lib COPY --chown=node:node --from=build /usr/app-deps/locales ./locales COPY --chown=node:node --from=build /usr/app-deps/server ./server ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser ENV chrome_launchOptions_args --no-sandbox,--disable-dev-shm-usage ENTRYPOINT ["npm", "run", "start-docker"]
In my node server process, I initialize the jsreport service as follows:
const reportingApp = express(); app.use('/reporting', reportingApp); const server = require('http').Server(app); const storeDir = __dirname + '/../../data'; console.log('jsreport store dir', storeDir); const jsreport = require('jsreport')({ rootDirectory: __dirname + '/../../node_modules', extensions: { express: { app: reportingApp, server: server, }, authentication: { enabled: false, }, authorization: { enabled: false, }, cli: { enabled: false, }, debug: { enabled: true, }, freeze: { enabled: false, }, 'fs-store': { dataDirectory: storeDir, 'syncModifications': false, }, 'html-to-xlsx': { enabled: false, }, 'import-export': { enabled: true, }, jsrender: { enabled: false, }, 'public-templates': { enabled: false, }, 'resources': { enabled: true, }, 'sample-template': { enabled: false, }, scheduling: { enabled: false, }, scripts: { enabled: true, }, studio: { enabled: false, }, 'studio-theme-dark': { enabled: false, }, text: { enabled: true, }, 'version-control': { enabled: false, }, xlsx: { enabled: false, }, }, chrome: { timeout: 240000, }, templatingEngines: { numberOfWorkers: 2, timeout: 90000, strategy: 'http-server', }, logger: { console: {transport: 'console', level: 'debug'}, }, allowLocalFilesAccess: true, appPath: '/reporting', mountOnAppPath: true, store: {provider: 'fs'}, tempDirectory: 'temp', }); jsreport.init();
-
Hi Again,
I just noticed that you install version 79.
The image I use has version 93.Is there a specific reason for the version choice?
Best regards,
Axel
-
Is there a specific reason for the version choice?
We wanted to keep a consistent chrome version across the official images and npm package. That time the 79 wasn't available for alpine yet if I remember it right.
Also, the 79 version was sometimes 20% faster than the newer chrome versions.
Nevertheless, the jsreport v3 uses chrome 93 now.If you want to try to use the same chrome version as it's in the jsreport 2.11, you could inherit from the official alpine jsreport image
FROM jsreport/jsreport:2.11.0