Khairul Habib
Khairul Habib

Reputation: 471

html-pdf not work in docker to create pdf

i have an node js app which deploy into docker and using html-pdf library.

but when tried in local docker container, it return this error:

Error: spawn Unknown system error -8

at ChildProcess.spawn (node:internal/child_process:415:11)

at Object.spawn (node:child_process:698:9)

at PDF.PdfExec [as exec] (/srv/node_modules/html-pdf/lib/pdf.js:89:28)

at PDF.PdfToFile [as toFile] (/srv/node_modules/html-pdf/lib/pdf.js:85:8)

at exports.renderPdf (/srv/service/PdfRenderer.js:27:14)

at processTicksAndRejections (node:internal/process/task_queues:96:5)

at async /srv/routes/Report.js:63:16 {



errno: -8,

  code: 'Unknown system error -8',

  syscall: 'spawn'

}

this is how i create dockerfile:

FROM mhart/alpine-node:16.4.2

WORKDIR /srv
ADD . .
RUN npm install
RUN apk update && apk add --no-cache fontconfig curl curl-dev && \
    mkdir -p /usr/share && \
    cd /usr/share \
    && curl -L https://github.com/Overbryd/docker-phantomjs-alpine/releases/download/2.11/phantomjs-alpine-x86_64.tar.bz2 | tar xj \
    && ln -s /usr/share/phantomjs/phantomjs /usr/bin/phantomjs \
    && phantomjs --version

EXPOSE 3000
CMD ["node", "index.js"]

and this is how i'm rendering the PDF in node js:

const content = await compile(template, context)
        pdf.create(content,
            { format: 'Letter',
                footer: { contents: footer, height: '20mm' },
                header: { content: '', height: '6mm' },
                timeout: 540000 })
            .toFile(path, (err, response) => {
            if (err) {
                fs.unlinkSync(path)
                return console.log(err);
            }
            const data = fs.readFileSync(path)
            res.setHeader('Content-Type', 'application/pdf')
            res.setHeader('Content-Length', fs.statSync(path).size + 200)
            res.send(data)
            return fs.unlinkSync(path)
          });

the line that didn't work at .toFile() which i'm not sure why. but i will need to return pdf file i've tried to install phantom prebuild and adding phantomPath but it's still return the same error. is there any way that i can do to fix this problem

Upvotes: 1

Views: 6607

Answers (4)

Clark Hoang
Clark Hoang

Reputation: 1

Working solution of mine (update phantomized link as the link above is 404)

FROM node:16-alpine3.12
WORKDIR /
ADD . .

RUN npm install

ENV PHANTOMJS_VERSION=2.1.1
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin
RUN apk update && apk add --no-cache fontconfig curl curl-dev && \
    cd /tmp && curl -Ls https://github.com/topseom/phantomized/releases/download/${PHANTOMJS_VERSION}/dockerized-phantomjs.tar.gz | tar xz && \
    cp -R lib lib64 / && \
    cp -R usr/lib/x86_64-linux-gnu /usr/lib && \
    cp -R usr/share /usr/share && \
    cp -R etc/fonts /etc && \
    curl -k -Ls https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-${PHANTOMJS_VERSION}-linux-x86_64.tar.bz2 | tar -jxf - && \
    cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs

COPY package.json package-lock.json ./
RUN npm install phantomjs-prebuilt --s
RUN npm install -g html-pdf
RUN npm install
RUN apk --update add ttf-ubuntu-font-family fontconfig && rm -rf /var/cache/apk/*
COPY . ./
USER node

EXPOSE 3000
CMD ["node", "app.js"]

Upvotes: 0

i was with the same problem.

You'll need install PhantomJS manually since phantomjs-prebuilt won't work in linux alpine as you can see through this

Upvotes: 0

Khairul Habib
Khairul Habib

Reputation: 471

FROM node:8-alpine

WORKDIR /srv
# [omitted] git clone, npm install etc....

ENV PHANTOMJS_VERSION=2.1.1
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin
RUN apk update && apk add --no-cache fontconfig curl curl-dev && \
    cd /tmp && curl -Ls https://github.com/dustinblackman/phantomized/releases/download/${PHANTOMJS_VERSION}/dockerized-phantomjs.tar.gz | tar xz && \
    cp -R lib lib64 / && \
    cp -R usr/lib/x86_64-linux-gnu /usr/lib && \
    cp -R usr/share /usr/share && \
    cp -R etc/fonts /etc && \
    curl -k -Ls https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-${PHANTOMJS_VERSION}-linux-x86_64.tar.bz2 | tar -jxf - && \
    cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs

COPY package.json package-lock.json ./
RUN npm install phantomjs-prebuilt --s
RUN npm install -g html-pdf
RUN npm install
RUN chmod -R a+rwx /srv
RUN apk --update add ttf-ubuntu-font-family fontconfig && rm -rf /var/cache/apk/*
COPY . ./
VOLUME /srv
USER node



EXPOSE 3000
CMD ["node", "index.js"]

this is how i fixed my issues by install phantomjs prebuilt and html-pdf after copy and reinstall other package. also install back the font family so that my report have text in it. other wise the text will be blank in pdf

Upvotes: 3

bhwp
bhwp

Reputation: 51

This error seems related to phantomjs and its also documented in there docs

https://www.npmjs.com/package/phantomjs#installation-fails-with-spawn-enoent

Installation fails with spawn ENOENT This is NPM's way of telling you that it was not able to start a process. It usually means:
node is not on your PATH, or otherwise not correctly installed. tar is not on your PATH. This package expects tar on your PATH on Linux-based platforms.

Upvotes: 1

Related Questions