Libre linking for poems and memes π Run your own instance for free on any domainπ
GetPost is a simple, secure imagebin and pastebin built on Cloudflare Workers. Share text, images, and files up to 10MB with no accounts, no tracking, and global distribution.
# Try it now
curl --data-binary @myfile.txt https://public.getpost.workers.dev
# Deploy your own in minutes
git clone https://github.com/getpost-loves-you/getpost
cp .staging .mydomain
<add API keys>
./deploy.sh mydomainFor Users:
- π Instant sharing - Text, markdown, images, most other filetypes
- π Clean URLs - Short, shareable links with delete keys
- β‘ Fast worldwide - Sub-100ms response times via Cloudflare edge
- π‘οΈ Privacy-focused - No tracking, no ads, no accounts required
For Self-Hosters:
- π° Free forever - Cloudflare's generous free tier (100k reads, 1k uploads daily)
- π§ Zero maintenance - No servers, no updates, no downtime
- π Global by default - Your content is distributed worldwide automatically
- π¨ Hackable - Minimal, suckless codebase that is easy to customize
Visit your GetPost instance and drag & drop files. Markdown is rendered automatically via marked.
# Basic upload
curl --data-binary @file.txt https://your-domain.com
# From clipboard (macOS)
pbpaste | curl --data-binary @- https://your-domain.com
# Custom expiration
curl -H "X-TTL: 3600" --data-binary @file.txt https://your-domain.comSave as /usr/local/bin/pastebin:
#!/bin/bash
curl --data-binary @${1:--} https://your-domain.comUsage: pastebin file.txt or echo "hello" | pastebin
GetPost runs on Cloudflare Workers - zero servers, global distribution, generous free tier (100k reads, 1k uploads daily).
git clone https://github.com/getpost-loves-you/getpost
cd getpost
# Follow SETUP.md for detailed instructions
./deploy.sh mydomainWhy Self-Host?
- π° Free forever - No hosting costs on Cloudflare's free tier
- π Your domain - Custom branding and control
- π§ Zero maintenance - No servers, no updates, no downtime
- π‘οΈ Privacy - Your data stays in your KV namespace
π Full Setup Guide β
- π Text & Markdown - Server-side rendering with clean typography
- πΌοΈ Images - PNG, JPEG, GIF with instant preview
- π Documents - PDFs, videos, any file type up to 10MB
- π Raw Access - Append
&rawfor direct file download - β° Configurable TTL - Default 1 year, customizable via X-TTL header
- ποΈ Delete Keys - Every upload gets a unique deletion URL
- π CORS Support - Add
?cors=1for cross-origin requests - π Debug Tools -
/headers,/echoendpoints for troubleshooting
Built on Cloudflare Workers - a globally distributed edge computing platform.
User β Cloudflare Edge β Worker β KV Storage
- Workers: JavaScript runtime at 200+ locations worldwide
- KV Storage: Eventually-consistent key-value store, AES-256 encrypted
- ULIDs: Lexicographically sortable identifiers for posts and delete keys
- Zero dependencies: Self-contained, no external services
From Cloudflare's documentation:
Workers KV supports exceptionally high read volumes with low-latency, making it possible to build highly dynamic APIs and websites which respond as quickly as a cached static file would.
Perfect for a pastebin! Popular content gets cached globally, while the free tier offers:
- 100,000 reads per day
- 1,000 writes per day
- Sub-100ms cold start times
- 128MB memory per request
GetPost prioritizes simplicity over complexity in its security approach:
What's Protected:
- π Access control - 80 bits of entropy in ULIDs (stronger than most passwords)
- π Data at rest - AES-256 encryption by Cloudflare
- π Data in transit - TLS encryption for all requests
- π« No tracking - No cookies, analytics, or third-party scripts
What's Not Protected:
- Content is theoretically accessible to Cloudflare employees, with some difficulty
- No client-side encryption (by design, for simplicity)
- Your computer.
Privacy Philosophy: We choose transparent simplicity over false security promises. For most use cases, ULID-based access control and Cloudflare's infrastructure security are sufficient.
It's free and easy to get started with your own GetPost instance, either on a domain you already own, or a free "*.workers.dev" subdomain.
Because I love you, I have included a set of credentials allowing anyone to deploy to "https://staging.getpost.workers.dev" - as well as a set of end-to-end tests, and lots of source code comments. Also spared interested parties from painful toolchain misadventures!
GetPost doesn't require the use of Cloudflare's Wrangler tool, the Node Package Manager, or a Rust buildchain. It does require curl, python3, and a Linux-like environment (termux or WSL should work).
To keep the main worker.js file manageable, a simple well-documented Python script - autoinsert.py - loads files from the deps folder into worker.js to make worker.packed.js.
The deploy.sh script calls autoinsert.py to assemble the packed worker, loads credentials from a file in the local directory, and uploads the worker.packed.js file to Cloudflare.
You can get started by cloning this repository, making a small edit to worker.js or one of the resources in deps - and running ./deploy.sh staging.
This loads the credentials from the .staging file, assembles your changes, and uploads the file.
Your script will then start running on "https://staging.getpost.workers.dev" - and you can verify it works as expected by running ./test.sh staging
This loads other values from the .staging file, makes a series of requests to the staging URL, and prints "ALL TESTS PASSED" if the responses to the inputs are all as expected.
Be excellent to one another, and follow the instructions in SETUP.md to create your own account with your own credentials, if you intend to do any real work - after all, other folks may also avail themselves of the staging deploy API key!
getpost/
βββ worker.js # Main Cloudflare Worker code
βββ autoinsert.py # Build script (embeds deps/ into worker)
βββ deploy.sh # Deployment automation
βββ test.sh # End-to-end testing
βββ SETUP.md # Detailed deployment guide
βββ deps/ # Static assets
β βββ getpost.css # Styling
β βββ getpost.html # Content template
β βββ upload.html # Upload page
β βββ marked.min.js # Markdown parser
βββ .staging # Shared staging credentials
# Test against staging (using shared credentials)
./test.sh staging
# Test your own deployment
./test.sh mydomain
# Generate new baseline hashes after changes
./generate_test_hashes.sh staging- Custom CSS themes - Edit
deps/getpost.css - File type support - Extend
generateHtmlBasedOnType() - Rate limiting - Add IP-based restrictions
- Analytics - Track usage stats (respect privacy!)
- Content filtering - Add moderation hooks
POST /post
Content-Type: application/octet-stream
X-TTL: 3600 # Optional: expiry in seconds
# Response includes share link and delete keyGET /post?key=ULID # Rendered HTML view
GET /post?key=ULID&raw # Original file
GET /post?key=ULID&cors=1 # With CORS headersGET /post?key=ULID&del=DELETE_KEYGET /headers # Request headers and metadata
GET /echo # Echo request bodyPhilosophy: CC0. No Rights Reserved. Fork it, hack it, improve it, deploy it everywhere.
- π Source Code
- π Setup Guide
- π Report Issues
- Test changes with
./test.sh staging - Update
RELEASE_NOTES.mdandREADME.md - Follow SemVer for version numbers
- Submit PRs with clear descriptions
GetPost revives the spirit of personal file servers from the pre-GitHub era, when sharing a file meant SCPing it to your homepage. We've made that experience:
- Globally distributed (via Cloudflare's edge network)
- Zero maintenance (no servers to patch)
- Free forever (generous cloud free tiers)
- Instantly deployable (minutes, not hours)
Posts use ULIDs instead of UUIDs:
- Lexicographically sortable (chronological ordering)
- 26 characters vs UUID's 36 (shorter URLs)
- Crockford base32 (avoids visual ambiguity: 0/O, 1/I/L)
GetPost examines file headers to determine MIME types:
- Magic bytes for binary formats (PNG, PDF, etc.)
- UTF-8 validation for text content
- Markdown rendering for text files
- Raw passthrough for unknown types
- Cold start: ~50ms (Cloudflare Workers)
- Warm requests: ~10ms globally
- KV read latency: ~10ms from cache, ~100ms from origin
- Global propagation: ~60 seconds for KV writes
"Because I love you, I included credentials for anyone to deploy to staging.getpost.workers.dev. Be excellent to one another!"