Skip to content

fix: PDF export broken in Docker and Serverless (Vercel) environments - #890

Open
ramanujamgond wants to merge 2 commits into
joemccann:masterfrom
ramanujamgond:fix/pdf-export-docker-puppeteer
Open

fix: PDF export broken in Docker and Serverless (Vercel) environments#890
ramanujamgond wants to merge 2 commits into
joemccann:masterfrom
ramanujamgond:fix/pdf-export-docker-puppeteer

Conversation

@ramanujamgond

@ramanujamgond ramanujamgond commented Feb 22, 2026

Copy link
Copy Markdown

Summary

Fixes #885 - PDF export broken on dillinger.io

This PR fixes the PDF export functionality that fails in both Docker and serverless (Vercel/AWS Lambda) environments.

Issues Addressed

Docker Environment Error

Failed to move to new namespace: PID namespaces supported, Network namespace supported, 
but failed: errno = Operation not permitted

Serverless (Vercel) Environment Error

Could not find Chrome (ver. 142.0.7444.175). This can occur if either
1. you did not perform an installation before running the script
2. your cache path is incorrectly configured (which is: /home/sbx_user1051/.cache/puppeteer)

Root Cause Analysis

1. Incorrect launch_options Format

The md-to-pdf library expects launch_options to be an object matching Puppeteer's launch options format, but it was incorrectly passed as an array.

2. Docker Security Restrictions

Docker's default seccomp profile blocks the system calls that Chromium needs to create namespaces for its sandbox.

3. Serverless Chrome Missing

Serverless platforms like Vercel don't have Chrome pre-installed. The standard Puppeteer package tries to find Chrome in a cache directory that doesn't exist in these environments.

Changes Made

plugins/core/server.js

  • Added smart environment detection using @sparticuz/chromium
  • Serverless mode: Uses @sparticuz/chromium for Vercel/Lambda environments
  • Docker mode: Falls back to system Chrome with proper sandbox flags
let chromium
try {
  chromium = require('@sparticuz/chromium')
} catch (e) {
  chromium = null
}

// In markdown2Pdf:
if (chromium) {
  // Serverless (Vercel, AWS Lambda)
  launchOptions = {
    args: chromium.args,
    executablePath: await chromium.executablePath(),
    headless: chromium.headless
  }
} else {
  // Docker/traditional server
  launchOptions = {
    executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined,
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', 
           '--disable-gpu', '--single-process', '--no-zygote']
  }
}

package.json

  • Added @sparticuz/chromium: ^131.0.0 dependency for serverless Chrome support

docker-compose.yml

  • Added security_opt: seccomp=unconfined - Disables seccomp filtering
  • Added cap_add: SYS_ADMIN - Grants capability for namespace operations

Validation

This fix has been validated against multiple sources:

Testing

Docker

docker-compose down
docker-compose build --no-cache
docker-compose up

Vercel

The @sparticuz/chromium package is automatically detected and used when deployed to Vercel.

Note for Maintainers

If Vercel deployment still has issues, you may need to:

  1. Ensure the Vercel function has sufficient memory (1024MB+ recommended)
  2. Check if libnss3.so or other dependencies are missing (may require custom build)

Fixes joemccann#885

## Problem
PDF export fails in Docker with the error:
"Failed to move to new namespace: PID namespaces supported, Network
namespace supported, but failed: errno = Operation not permitted"

This occurs because:
1. The `launch_options` was incorrectly passed as an array instead of
   an object (md-to-pdf expects Puppeteer's launch options format)
2. Docker's default security profile blocks Chromium's namespace
   creation needed for sandboxing

## Solution

### plugins/core/server.js
- Fixed `launch_options` to use correct object format instead of array
- Added `executablePath` to use PUPPETEER_EXECUTABLE_PATH env var
- Added critical Chrome flags for containerized environments:
  - `--no-sandbox` - Disable Chrome sandbox
  - `--disable-setuid-sandbox` - Disable setuid sandbox
  - `--disable-dev-shm-usage` - Overcome /dev/shm size issues
  - `--disable-gpu` - Disable GPU hardware acceleration
  - `--single-process` - Run in single process mode
  - `--no-zygote` - Disable zygote process forking

### docker-compose.yml
- Added `security_opt: seccomp=unconfined` to disable seccomp filtering
- Added `cap_add: SYS_ADMIN` capability for namespace operations

## Note on Production (dillinger.io)
The production site appears to run on a serverless/sandboxed environment
(path shows `/home/sbx_user1051/`). Serverless platforms like Vercel have
significant limitations with Puppeteer due to function size limits and
missing Chrome dependencies. For production, consider:
- Using @sparticuz/chromium for serverless environments
- Self-hosting Chromium binary
- Using a remote browser service like browserless.io
@vercel

vercel Bot commented Feb 22, 2026

Copy link
Copy Markdown

@ramanujamgond is attempting to deploy a commit to the Joe McCann's projects Team on Vercel.

A member of the Team first needs to authorize it.

This commit extends the PDF export fix to support both Docker and
serverless environments (Vercel, AWS Lambda, etc.)

Changes:
- Add @sparticuz/chromium dependency for serverless Chromium support
- Implement smart environment detection in markdown2Pdf function
- If @sparticuz/chromium is available, use serverless-optimized config
- Otherwise, fall back to Docker/traditional server configuration

This fixes:
- Docker: "Failed to move to new namespace" error
- Vercel: "Could not find Chrome" error (issue joemccann#885)

The code automatically detects the environment:
- Serverless (Vercel/Lambda): Uses @sparticuz/chromium executable
- Docker/Server: Uses system Chromium with sandbox-disabled flags
@ramanujamgond ramanujamgond changed the title fix: PDF export broken in Docker - Puppeteer namespace error fix: PDF export broken in Docker and Serverless (Vercel) environments Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PDF export broken on dillinger.io - "Could not find Chrome (ver. 142.0.7444.175)"

1 participant