Skip to content
You're viewing documentation for v1.2. It may be out of date.Go to latest
jalco-drop
Esc
↑↓navigate↵open⌘Jpreview
On this page

Self-hosting

Every setting for Cloudflare, Docker and Neon, and how storage, previews and expiry work on each.

jalco-drop is one app with three entry points: src/worker.ts for Cloudflare, src/node.ts for Node and Docker, and src/neon-function.ts for Neon Functions. Storage, rate limiting, preview cards and the hourly cleanup sit behind small interfaces, so all three behave the same.

Cloudflare Docker Neon
Storage R2 A /data volume, or any S3-compatible bucket A Neon bucket
Preview cards Browser Rendering Chromium in the image Summary card, no image
Rate limit Workers rate limiting, 60 a minute per IP In memory, 60 a minute per IP In memory, per instance
Expiry cleanup Hourly cron trigger Hourly timer Hourly schedule trigger
Largest upload 100 MB (Cloudflare’s limit) MAX_UPLOAD_MB, default 100 10 MB (Neon’s request limit)

Cloudflare

Settings are vars in wrangler.local.jsonc, which setup writes from the wrangler.jsonc template. npm run dev and npm run deploy use it when it exists. The hostname is bound as a custom domain, so its zone must be on the same Cloudflare account. ADMIN_TOKEN is a secret:

npx wrangler secret put ADMIN_TOKEN -c wrangler.local.jsonc
npm run deploy

Docker

Settings are environment variables, usually in .env:

Variable Default
ADMIN_TOKEN required Signs in to /admin and signs session, unlock and card cookies
SITE_NAME, OWNER_NAME, ACCENT_COLOR, CODE_THEME, HOME_URL Starting settings
STORAGE disk disk or s3
DATA_DIR /data Where disk storage keeps files
S3_ENDPOINT, S3_BUCKET, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY For s3: AWS S3, Backblaze B2, MinIO, or R2’s S3 API
CHROME_PATH /usr/bin/chromium Browser for preview cards
CARDS on off skips preview cards
MAX_UPLOAD_MB 100 Largest upload
TRUST_PROXY true Read X-Forwarded-* from your reverse proxy

Run it behind a reverse proxy with TLS. Rotating ADMIN_TOKEN signs everyone out.

Neon

Deploy on Neon walks through both ways to deploy. In short: neon.ts is the whole deployment: the drop function (built to dist/neon by npm run build:neon, with the static files beside it), a private drops bucket, and a cleanup trigger that POSTs to /__scheduled every hour. The function only runs cleanup when the request carries Neon’s X-Neon-Trigger-Invocation-Id header, which Neon strips from outside callers.

npm run deploy:neon reads .env: ADMIN_TOKEN, the optional SITE_NAME, OWNER_NAME, ACCENT_COLOR, CODE_THEME and HOME_URL, and DROP_DOMAIN to serve from your own hostname. The bucket’s AWS_* credentials are injected by Neon.

npm run test:neon runs the smoke tests against the Neon build with any S3 endpoint in AWS_ENDPOINT_URL_S3.

Security

  • Passwords are hashed with PBKDF2 and checked on the server. A locked drop never sends its bytes until it is unlocked.
  • Raw files are served with a sandboxing Content-Security-Policy, so an uploaded HTML or SVG file cannot run script on your domain.
  • / redirects away, nothing is listable without a token, random slugs are 10 characters, and pages send noindex. Link-preview bots are allowed in robots.txt; search crawlers are not.

Was this page helpful?