fraserxu / electron-pdf

📄 A command line tool to generate PDF from URL, HTML or Markdown files.
MIT License
1.24k stars 136 forks source link

Running electron-pdf in a docker container #285

Open mpizosdim opened 3 years ago

mpizosdim commented 3 years ago

I have seen some posts from examples of Dockefile to run electron-pdf but with none of them had any success to make electron-pdf run inside a container.

The library seems to be install normally but when I run:

electron-pdf --version : I get no version or anything (I dont get an error) electrin-pdf example.html example.pdf: no output, no error.

Something to add which I am not sure if its related. If I run electron --version I get the following error:

[23:0407/164330.591827:FATAL:electron_main_delegate.cc(254)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180. /node_modules/electron/dist/electron exited with signal SIGTRAP

Can someone share a simple Dockerfile to test electron-pdf on a container?

eflukx commented 3 years ago

Yep same issue here. electron-pdf (cli) just plays dead, not any output whatever command line params provided. Running on Docker image node:lts (v14.16.1)

codecounselor commented 3 years ago

Here is mine, YMMV. I have a NodeJS http server that listens for requests inside the docker container, on port 3002. But I think you are probably missing some of the packages below, so maybe this will help.

Dockerfile

# Base image from ubuntu instead of node to get the correct version of muPDF (12) https://launchpad.net/ubuntu/+source/mupdf
FROM ubuntu:18.04

WORKDIR /app

################################################
####### Ubuntu Package Documentation ###########
################################################

# These were used by somebody who ran electron from Linux once upon a time, we don't seem to need them,
# but keeping here for a reference incase we do need fonts.
# -------------------------------------------
# libnotify4 xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic fonts-font-awesome fonts-takao-mincho

# Removed while upgrading to electron-pdf v4:
# -------------------------------------------
# libnss3 : network security
# libgconf2-4 : GNOME configuration database system for storing application preferences
# libxtst6 : X11 Testing -- Record extension library

# Required Dependencies:
# ----------------------
# xvfb -:Display Server that implements X11
# dbus-x11 : simple interprocess messaging system (X11 deps)
# libgtk-3-common : Required by Electron, GTK+ graphical user interface
# libxss1 : X11 Screen Saver extension library
# libasound2 : Required by Electron, shared library for ALSA applications
################################################

RUN apt-get update && \
  apt-get install -y curl && \
# Node v7 doesn't cut it anymore, so lets get 10 (what electron packages)
  curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
  apt-get install -y nodejs \
# Required for a GUI
    xvfb dbus-x11 libgtk-3-common \
# Required by Electron (to run)
    libxss1 libasound2 \
# Required for PDF -> PNG Conversion
    mupdf-tools \
# Used for PDF->PNG splitting by pdf2images-multiple
    poppler-utils && \
# Get rid of files we don't need
  rm -rf /var/lib/apt/lists/* && \
# Get latest npm
  npm install -g npm

# Copy this before user and folder permissions are assigned but as late as possible
# To prevent additional docker layers from needing rebuilt when it changes
COPY ./package.json build/docker-start.sh start.js /app/
COPY src/ /app/src

RUN \
# sbe is a non-privileged user for running the export server
# (so that there is no attack vector from root escalating out onto the host;
#  this is a docker best practice for running in production)
# Home directory is for the Chrome sandbox
# Hard coded ids of 1500:1500 so we can map the user/group to the production host user/group
groupadd -g 1500 -r sbe && \
useradd -u 1500 --no-log-init -m -r -g sbe -G audio,video sbe && \
mkdir -p /home/sbe/Downloads && \
chown -R sbe:sbe /home/sbe && \
chown -R sbe:sbe /app && \
chmod -R 755 /app

# Run as a non-privileged user (inside the container)
USER sbe

ENV NODE_ENV="production"
# Must be after setting the sbe user or electron will choke on file permissions
RUN npm install

ENV \
# The ip or the hostname that the server will listen on
ELECTRONEXPORT_HOST="0.0.0.0" \
# The port that the server will listen on (http)
ELECTRONEXPORT_PORT="3002" \
# Can optionally be mounted, otherwise all export artifacts will be ephemeral
ELECTRONEXPORT_DATA="/data" \
# This folder must be mounted into the container as a volume
ELECTRONEXPORT_LOGDIR="/var/log/export" \
# Size of each log file in MB, 10 files will be kept
ELECTRONEXPORT_LOGSIZE="1" \
# Log level for production environment
ELECTRONEXPORT_LOGLEVEL="info" \
# (Scoreboard Issue #19118) - 100 is the default, but we ned a bit more time
ELECTRONPDF_PNG_CAPTURE_DELAY=250 \
# So log events show up for the libraries that use the 'debug' module
DEBUG="electronpdf*,pdf*"
# https://github.com/electron/electron/blob/master/docs/api/environment-variables.md#electron_enable_stack_dumping
#ELECTRON_ENABLE_STACK_DUMPING=true

EXPOSE 3002

CMD ["sh", "/app/docker-start.sh"]

docker-start.sh

#!/bin/sh

export DISPLAY=:99

# Start xvfb
if pgrep -x "Xvfb" > /dev/null
then
    echo "Xvfb is already running"
else
    echo "Starting Xvfb screen $DISPLAY"
    rm /tmp/.X99-lock
    /usr/bin/Xvfb $DISPLAY -ac -screen 0 1920x1280x24 &
    # Give time to dbus & Xvfb to boot
    sleep 1
fi

# Start application
cd /app
npm run dockerStart
amsaddaa commented 3 years ago

Here is mine, YMMV. I have a NodeJS http server that listens for requests inside the docker container, on port 3002. But I think you are probably missing some of the packages below, so maybe this will help.

Dockerfile

# Base image from ubuntu instead of node to get the correct version of muPDF (12) https://launchpad.net/ubuntu/+source/mupdf
FROM ubuntu:18.04

WORKDIR /app

################################################
####### Ubuntu Package Documentation ###########
################################################

# These were used by somebody who ran electron from Linux once upon a time, we don't seem to need them,
# but keeping here for a reference incase we do need fonts.
# -------------------------------------------
# libnotify4 xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic fonts-font-awesome fonts-takao-mincho

# Removed while upgrading to electron-pdf v4:
# -------------------------------------------
# libnss3 : network security
# libgconf2-4 : GNOME configuration database system for storing application preferences
# libxtst6 : X11 Testing -- Record extension library

# Required Dependencies:
# ----------------------
# xvfb -:Display Server that implements X11
# dbus-x11 : simple interprocess messaging system (X11 deps)
# libgtk-3-common : Required by Electron, GTK+ graphical user interface
# libxss1 : X11 Screen Saver extension library
# libasound2 : Required by Electron, shared library for ALSA applications
################################################

RUN apt-get update && \
  apt-get install -y curl && \
# Node v7 doesn't cut it anymore, so lets get 10 (what electron packages)
  curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
  apt-get install -y nodejs \
# Required for a GUI
    xvfb dbus-x11 libgtk-3-common \
# Required by Electron (to run)
    libxss1 libasound2 \
# Required for PDF -> PNG Conversion
    mupdf-tools \
# Used for PDF->PNG splitting by pdf2images-multiple
    poppler-utils && \
# Get rid of files we don't need
  rm -rf /var/lib/apt/lists/* && \
# Get latest npm
  npm install -g npm

# Copy this before user and folder permissions are assigned but as late as possible
# To prevent additional docker layers from needing rebuilt when it changes
COPY ./package.json build/docker-start.sh start.js /app/
COPY src/ /app/src

RUN \
# sbe is a non-privileged user for running the export server
# (so that there is no attack vector from root escalating out onto the host;
#  this is a docker best practice for running in production)
# Home directory is for the Chrome sandbox
# Hard coded ids of 1500:1500 so we can map the user/group to the production host user/group
groupadd -g 1500 -r sbe && \
useradd -u 1500 --no-log-init -m -r -g sbe -G audio,video sbe && \
mkdir -p /home/sbe/Downloads && \
chown -R sbe:sbe /home/sbe && \
chown -R sbe:sbe /app && \
chmod -R 755 /app

# Run as a non-privileged user (inside the container)
USER sbe

ENV NODE_ENV="production"
# Must be after setting the sbe user or electron will choke on file permissions
RUN npm install

ENV \
# The ip or the hostname that the server will listen on
ELECTRONEXPORT_HOST="0.0.0.0" \
# The port that the server will listen on (http)
ELECTRONEXPORT_PORT="3002" \
# Can optionally be mounted, otherwise all export artifacts will be ephemeral
ELECTRONEXPORT_DATA="/data" \
# This folder must be mounted into the container as a volume
ELECTRONEXPORT_LOGDIR="/var/log/export" \
# Size of each log file in MB, 10 files will be kept
ELECTRONEXPORT_LOGSIZE="1" \
# Log level for production environment
ELECTRONEXPORT_LOGLEVEL="info" \
# (Scoreboard Issue #19118) - 100 is the default, but we ned a bit more time
ELECTRONPDF_PNG_CAPTURE_DELAY=250 \
# So log events show up for the libraries that use the 'debug' module
DEBUG="electronpdf*,pdf*"
# https://github.com/electron/electron/blob/master/docs/api/environment-variables.md#electron_enable_stack_dumping
#ELECTRON_ENABLE_STACK_DUMPING=true

EXPOSE 3002

CMD ["sh", "/app/docker-start.sh"]

docker-start.sh

#!/bin/sh

export DISPLAY=:99

# Start xvfb
if pgrep -x "Xvfb" > /dev/null
then
    echo "Xvfb is already running"
else
    echo "Starting Xvfb screen $DISPLAY"
    rm /tmp/.X99-lock
    /usr/bin/Xvfb $DISPLAY -ac -screen 0 1920x1280x24 &
    # Give time to dbus & Xvfb to boot
    sleep 1
fi

# Start application
cd /app
npm run dockerStart

Hello,

Can you please share the solution? I am not familiar with node apps. I am trying to make a simple service that accepts a url and returns the file in a mounted volume.

Many thanks

karwank commented 2 years ago

Try to add:

security_opt:
    - seccomp:unconfined

in your docker-compose.yml file.