skip to Main Content

Ealier I had both ghostscript and graphicsmagick installed via apt install ..., but to support the latest versions I decided to uninstall and instead build and install from source

Before everything worked, but after installing from source graphicsmagick commands that require ghostscript fails (when running from nginx)

Command

gm convert -density 50 input.pdf[0] -background white -resize 140x140 -strip -quality 40 thumb.jpg

The above command works fine when running it as root, but when running it from the webserver nginx an error is returned

execvp failed, errno = 2 (No such file or directory) gm convert: "gs"
"-q" "-dBATCH" "-dSAFER" "-dMaxBitmap=50000000" "-dNOPAUSE"
"-sDEVICE=pnmraw" "-dTextAlphaBits=4" "-dGraphicsAlphaBits=4"
"-r50x50" "-dFirstPage=1" "-dLastPage=1" "-sOutputFile=/tmp/gmhjqkzP"
"–" "/tmp/gmZaShhP" "-c" "quit". gm convert: Request did not return
an image.

What is the reason for this and how to fix it?

Build and install (from source)

# cd /var/bin && wget https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10021/ghostscript-10.02.1.tar.gz && tar -xvf ghostscript-10.02.1.tar.gz
# cd ghostscript-10.02.1 && ./configure && make -j $(nproc) && make install

update

# type gs
gs is hashed (/usr/local/bin/gs)

The path /usr/local/bin is already included in /etc/profile

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin

When printing the PATH from nginx (HTTP request)

echo shell_exec('echo $PATH');

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

2

Answers


  1. The problem is that the nginx user does not have Ghostscript (i.e. the gs binary) in their PATH, whereas you and the root user do. So the nginx user cannot find gs, and fails to exec it.

    The first thing to do is su to, or login as, root (or any user who can run ghostscript), then run:

    type gs
    

    and it will tell you the full path to Ghostscript. Then you need to ensure that the nginx user has the directory containing gs on their PATH.

    Another way to find the full path to Ghostscript is with:

    sudo find / -type f -name "gs" 2> /dev/null
    

    Alternatively, you can alter the ImageMagick "delegates" file to include the full path to the Ghostscript executable. So, you need to find the delegates.xml that ImageMagick is using like this:

    identify -list configure | grep CONFIGURE_PATH
    

    and that will tell you something like this, though it will be different on debian since I am using homebrew on a Mac:

    CONFIGURE_PATH /opt/homebrew/Cellar/imagemagick/7.1.1-21/etc/ImageMagick-7/
    

    Then you need to add delegates.xml onto that PATH, to give something akin to:

    /opt/homebrew/Cellar/imagemagick/7.1.1-21/etc/ImageMagick-7/delegates.xml
    

    Then, after backing up that file, edit it and change where it says delegate decode=pdf so that it has the full path to ghostscript there for all users. It looks like this:

    <delegate decode="pdf" encode="ps" mode="bi" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=ps2write&quot; &quot;-sPDFPassword=%a&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;"/>
    

    So, you would need to change it to something more like this with the full path to gs:

    <delegate decode="pdf" encode="ps" mode="bi" command="&quot;/FULL/PATH/TO/gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=ps2write&quot; &quot;-sPDFPassword=%a&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;"/>
    
    Login or Signup to reply.
  2. You want:

    +-----------------+     calls    +------------------+
    |                 |  ----------> |                  |
    |  nginx (web)    |              |  graphicsmagick  |
    |                 | <----------  |                  |
    +-----------------+   requires   +------------------+
                                |
                                |
                                V
                        +-----------------+
                        |                 |
                        |  ghostscript    |
                        |   (from source) |
                        +-----------------+
    

    But graphicsmagick does not find ghostscript (mentioned in "Installing GraphicsMagick") when run by the nginx user, even though the gs path is included in PATH in /etc/profile.

    Since nginx runs as a specific user (usually nginx or www-data), this user might not have the same PATH as the root user.
    To check the PATH available to the nginx user, you can modify a script run by nginx to include echo $PATH > /tmp/nginx_path.txt. That will print the PATH seen by nginx to a file.

    If the path to gs is /usr/local/bin/gs, you can modify the startup script of nginx to include this path. For instance:

    # Edit nginx startup script
    sudo nano /etc/init.d/nginx
    
    # Find the section where PATH is set and modify it
    # For example:
    # PATH=/usr/local/bin:$PATH
    

    Or, update the script that calls graphicsmagick:

    #!/bin/bash
    # Set the PATH
    export PATH="/usr/local/bin:$PATH"
    
    # Then call your graphicsmagick command
    gm convert -density 50 input.pdf[0] -background white -resize 140x140 -strip -quality 40 thumb.jpg
    

    As a workaround, specify the full path to the ghostscript executable in your graphicsmagick command.

    gm convert -density 50 input.pdf[0] -background white -resize 140x140 -strip -quality 40 
       -command "/usr/local/bin/gs" thumb.jpg
    

    Make sure the nginx user has execute permissions on the ghostscript binary.
    And check that any security policies or apparmor profiles are not restricting access to the necessary paths for the nginx user.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search