Self-Hosted Code Sharing With Hastebin: Private Pastebin Without the Ads

Tired of Pastebin being slow and ad-filled? Hastebin is 50 lines of code to run. Here's how to deploy it.

The Problem With Pastebin (And Why I Left)

Pastebin is slow. Pastebin is covered in ads. Pastebin’s syntax highlighting is… okay at best.

But the bigger thing? I don’t want my code sitting on someone else’s server.

Sometimes I’m debugging, and I want to share a config snippet or error log with someone. I use Pastebin, paste my thing, and oh look—my AWS keys are now on the internet.

(I do rotate them after. Sometimes.)

So I did what any reasonable person does: I built my own.

Enter Hastebin

Hastebin is a Pastebin clone by Jan Lelis. It’s:

  • Lightweight — ~50MB Docker image
  • Fast — Returns syntax-highlighted code in milliseconds
  • Simple — Plain HTML + some JS, no database required
  • Permanent — Files are stored on disk
  • Private — Only accessible from your network

I deployed it last month and immediately stopped using Pastebin.

Why Hastebin, Not Others?

There are other Pastebin clones: Etherpad, Tinybin, Snippetsbox, etc.

I picked Hastebin because:

  1. No database — Files are stored as flat files. No Postgres setup.
  2. Built-in expiry — You can set pastes to auto-delete (1 hour, 1 day, 1 week, never)
  3. Great syntax highlighting — Highlight.js + 200+ languages
  4. Minimal footprint — Runs on a $2 VPS without sweating

Etherpad is great but huge and overkill if you just want one-way code sharing.

Deploy Hastebin (5 Minutes)

Option 1: Docker Compose (Easiest)

# docker-compose.yml
version: '3'

services:
  hastebin:
    image: rlgod/hastebin:latest
    container_name: hastebin
    ports:
      - "7777:7777"
    volumes:
      - ./data:/app/data
    environment:
      - HOST=0.0.0.0
      - PORT=7777
    restart: unless-stopped
docker-compose up -d
# That's it. Visit http://localhost:7777

Option 2: Docker (No Compose)

docker run -d \
  --name hastebin \
  -p 7777:7777 \
  -v hastebin-data:/app/data \
  --restart unless-stopped \
  rlgod/hastebin:latest

Option 3: Reverse Proxy (Nginx)

If you want it behind a domain (e.g., paste.example.com):

server {
    listen 80;
    server_name paste.example.com;

    location / {
        proxy_pass http://localhost:7777;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Then add SSL with certbot:

certbot --nginx -d paste.example.com

Now you have https://paste.example.com.

Customizing Hastebin

Hastebin has a config.js in the container. You can override it:

// config.js (mount this inside the container)
{
  "host": "0.0.0.0",
  "port": 7777,
  "keyLength": 10,
  "maxLength": 400000,
  "staticMaxAge": 86400,
  "recentLength": 30,
  "storageType": "file",
  "rateLimits": {
    "categories": {
      "paste": {
        "totalRequests": 15,
        "every": 60000
      }
    },
    "default": {
      "totalRequests": 30,
      "every": 60000
    }
  },
  "logger": {
    "level": "verbose",
    "type": "Console"
  }
}

Key settings:

  • keyLength: Length of the paste ID (10 = 62^10 combinations, basically infinite)
  • maxLength: Max characters per paste (400KB is reasonable)
  • recentLength: Number of recent pastes shown on homepage
  • rateLimits: Prevent spam (15 pastes per minute, default)

Usage

Creating a Paste

  1. Visit https://paste.example.com
  2. Paste your code
  3. Click “Save”
  4. Share the link

You get a short URL like https://paste.example.com/abc123.

The person clicks it, they see your code with syntax highlighting.

Expiring Pastes

By default, pastes are permanent (stored on disk).

To make a paste expire:

  • Click the clock icon after saving
  • Choose 1 hour, 1 day, 1 week, or never

The cron job (/app/hastebin-cleanup.sh) runs daily and deletes expired pastes.

Privacy Settings

Hastebin has no authentication. Anyone with the URL can read it.

If you want privacy, add Basic Auth to your Nginx config:

location / {
    auth_basic "Hastebin";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    proxy_pass http://localhost:7777;
    # ...
}

Generate the .htpasswd file:

htpasswd -c /etc/nginx/.htpasswd username

Now users need a password.

My Workflow (How I Use It)

Scenario 1: Debugging With a Friend

Me: "Something's broken in my app logs. Check this:"
Me: [paste logs to hastebin]
Me: "https://paste.example.com/xyz"
Friend: [clicks link, sees logs with line numbers]
Friend: "Line 42. You're missing error handling."

Done in 30 seconds. No weird formatting, no ads, no tracking.

Scenario 2: Config Sharing

Me: "Deploy Nextcloud with this config:"
Me: [paste docker-compose.yml to hastebin]
Me: [send the link]
Colleague: [copies the YAML, runs `docker-compose up`]

Much better than emailing a file or Slack (which mangles formatting).

Scenario 3: Quick Code Review

Junior dev: "Can you check this function?"
Junior dev: [pastes code]
Me: [reviews on hastebin, gives feedback]
Junior dev: [opens their IDE, applies fixes]

Faster than GitHub PRs for tiny snippets.

Monitoring & Maintenance

Hastebin is rock-solid, but you should monitor it:

# Check disk usage (data accumulates)
du -sh /app/data

# Logs
docker logs hastebin --tail 50

# Restart if needed
docker restart hastebin

Cleanup: Every day, old pastes are deleted (if they’ve expired). You can also manually prune:

# Inside container
find /app/data -mtime +7 -delete  # Delete pastes older than 7 days

Limitations (Be Aware)

  1. No database = No search, no API for retrieving pastes
  2. No syntax highlighting customization = It uses Highlight.js, that’s it
  3. No user accounts = Everyone uploads as “anonymous”
  4. No edit history = Once you save, you can’t change it
  5. Flat files = Can get slow with millions of pastes

For a personal or small-team Hastebin, these don’t matter. If you need the above, you want a more complex tool (Etherpad, Gitea snippets, etc.).

My Hastebin Setup

I’m running it on a cheap VPS:

  • Domain: paste.example.com (reverse-proxied through Nginx)
  • Auth: Basic HTTP auth (username/password)
  • Expiry: Default expiry is disabled (pastes persist)
  • Cleanup: Cron job runs daily, removes 30+ day old pastes
  • Backups: Daily tar of the data directory, sent offsite

The whole setup takes about 5GB disk (I’ve got a few thousand pastes archived).

Why This Matters

The bigger point: You don’t need SaaS for everything.

Pastebin could be down. Pastebin could change pricing. Pastebin could get bought and enshittified.

Your self-hosted Hastebin? Always there. Always yours. Always fast.

This is the self-hosting philosophy in a nutshell.

Your Action Plan

  1. Deploy Hastebin (Docker Compose, 2 minutes)
  2. Expose it through a reverse proxy (5 minutes)
  3. Add authentication if you want privacy (optional)
  4. Replace Pastebin in your workflow
  5. Never deal with ads again

Running a Hastebin instance? Let me know what you use it for. Code snippets? Config sharing? Something weird I haven’t thought of?

Tested with Hastebin latest | Nginx 1.24 | March 2026

Stay in the loop 📬

Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.

Join 0 self-hosters. Free forever.