0

I am working on a Node.js application that uses html-pdf, which uses PhantomJS when creating the pdf file given the html string.

Everything works fine, but when I want to build the application in Docker, this error occurs:

ERROR: Error: spawn /usr/src/app/node_modules/phantomjs-prebuilt/lib/phantom\bin\phantomjs.exe ENOENT
events.js:291
throw er; // Unhandled 'error' event
Error: write EPIPE
at afterWriteDispatched (internal/stream_base_commons.js:156:25)
at writeGeneric (internal/stream_base_commons.js:147:3)
at Socket._writeGeneric (net.js:785:11)
at Socket._write (net.js:797:8)
at writeOrBuffer (_stream_writable.js:352:12)
at Socket.Writable.write (_stream_writable.js:303:10)
at PDF.PdfExec [as exec] (/usr/src/app/node_modules/html-pdf/lib/pdf.js:141:15)
at PDF.PdfToFile [as toFile] (/usr/src/app/node_modules/html-pdf/lib/pdf.js:83:8)
at /usr/src/app/src/createPDF.js:87:42
at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:100:8)
at emitErrorCloseNT (internal/streams/destroy.js:68:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}

Here is the Dockerfile I am using:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .  

RUN npm install --production

RUN wget -O /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
RUN mkdir -p /usr/local/lib/node_modules/phantomjs/lib/phantom/
RUN tar xvjf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /tmp/phantomjs
RUN mv /tmp/phantomjs/phantomjs-2.1.1-linux-x86_64/* /usr/local/lib/node_modules/phantomjs/lib/phantom/
RUN rm -rf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz && rm -rf /tmp/phantomjs

EXPOSE 8080
CMD ["npm","run","serve"]

I prefer not to manually install PhantomJS but this is the only solution I found online.

I have also looked at other questions and tried to pass the path of phantom in the options but did not work.

Majed Badawi
  • 27,616
  • 4
  • 25
  • 48

2 Answers2

4

For anyone facing this issue in the future, here is how I managed to fix this problem:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .  

RUN npm install --production

RUN npm install -g phantomjs --unsafe-perm

EXPOSE 8080
CMD ["npm","run","serve"]

Then pass the global path of phantomjs in the options using requireg:

var options = { phantomPath: require('requireg')('phantomjs').path }
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
0

For me it worked like this, and the key point is you have to do npm install on the docker image where you are going to run your application and expose the port!

FROM node:12.18.4 AS dep

ENV PHANTOMJS_VERSION 2.1.1

COPY ./dist /app/ COPY ./package*.json /app/ WORKDIR /app RUN npm install --production

FROM node:12.18.4-slim COPY --from=dep /app /app WORKDIR /app

Install phantomjs

RUN apt-get update
&& apt-get install -y --no-install-recommends
ca-certificates
bzip2
fontconfig
libfontconfig
&& apt-get clean
&& rm -rf /var/lib/apt/lists/* RUN npm install --production RUN npm install -g phantomjs-prebuilt --unsafe-perm

EXPOSE 3000 CMD ["server.js"]