~/rebaz.dev
Back to articles
Node.jsDockerPM2

PDF Thumbnail Generation Fix for Ubuntu Server

PDF Thumbnail Generation Fix for Ubuntu Server

Rebaz OmarJune 3, 20255 min read
PDF Thumbnail Generation Fix for Ubuntu Server
Share this article

Problem Description

The PDF thumbnail generation feature works correctly on macOS development machines but fails on Ubuntu servers with the following error:

Error: spawn convert ENOENT

Or after installing ImageMagick:

convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/413.
convert-im6.q16: no images defined `png:-' @ error/convert.c/ConvertImageCommand/3258.

Root Cause

The pdftopic package used in the code requires:

  1. ImageMagick to be installed on the system
  2. Proper security policy configuration to allow PDF processing
  3. Additional system dependencies for image processing

Complete Solution

Step 1: Install Required System Dependencies

SSH into your Ubuntu server and run these commands:

# Update package list
sudo apt update

# Install ImageMagick and required dependencies
sudo apt install -y imagemagick
sudo apt install -y ghostscript
sudo apt install -y poppler-utils

# Install additional dependencies for Sharp (image processing)
sudo apt install -y libvips-dev
sudo apt install -y libglib2.0-dev
sudo apt install -y libexpat1-dev
sudo apt install -y libpng-dev
sudo apt install -y libjpeg-dev
sudo apt install -y libgif-dev
sudo apt install -y librsvg2-dev
sudo apt install -y libwebp-dev

Step 2: Configure ImageMagick Security Policy

ImageMagick has strict security policies that prevent PDF processing by default. You need to modify the security policy:

Option A: Find and Edit Existing Policy File

# Find the policy file location
sudo find /etc -name "policy.xml" | grep ImageMagick

# Edit the policy file (use the path found above)
sudo nano /etc/ImageMagick-6/policy.xml
# OR
sudo nano /etc/ImageMagick-7/policy.xml

Option B: Create New Policy File

If no policy file exists, create one:

# Create policy directory if it doesn't exist
sudo mkdir -p /etc/ImageMagick-6

# Create the policy file
sudo nano /etc/ImageMagick-6/policy.xml

Add this content to the policy file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policymap [
<!ELEMENT policymap (policy)*>
<!ELEMENT policy EMPTY>
<!ATTLIST policy domain (delegate|coder|filter|path) #REQUIRED>
<!ATTLIST policy name CDATA #IMPLIED>
<!ATTLIST policy rights (none|read|write|execute) #REQUIRED>
<!ATTLIST policy pattern CDATA #IMPLIED>
]>
<policymap>
  <!-- Allow PDF processing -->
  <policy domain="coder" rights="read|write" pattern="PDF" />

  <!-- Allow other common formats -->
  <policy domain="coder" rights="read|write" pattern="LABEL" />
  <policy domain="coder" rights="read|write" pattern="PNG" />
  <policy domain="coder" rights="read|write" pattern="JPEG" />
  <policy domain="coder" rights="read|write" pattern="GIF" />
  <policy domain="coder" rights="read|write" pattern="WEBP" />

  <!-- Allow reading from temporary directories -->
  <policy domain="path" rights="read" pattern="/tmp/*" />
  <policy domain="path" rights="read" pattern="/var/tmp/*" />
</policymap>

Step 3: Verify Installation

Test if ImageMagick is working correctly:

# Check if convert command is available
which convert

# Check ImageMagick version
convert --version

# Test PDF to PNG conversion (optional)
echo "Testing PDF processing..."
convert -density 200 -strip -background white -flatten test.pdf[0] test.png

Step 4: Rebuild Node.js Dependencies

After installing system dependencies, rebuild your Node.js application:

# Navigate to your server directory
cd /path/to/your/server

# Remove existing node_modules
rm -rf node_modules package-lock.json

# Reinstall dependencies
npm install

# Or if using yarn
yarn install

Step 5: Restart Your Application

Restart your Node.js application to ensure all changes take effect:

# If using PM2
pm2 restart all

# If using systemd
sudo systemctl restart your-app-service

# If using Docker
docker restart your-container-name

# Or restart manually
# (stop and start your Node.js process)

Verification

After completing all steps, test the PDF thumbnail generation:

  1. Upload a PDF file through your application
  2. Check the server logs for success messages
  3. Verify that a thumbnail image is generated and uploaded to AWS S3

Expected Success Logs

๐Ÿš€ Starting PDF thumbnail generation...
๐Ÿ“„ File details: { originalFilename: "document.pdf", ... }
๐Ÿ“ Checking upload directories...
โœ… Uploads directory already exists
โœ… Thumbnail directory already exists
๐Ÿ’พ Save path for PNG: ./public/uploads/thumbnail/document.pdf.png
๐Ÿ“– Reading PDF file from: /tmp/...
โœ… PDF file read successfully, size: 123456 bytes
๐Ÿ”„ Converting PDF first page to PNG using pdftobuffer...
โœ… PDF to PNG conversion successful, buffer size: 45678 bytes
๐Ÿ’พ Writing PNG buffer to file: ./public/uploads/thumbnail/document.pdf.png
โœ… PNG file written successfully
๐Ÿ–ผ๏ธ Sharp processing path: ./public/uploads/thumbnail/document.pdfabc123.png
๐Ÿ”„ Resizing image with Sharp...
โœ… Image resized successfully
๐Ÿ“ Original filename for upload: document.png
โ˜๏ธ Uploading to AWS S3...
โœ… File uploaded to AWS successfully
๐Ÿ—‘๏ธ Cleaning up local files...
โœ… Deleted savePath: ./public/uploads/thumbnail/document.pdf.png
โœ… Deleted sharpPath: ./public/uploads/thumbnail/document.pdfabc123.png
๐ŸŽ‰ PDF thumbnail generation completed successfully!

Troubleshooting

Common Issues

  1. Permission Denied Errors

    # Ensure proper permissions
    sudo chown -R $USER:$USER /path/to/your/app
    sudo chmod -R 755 /path/to/your/app/public/uploads
    
  2. ImageMagick Still Blocking PDFs

    # Check if policy file is being read
    convert -list policy | grep PDF
    
    # Restart ImageMagick services
    sudo systemctl restart imagemagick
    
  3. Sharp Dependencies Missing

    # Reinstall Sharp with proper dependencies
    npm uninstall sharp
    npm install sharp
    

Alternative Solutions

If ImageMagick continues to cause issues, consider:

  1. Using a different PDF library (pdf-poppler, pdf2pic)
  2. Using a headless browser (Puppeteer) to render PDFs
  3. Using cloud-based PDF processing services

Security Considerations

โš ๏ธ Important: Modifying ImageMagick security policies can have security implications:

  • Only allow PDF processing if absolutely necessary
  • Keep ImageMagick updated to the latest version
  • Monitor server logs for any suspicious activity
  • Consider using a dedicated container for PDF processing

Files Modified

  • /etc/ImageMagick-6/policy.xml - ImageMagick security policy
  • server/src/api/features/cloud/utils/cloud.getFirstPdfPageAndChangeToPng.utils.js - Added detailed logging

Dependencies Added

System Packages

  • imagemagick - Image processing library
  • ghostscript - PDF processing support
  • poppler-utils - PDF utilities
  • libvips-dev - Image processing library for Sharp
  • Various image format libraries (libpng-dev, libjpeg-dev, etc.)

Node.js Packages

  • pdftopic - PDF to image conversion
  • sharp - Image resizing and processing

References


Note: This solution is specifically for Ubuntu servers. For other Linux distributions, package names and installation commands may vary.

Gallery

PDF Thumbnail Generation Fix for Ubuntu Server - Image 1