Web UI now accepts both images and PDFs. Images go through /strip as before; PDFs go through new /convert/pdf endpoint which renders all pages via pdftoppm and returns base64 JPEGs. Also updates page title and layout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1.6 KiB
1.6 KiB
PostConvert
Image/PDF-to-JPEG conversion microservice. Single-file Node.js/Express app (server.js).
Tech Stack
- Node.js 18+ (ES modules), Express
- Sharp (image processing), libheif-js (HEIC/HEIF via WASM)
- pdftoppm from Poppler (PDF rendering), archiver (ZIP output)
- Docker (node:20-bookworm-slim), deployed on Fly.io (sjc region)
Endpoints
GET /— web UI for stripping photo metadata (drag-and-drop, uses/strip)GET /health— health checkPOST /strip— strip metadata from image, return clean JPEG + removed metadata (JSON or raw)POST /convert— image or first PDF page → JPEG (resize/quality via headers)POST /convert/pdf— all PDF pages → JSON array of base64 JPEGs
Auth
Bearer token via CONVERTER_TOKEN env var on all endpoints.
Key Design
- Single-flight concurrency (1 conversion at a time, 429 if busy)
- Resize/quality via headers:
x-jpeg-quality,x-max-dimension,x-pdf-dpi,x-without-enlargement - Pixel limit 200M, bounded /tmp, no stack traces leaked, request timeouts
- Fly.io auto-scaling 0–10 machines, 2 concurrent connection hard limit
Environment Variables
PORT(default 8080)CONVERTER_TOKEN(required)REQ_TIMEOUT_MS(default 120s, range 5–600s)REQ_TIMEOUT_PDF_MS(default 5m, range 10s–30m)
Development
npm install
node server.js
Docker:
docker build -t postconvert .
docker run -e CONVERTER_TOKEN=secret -p 8080:8080 postconvert
Fly.io Deployment
Tokens are in .env (gitignored). Load with source .env or use dotenv.
Deploy: FLY_API_TOKEN="$FLY_API_TOKEN" fly deploy