Skip to content

a5sh/rasterize-node

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rasterizer Fleet — Deployment Reference

Project structure

repo-root/
├── core/                        ← shared source (never deployed directly)
│   ├── fauxBold.js
│   ├── sharedRender.js
│   ├── renderPool.js
│   ├── renderWorker.js
│   └── NotoSans-Subset.ttf
├── scripts/
│   └── build.mjs               ← copies core/ → {platform}/lib/
├── cloudflare/                  ← wrangler deploy root
│   ├── worker.js
│   ├── wrangler.jsonc
│   └── package.json
├── netlify/                     ← Netlify base directory
│   ├── netlify.toml
│   ├── package.json
│   ├── functions/
│   │   └── rasterize.js
│   └── lib/                    ← GENERATED (gitignored)
├── vercel/                      ← Vercel root directory
│   ├── vercel.json
│   ├── package.json
│   ├── api/
│   │   └── rasterize.js
│   └── lib/                    ← GENERATED (gitignored)
├── render/                      ← Render.com rootDir
│   ├── render.yaml
│   ├── Dockerfile
│   ├── package.json
│   ├── server.js
│   ├── discord.js
│   └── lib/                    ← GENERATED (gitignored)
├── vps/                         ← Generic Node / Pterodactyl / Fly / Railway
│   ├── Dockerfile
│   ├── package.json
│   ├── server.js
│   ├── discord.js
│   └── lib/                    ← GENERATED (gitignored)
├── docker-compose.yml
└── .gitignore

Files to DELETE from old repo

core/font.js                          ← replaced by core/sharedRender.js
core/logic.js                         ← replaced by direct applyFauxBold calls
scripts/embed-font.mjs                ← replaced by scripts/build.mjs
netlify-node/                         ← entire old folder
node/                                 ← entire old folder (renamed to vps/)
render-node/                          ← entire old folder (renamed to render/)
vercel-node/                          ← entire old folder (renamed to vercel/)
edge-node/                            ← entire old folder (renamed to cloudflare/)

.gitignore additions

# Generated by scripts/build.mjs
netlify/lib/
vercel/lib/
render/lib/
vps/lib/
**/node_modules/
cloudflare/.wrangler/

Platform deployment

Cloudflare Workers

cd cloudflare
npm install
npx wrangler deploy
  • Root directory: cloudflare/
  • No build step — wrangler bundles ../core/ imports automatically
  • Font loaded as a Data binding via wrangler.jsonc rules (.ttf glob)

Netlify

UI settings:

Setting Value
Base directory netlify
Build command (leave blank — read from netlify.toml)
Publish directory (leave blank)
Functions directory netlify/functions

The netlify.toml handles everything:

command = "node ../scripts/build.mjs netlify"

This runs build.mjs from netlify/, which goes one level up (../) to reach scripts/ and core/, then copies them into netlify/lib/.


Vercel

UI settings:

Setting Value
Root directory vercel
Build command (leave blank — read from vercel.json)
Output directory (leave blank)

vercel.json handles the build:

"buildCommand": "node ../scripts/build.mjs vercel"

Render.com

UI settings:

Setting Value
Root directory render
Build command (read from render.yaml)
Start command npm start

render.yaml:

buildCommand: "npm install && node ../scripts/build.mjs render"
startCommand: npm start

Environment variables:

  • MAX_CONCURRENT — number of worker threads (default: 2, set based on instance CPU)
  • DISCORD_WEBHOOK_URL — webhook URL for dashboard (required)
  • PORT — set automatically by Render

VPS / Docker / Pterodactyl / Fly.io / Railway

Docker (recommended):

# Build context must be repo root
docker build -f vps/Dockerfile -t rasterize-vps .
docker run -p 3000:3000 \
  -e DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." \
  -e MAX_CONCURRENT=4 \
  rasterize-vps

Manual:

cd vps
npm install
node ../scripts/build.mjs vps   # or: npm run build
npm start

Environment variables:

  • MAX_CONCURRENT — worker threads (default: 4)
  • DISCORD_WEBHOOK_URL — webhook URL
  • NODE_NAME — display name in Discord dashboard
  • PORT — HTTP port (default: 3000)

Local testing with docker-compose

# From repo root
docker compose up --build

curl http://localhost:3001/health   # render-node
curl http://localhost:3002/health   # vps-node

How the build step works

scripts/build.mjs
  │
  ├── reads: core/fauxBold.js
  ├── reads: core/sharedRender.js
  ├── reads: core/renderPool.js
  ├── reads: core/renderWorker.js
  └── reads: core/NotoSans-Subset.ttf
  │
  └── writes to: {platform}/lib/

renderWorker.js uses createRequire(workerData.serverDir) to resolve @resvg/resvg-js from the platform's own node_modules/, regardless of where the worker file physically lives.


Font + bold consistency

Every node in the fleet:

  1. Loads only NotoSans-Subset.ttf (Regular) — loadSystemFonts: false, no fontDirs
  2. Calls applyFauxBold() before every render — adds stroke-width: 0.035em to bold elements
  3. Covers font-weight="bold", style="font-weight: bold", font-weight="600–900", and <tspan> children

This makes all nodes produce pixel-consistent output regardless of what system fonts the host OS has installed.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors