Blossom server
Blossom is where the pictures go. A server stores blobs and serves them back by their SHA-256 hash, with Nostr keys as the only identity — the cheapest useful thing to run on this list, and the one shortest of operators.
What it holds
Section titled “What it holds”Content, addressed by its own hash. GET /<sha256> returns the bytes; PUT /upload takes them, authorized by a signed kind-24242 event. Because the
address is the hash, the same file uploaded twice is one blob, and a blob
mirrored to a second server keeps the same URL path — which is why Armada
uploads to several and treats none of them as the home.
What a server holding Armada media can see is less than you would think. In a
Concord community, attachments are encrypted client-side before upload and
arrive as opaque application/octet-stream — community icons and banners
included. The server stores ciphertext and a hash.
Run it
Section titled “Run it”blossom-server is the reference implementation: Deno 2, Hono, SQLite or libSQL, with local-filesystem or S3-compatible storage.
git clone https://github.com/hzrd149/blossom-servercd blossom-servercp config.example.yml config.ymldocker compose up --buildIt listens on 3000. Set publicDomain to the hostname it is reachable at — a
bare hostname, no scheme — because that is what goes into the url of every
blob descriptor it hands back, and what BUD-11 checks a server tag against.
TLS goes on your proxy, as usual.
| Key | Why you touch it |
|---|---|
publicDomain |
The hostname in returned blob URLs. Wrong here means clients fetch from the wrong origin. |
storage.backend |
local or s3. S3 can redirect GET to a publicURL instead of proxying bytes. |
storage.rules |
Retention and an upload allowlist, matched by MIME glob. |
upload.maxSize |
2 GB by default, which is more generosity than most operators mean. |
upload.requireAuth |
On by default. Leave it on unless you enjoy hosting other people’s warez. |
list.enabled |
GET /list/:pubkey, off by default. |
media.enabled |
BUD-05 resize and transcode. Needs ffmpeg. |
Point Armada at it
Section titled “Point Armada at it”Settings → Media servers takes a list. A user’s own servers are published as a kind-10063 list, so other Nostr clients pick them up too, and a toggle decides whether uploads also go to the app’s defaults.
To ship a default with a client you host, build with
VITE_APP_BLOSSOM_SERVERS — see
the web app’s configuration. Trailing
slashes are fine; several servers are better than one, because Armada mirrors
uploads across them and a blob that exists in two places survives one of them
disappearing.
The easy one to volunteer for
Section titled “The easy one to volunteer for”A relay is a commitment. A Blossom server is a disk, a proxy and a retention rule — and it serves every Nostr app, not just Armada.
$ hold some bytes