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.