How to Use PrivateBin: The Beginner's Guide (First Paste, the Zero-Knowledge Rule, Burn-After-Read, and the Self-Host Lesson)
CodexFuse Team · 2026-11-01T12:58:00.928Z · 12 min read
Learning how to use PrivateBin starts with one idea that most pastebin tools never give you: the server never sees your paste. You type text into your browser, your browser encrypts it before anything leaves your computer, and the server stores only unreadable ciphertext. The decryption key travels inside your link, in the part of the URL that browsers never send to servers. This privatebin tutorial walks you through that zero knowledge design, your first paste on a public instance, the options that matter (expiration, passwords, burn-after-read), and the full self-hosted route on your own server. If you want a faster deployment lane, pair this walkthrough with the Coolify beginner guide — but the classic VPS path below works with nothing but PHP and a web server.
What Is PrivateBin? The Zero Knowledge Pastebin, Defined
PrivateBin is a free, open-source, zero-knowledge pastebin: a minimalist website where you paste text, documents, or code and get a shareable link, with AES-256-GCM encryption happening in your browser so the server operator cannot read what you shared. The current release is 2.1.0, published on 18 October 2026, and the project on GitHub counts roughly 8,721 stars and 1,056 forks. It is released under the zlib/libpng license, requires PHP 7.4 or newer, and by default stores pastes as files in a data/ directory — with MySQL, PostgreSQL, SQLite, S3, and Google Cloud Storage backends available.
The term "zero knowledge" is the whole pitch, and it is precise. When you create a paste, PrivateBin encrypts the content in your browser with AES-256 in Galois Counter mode. The 256-bit key is generated locally and appended to your share link after a # fragment. Browsers never send URL fragments to servers — not in requests, not in logs — so the server stores only ciphertext and mathematically cannot decrypt it. One load-bearing caveat, said once: the operator cannot read your pastes, but they still see connection metadata such as IP addresses and timestamps. Zero knowledge about content, not about visits.
Since version 2.0, the project's own documentation calls them "documents" rather than "pastes," though the community still says pastes. A naming footnote worth knowing: if you search for "how to use privatebin" you will also meet gearnode/privatebin, an unrelated third-party Go CLI client that talks to PrivateBin instances — it is a companion tool, not the PHP project this guide covers.
Your First Paste: Five Steps on a Public Instance
The fastest way to learn the product is the public reference instance at privatebin.info, which runs the current 2.1.0 release. No account, no signup — that is by design.
- Paste your text. Open privatebin.info, click into the editor, and paste or type your content. There are also "Markdown" and "Source Code" tabs if you want formatted or highlighted output.
- Set an expiration. The expiration dropdown controls how long the paste lives. Options run from minutes up to "forever" — pick the shortest life that fits the job. A shorter life is the easiest privacy habit you can build.
- Add a password (optional). The password field is a per-paste option: the recipient must enter the password to decrypt. Use it when the link might travel through channels you do not fully control, like chat history.
- Tick "Burn after reading" (optional). This is also per-paste: the first time anyone opens the link, the paste is deleted from the server immediately after being displayed. One view, then gone.
- Send. Click "Send." You receive a link shaped like
https://privatebin.info/?a1b2c3#key-here. The part after the#is the key — share the whole link, and whoever opens it decrypts locally in their own browser.
Steps 3 and 4 above are the privatebin password protect and privatebin burn after read options — both are per-paste settings you choose at creation time, and the recipient needs nothing but the link (plus the password, if you set one).
Expiration and Burn-After-Read: How Lifetimes Actually Work
Expiration in PrivateBin is not a polite suggestion — it is enforced deletion. Here is the exact lifecycle.
| What happens | The rule |
|---|---|
| A paste passes its expiry time and someone opens it | It is deleted immediately on access — the visitor sees nothing |
| A paste passes its expiry time and nobody opens it | It waits for the server's cleanup job: bin/administration --purge, which administrators run on a schedule (cron) |
| You choose "forever" (expiration 0 = never expire) | The paste lives until the operator deletes it or purges the data directory |
| Burn-after-read is ticked | The paste is deleted right after its first successful display, regardless of the expiration setting |
Instance owners configure the available lifetimes in the [expire] section of conf.php, and the pre-selected default comes from [expire_options]. On public instances you just pick from the dropdown; if you self-host, trimming the options down to short lifetimes is the single easiest policy decision you will make.
When Not to Use PrivateBin (Read This Once)
PrivateBin is the wrong tool in three situations. First, anything that needs collaboration: there are no accounts, no edit history, and no shared workspaces — a paste is a one-shot publication, not a document you co-edit. Second, anything legally sensitive where metadata matters: as noted above, the operator sees IPs and timestamps, and your recipient's network path is visible to whoever watches it. Third, pastes that must be auditable later: burn-after-read and expiration are designed to destroy evidence of the content, which is exactly wrong for contracts, compliance records, or anything your future self needs to prove existed.
Use PrivateBin for sharing a password over chat, sending a log snippet to support, handing a developer an API key, or publishing a code sample that should not live on a third-party server forever. For everything else, a tool with accounts and history is the honest choice.
PrivateBin vs Hastebin: Which Self Hosted Pastebin Should You Pick?
PrivateBin and Hastebin are the two names that come up whenever someone searches for a self hosted pastebin, so here is the draw-the-line comparison on this page — no rival article needed.
| Question | PrivateBin | Hastebin |
|---|---|---|
| Who can read your paste? | Nobody but key holders — AES-256-GCM encrypts in your browser; the server stores ciphertext only | The server operator — Hastebin stores plaintext on the server |
| Burn-after-read | Built in, per paste | Not built in (some forks add it) |
| Password protection | Built in, per paste | Not built in |
| Stack | PHP (7.4+), files or SQL/S3 backends | Node.js, Redis or filesystem |
| Best for | Secrets, passwords, anything you would not hand to a stranger | Quick public code snippets where privacy does not matter |
The rule of thumb: if the paste would embarrass you, cost you money, or lock you out of something if leaked, use PrivateBin. If it is a stack trace you want the world to see, either works. Microbin and Wastebin are smaller alternatives in the same family, but they inherit the same comparison — PrivateBin is the one with the zero-knowledge story.
Self-Hosting PrivateBin on a VPS: The PrivateBin Self Hosted Route
Self-hosting is where PrivateBin shines: the whole application is PHP with no database required, so a privatebin self hosted instance runs on the smallest server you own. If you do not have one yet, read what is VPS hosting first, then come back — the steps below assume a Debian or Ubuntu box with a web server.
The install is deliberately boring. You need PHP 7.4 or newer with the zlib extension (GD, OPcache, and PDO are optional, enabled per feature), plus nginx or Apache. Download the 2.1.0 release archive from GitHub, unpack it, and point your web server's document root at the public/ directory — not the project root. That last detail is the product's most important security property: the official installation guide explicitly says you can move the bin, cfg, data, lib, tpl, and vendor directories outside the document root, and the official container images ship exactly that way. The #1 self-host footgun, said once: never let the data/ directory be reachable from the web. Ciphertext on a public URL is still a leak of who pasted what and when.
Copy cfg/conf.sample.php to cfg/conf.php and edit the basics: your instance name, the expiration options you want to offer, and whether registration of pastes is open. Then make sure the web-server user can write to data/ and that no other system user can read cfg/conf.php or data/ — the official docs call this out directly. Set up the bin/administration --purge cron job so expired pastes are actually deleted, and you have a working private instance.
The Docker Lane: PrivateBin Docker in One Container
If you prefer containers, the project publishes official images on Docker Hub and GitHub Container Registry: privatebin/nginx-fpm-alpine (an all-in-one image with nginx and PHP-FPM on Alpine) and privatebin/unit (built on NGINX Unit). New to the tooling? The Docker beginner guide covers the concepts this section assumes.
The documented one-liner for the Alpine image:
docker run -d --restart="always" --read-only -p 8080:8080 -v $PWD/privatebin-data:/srv/data --tmpfs /tmp:nodev,noexec,mode=1777 --tmpfs /run:nodev,exec,mode=1777 privatebin/nginx-fpm-alpine
Two things to notice. First, your pastes persist in the mounted privatebin-data directory on the host — lose the volume and you lose the pastes. Second, the nginx inside the container serves plain HTTP on port 8080; HTTPS termination is your reverse proxy's job, which brings us to the next section. The --read-only flag plus the tmpfs mounts are straight from the official image documentation and are worth keeping: they shrink what a compromised container can do.
Putting Nginx and HTTPS in Front
PrivateBin links carry decryption keys in the URL fragment, so serving your instance over HTTPS is not optional — without it, the ciphertext and the key-adjacent metadata travel in the clear. The standard shape: nginx listens on 443 with a Let's Encrypt certificate and proxies to the container (or PHP-FPM) on localhost. The Nginx beginner guide walks the config pattern, and if you would rather have the proxy fetch and renew certificates itself, the Caddy beginner guide covers the automatic-HTTPS route.
The proxy config itself is minimal: forward / to the backend, pass the real client IP in X-Forwarded-For (PrivateBin uses it for its traffic-limiter), and set the usual security headers. After it is up, test with a real paste: create one with burn-after-read, open the link in a private window, and confirm the second open shows nothing. That five-second test proves the whole lifecycle — encryption, key-in-fragment, and server-side deletion — is working on your instance.
Pasting From Your Terminal: The CLI Lane
Two different command-line tools exist, and they do different jobs. The official repository ships a server-side administration script: bin/administration --purge deletes expired pastes and bin/administration --statistics reports on the data directory. You run it on the server, on a schedule, as the cleanup crew.
For creating pastes from the terminal, the community option is the third-party Go client gearnode/privatebin — the one whose docs show up in search results for this topic. It encrypts client-side, the same as the web UI:
cat deploy.log | privatebin create --expire 1day
It prints a shareable link; privatebin show <url> retrieves a paste. Its default instance is privatebin.net, but you can point it at your own server. Treat it as an optional companion: everything in this guide works from the browser alone.
Seven Beginner Mistakes That Break PrivateBin Setups
| Mistake | Why it hurts | The fix |
|---|---|---|
Serving the project root instead of public/ | Exposes cfg/ and data/ to the web | Point the document root at public/ only |
| Skipping HTTPS | Paste metadata and fragments travel readable on the network | Terminate TLS at the reverse proxy before going live |
Sharing the link without the #key part | The recipient gets an undecryptable page — the key never left your clipboard | Copy the full URL, fragment included; test in a private window |
| Using "forever" expiration for secrets | A secret outlives its usefulness and sits on disk indefinitely | Default to the shortest expiration; reserve "forever" for public notes |
| Forgetting the purge cron job | Expired pastes pile up in data/ forever | Schedule bin/administration --purge via cron |
| Mounting no volume in Docker | Container recreation wipes every paste | Always mount a host directory at /srv/data |
| Assuming zero knowledge means zero metadata | IPs and timestamps are still visible to the operator | Say it once, remember it always: content-private, not visit-private |
Sources
- PrivateBin releases — 2.1.0 released 18 Oct 2026, PHP 7.4 minimum, zlib extension required: github.com/PrivateBin/PrivateBin/releases
- PrivateBin repository — ~8,721 stars, ~1,056 forks, AES-256-GCM browser encryption, per-paste password/burn-after-read/discussion, storage backends (filesystem, MySQL, PostgreSQL, SQLite, S3, GCS): github.com/PrivateBin/PrivateBin
- Official installation guide — moving bin/cfg/data/lib/tpl/vendor outside the document root via
PATH, protecting cfg and data from other users: Installation.md - Configuration wiki —
[expire]/[expire_options]lifetimes, expired-paste deletion behavior: Configuration wiki - PrivateBin end-of-life dates — 2.1.0 latest, 2.0.x support ended 18 Oct 2026: endoflife.date/privatebin
- FreshPorts — PrivateBin license zlib/libpng: freshports.org/www/privatebin
- Official Docker image docs —
privatebin/nginx-fpm-alpineandprivatebin/unit, HTTP on 8080, run flags: hub.docker.com/r/privatebin/nginx-fpm-alpine - Public reference instance — privatebin.info, running 2.1.0: privatebin.info
- White Ravens blog — PrivateBin zero-knowledge explainer (AES-256-GCM, key in URL fragment): blog.whiteravens.net
- LowEndBox — self-hosted PrivateBin VPS arc (Debian 12, nginx + PHP-FPM, Let's Encrypt): lowendbox.com
- gearnode/privatebin Go CLI —
privatebin create/privatebin showcommand reference: deepwiki.com/gearnode/privatebin - EasyCode — PrivateBin on Docker guide: easycode.page
Frequently Asked Questions
Is PrivateBin really zero-knowledge?
Yes, for content. Your browser encrypts the paste with AES-256-GCM before upload, the key stays in the URL fragment that browsers never send to servers, and the server stores only ciphertext. The operator still sees metadata — IP addresses and timestamps — so it is content-private, not visit-private.
Can I self-host PrivateBin with Docker?
Yes. The official privatebin/nginx-fpm-alpine image bundles nginx and PHP-FPM; one docker run with a mounted data volume gets you a working instance on port 8080. Put a reverse proxy with HTTPS in front before sharing real secrets.
What happens when a PrivateBin paste expires?
If someone opens an expired paste, it is deleted immediately and they see nothing. Expired pastes nobody opens are removed by the server's scheduled bin/administration --purge job. Choosing "forever" (expiration 0) keeps a paste until the operator deletes it.
What is the difference between PrivateBin and Hastebin?
PrivateBin encrypts in your browser so the server operator cannot read your paste; Hastebin stores plaintext on the server. PrivateBin also ships per-paste passwords and burn-after-read. Use PrivateBin for secrets, Hastebin for public code snippets.
Does PrivateBin need a database?
No. The default storage is the filesystem — pastes live as files in the data/ directory. MySQL, PostgreSQL, SQLite, S3, and Google Cloud Storage backends are available if you outgrow files, but most private instances never need them.