Deploy Rusty paste

Minimal Rust pastebin: one-shot, password, URL shortener, petname links.

Deploy Rusty paste

Just deployed

/data

Rustypaste Lite

A ~15 MB single-binary paste service written in Rust (Actix). Four paste kinds — plain file, one-shot, URL shortener, and password-protected — with petname links, auto-expiry, and no database. The whole thing is a filesystem volume. One container, one volume, Hobby plan.

Deploy to Railway

Deploy and Host

One click. Railway provisions a single container with the /data volume and wires the public URL. No database, no sidecars, nothing to configure unless you want to change the default expiry or lock down uploads.

  • Runtime — Rust, statically linked, scratch base. No Node, no Python, no JVM.
  • Memory — ~15 MB at rest. Fits on the Railway Hobby plan.
  • Port — 8000 (baked into the wrapper image).
  • Persistence — plain filesystem on the /data volume. Pastes survive restarts and redeploys; no database to migrate.
  • Public URL — auto-generated by Railway; uploads return a full link to YOUR-DOMAIN.

Why Deploy

  • Sticky by design. Once GPU logs, bounty notes, and incident traces live in one place with memorable petname links, a second paste tool never gets installed.
  • Four paste kinds, one box. Plain file, one-shot (burns after the first read), URL shortener (302 redirect), and password-protected (Argon2id) — all from the same single binary.
  • Memorable links. Two-word petname URLs like capital-mosquito.txt — human-shareable, no UUID soup.
  • Zero database. Persistence is a filesystem volume. There is nothing to back up, migrate, or corrupt.
  • Blazingly small. One ~15 MB static ELF. Deploys in seconds; restarts are instant.
  • API-first. Every feature is reachable with plain curl — no browser required. Scripts and CI can drop long outputs and share the returned URL.

Common Use Cases

  • Log capture & share — pipe kubectl logs, CI output, or a GPU-deal trace into a paste and paste the petname URL next to the incident.
  • One-shot handoff — share a secret to exactly one person; the link burns the moment they fetch it.
  • Password-protected notes — the server generates a strong password and returns it to you in the upload response; the recipient needs it (via Authorization) to read the file.
  • Lightweight URL shortener — store a target URL and get a short petname link that 302-redirects to it.
  • Expiring drops — per-upload expire header or a global default so logs and keys don't linger.
  • Agent / bot drop — a service (or a human) shares long tracebacks to another endpoint without a UI.

Deployment Dependencies

No external database, cache, or queue:

  • Railway Hobby or above — 512 MB RAM is plenty; the binary uses ~15 MB at rest.
  • /data volume — where all pastes live; the template attaches it automatically. Without it, pastes vanish on container restart.
  • No Postgres, no Redis, no object store — everything is a plain file on the volume.

Dependencies for Rustypaste Lite

  • Railway Hobby or above — 512 MB RAM is plenty; the binary uses ~15 MB at rest.
  • /data volume — required for persistence. The template attaches it automatically.
  • No external database, cache, or queue — the filesystem on the volume is the storage.

Architecture

One service, one container, one volume:

PieceValue
Containerorhunp/rustypaste:0.18.1 (scratch base) + root wrapper in this repo
Port8000 (baked into the wrapper; Railway reverse-proxy + external healthcheck target /)
Volume/data — mounted by Railway; plain-file pastes persist here
Lock-downoptional AUTH_TOKEN (gates upload) + DELETE_TOKEN (enables per-file delete)
Domainauto-generated by Railway; exposed at 8000

The wrapper runs as uid 0 because Railway mounts persistent volumes as root-owned; the scratch base ships as a non-root user and EACCES-looped on its first write in testing. The scratch image also has no shell, so the healthcheck is Railway's external probe of / (there is no in-container HEALTHCHECK to write). The wrapper pins the config file at /app/config.toml; rustypaste exits at boot without a config, and upload_path is set to /data so every paste lands on the volume.

Features

  • Four paste kinds — plain file, one-shot, URL shortener, password-protected — from one binary.
  • One-shot (burn after reading) — the link returns the file once, then 404s.
  • Password-protected — Argon2id; the server generates the password and returns it in the upload response; read back with Authorization: Bearer and that password.
  • URL shortener — returns a 302 redirect to the stored target URL.
  • Petname links — capital-mosquito.txt, not a UUID.
  • Expiry — per-upload expire header or a global default; a janitor sweep removes expired pastes.
  • Upload lock-down — optional AUTH_TOKEN gates new uploads without hiding existing pastes.
  • Duplicate detection — identical content re-uploads return the existing link instead of a copy.
  • MIME handling — serves each file with a sensible content type from an override table.

About Hosting

Rustypaste Lite is a single container. Railway's reverse proxy terminates TLS at the edge and forwards plain HTTP to the container on port 8000; the external healthcheck targets /. The root wrapper exists solely to make the Railway volume mount writable by the rustypaste process — the binary itself is unchanged from the upstream orhunp/rustypaste:0.18.1 image. Nothing else to host.

Configuration

VariableDefaultDescription
RUST_LOGinfoLogging verbosity: error, warn, info, debug, trace.
PASTE__DEFAULT_EXPIRY1hDefault TTL for each paste when a client sends no expire header. Humantime format (5m, 1h, 1d, 1M). Set to 0 for no default expiry.
AUTH_TOKENblankWhen set, new uploads require Authorization: Bearer with this token (401 without). Reading existing pastes stays public. Blank = open public paste.
DELETE_TOKENblankWhen set, enables DELETE /{id} for holders of the token. When blank, the delete endpoint is disabled (404) — the safest public posture.

How to Use

All templates target YOUR-DOMAIN (your Railway public domain).

Plain file paste (petname link back)

curl -F "file=@vast-4090-deal.txt" https://YOUR-DOMAIN/

-> https://YOUR-DOMAIN/capital-mosquito.txt

One-shot paste (burns after the first read)

curl -F "oneshot=@bounty-0xe538.txt" https://YOUR-DOMAIN/

URL shortener (a file whose content is the destination URL) -> 302 redirect

printf 'https://internal.example/trace-12' > target.txt curl -F "url=@target.txt" https://YOUR-DOMAIN/

Password-protected: the response body is two lines — the link, then "Password: ***

curl -F "protected=@secret.txt" https://YOUR-DOMAIN/

Read it back with the generated password (Bearer scheme):

curl -H "Authorization: Bearer GENERATED_PASSWORD" "https://YOUR-DOMAIN/capital-mosquito.txt"

Per-upload expiry (humantime)

curl -F "file=@notes.txt" -H "expire: 24h" https://YOUR-DOMAIN/

Endpoints

MethodPathDescription
GET/Landing page.
POST/Upload. Multipart part name selects the kind: file, oneshot, url, protected.
GET/{name}Fetch a paste. One-shot pastes burn after this read; protected pastes need Authorization: Bearer with the generated password.
HEAD/{name}Metadata only.
DELETE/{name}Delete a paste. Requires a configured DELETE_TOKEN.

Troubleshooting

  • First upload returns EACCES or 500 — the /data volume must be attached to the service and the container must run as uid 0 (both are set by this template). A non-root process cannot write Railway's root-owned volume.
  • Paste gone after a redeploy — upload_path must be the volume (/data, set in config.toml) and the volume must be attached; otherwise pastes land in the container's writable layer and are wiped on restart.
  • 401 on upload — AUTH_TOKEN is set; send it as Authorization: Bearer TOKEN. Existing pastes are unaffected.
  • DELETE returns 404 — DELETE_TOKEN is not set; the delete endpoint is disabled by design until you set one.
  • Protected paste can't be read — send the exact password the upload response returned as Authorization: Bearer GENERATED-PASSWORD; a wrong or missing token returns the same 404 as a missing file (by design, to prevent enumeration).
  • Paste too large — the wrapper caps uploads at 10 MB (SERVER__MAX_CONTENT_LENGTH in config.toml); raise it and redeploy.

License

Upstream rustypaste is MIT-licensed. This template's wrapper Dockerfile and config are provided as-is.


Template Content

More templates in this category

View Template
Garage S3 Storage
Ultra-light S3 server: fast, open-source, plug-and-play.

PROJETOS
8
View Template
Redis
Self Host Latest Redis with Railway

8
View Template
EasyImg
Simple self-hostable Nuxt.js personal image hosting system.

Muhammad Bilal
0