Skip to content

Releases: elroykanye/barme

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 16:19

barme 1.1.0

A deployment can now tell the console where the API and the CDN really are.
Additive over 1.0: new optional settings, no change to the on-disk format and no
change to any existing behaviour.

In this release

  • console_api_url / console_cdn_url (#11). The console worked out its API
    base from the address bar plus a fixed port. That's right when it's reached
    directly and wrong the moment anything is put in front of it: served from
    https://store.example.com it called http://store.example.com:7373 — a port
    a reverse proxy doesn't publish, over plain HTTP from an HTTPS page, which
    browsers block as mixed content even when the port is open. Sign-in then never
    completed, and because the blocked request breaks the padlock it read as a TLS
    fault, sending you to inspect a certificate that was perfectly fine.

    Nothing outside the server could fix it: VITE_BARME_API is a Vite
    compile-time constant and the console is baked into the binary, so changing it
    meant rebuilding the image; cors_origins covers only the CORS half; and
    barmed knew its bind addresses but had no notion of a public URL. Now it does.
    Set console_api_url and console_cdn_url in barme.toml (or
    BARME_CONSOLE_API_URL / BARME_CONSOLE_CDN_URL) and they're injected into
    index.html as it is served — at serve time, not build time, which is the
    whole point: a deployment sets them without rebuilding an image. The console
    prefers them over what it would otherwise derive.

    The values land inside a script tag, so they're escaped rather than trusted,
    with a test that a value can't close the tag it sits in.

Compatibility

Drop-in over 1.0.0. Leave the new settings unset and not a byte of the served
page changes — the console behaves exactly as before, which is what you want on
localhost. Same on-disk format, same stable API (see docs/STABILITY.md).

Upgrading behind a proxy

If you publish the console through a reverse proxy, set the two URLs and route
those paths to the native (7373) and CDN (7375) listeners:

console_api_url = "https://store.example.com/api"
console_cdn_url = "https://store.example.com/cdn"

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:1.1.0

The road here

  • 0.4.x — durability (fsync, crash recovery) and concurrency/GC hardening
  • 0.5.x — security (encrypted secrets, no default login, presign, CORS)
  • 0.6.0 — S3 multipart upload
  • 0.7.0 — on-disk format version + API freeze
  • 0.8.0 — S3 bucket operations, Helm chart
  • 0.9.0 — operability (backup/restore, readiness, metrics, name fuzzing)
  • 1.0.0 — frozen format and API, trustworthy with data, operable
  • 1.1.0 — the console reachable from behind a reverse proxy

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 10:02

barme 1.0.0

barme is 1.0. It makes three promises and keeps them:

  1. The on-disk format and API are frozen. Anything written to a 1.x server
    reads on every later 1.x. Format changes ride a version stamp and a migration,
    never a silent break.
  2. You can trust it with data. An acknowledged write survives a hard kill
    (fsync-durable, recovers on restart); concurrent writes and GC are safe under
    load; secrets are encrypted at rest; there's no standing default credential.
  3. It's operable. Liveness + readiness probes, Prometheus /metrics, a
    documented and tested backup/restore story, and a Helm chart.

Everything is proven by harnesses that run in CI territory, not just asserted:
crash/kill durability, GC-under-load, security posture, multipart abuse, and a
copied-data-dir restore.

In this release

Two delivery-correctness fixes closed before cutting 1.0:

  • /cdn/{hash} erasure caveat, documented (#6). The immutable, cache-forever
    hash URL can't be revoked once bytes are in a cache, so deleting at the origin
    can't pull them back. This is now written down clearly — /cdn is for public,
    non-erasable content; serve erasable or personal data over the short-lived
    /s/{pot}/{key} share instead. Documented in USAGE, STABILITY, and the code.
  • Object hash surfaced on every write path (#7). A new X-Barme-Object-Id
    response header carries the object's content id on single PUT, multipart
    complete, and HEAD — the reliable handle for a /cdn link, since an S3
    multipart ETag is a digest of part digests, not the object hash.

The road here

  • 0.4.x — durability (fsync, crash recovery) and concurrency/GC hardening
  • 0.5.x — security (encrypted secrets, no default login, presign, CORS)
  • 0.6.0 — S3 multipart upload
  • 0.7.0 — on-disk format version + API freeze
  • 0.8.0 — S3 bucket operations, Helm chart
  • 0.9.0 — operability (backup/restore, readiness, metrics, name fuzzing)
  • 1.0.0 — the delivery caveats above, and meaning the three promises

Compatibility

Drop-in over 0.9.0. This is the compatibility baseline: 1.x won't break 1.0 data
or the stable API (see docs/STABILITY.md).

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:1.0.0

Scope and what's next

1.0 is a single node you'd trust. Not in 1.0, by design: horizontal
distribution (the v2 headline — content-addressing makes replication cheap to add
later), encryption of object contents, and the experimental surfaces (semantic
search, sync, webhooks, image-codec transcoding) that stay marked as such.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 09:35

barme 0.9.0

The operability pass: barme is now something you can watch, probe, and back up
with confidence — the last of the three v1 promises ("run it, watch it, back it
up, recover it"). The remaining gaps before 1.0 are closed.

What changed

  • Backup and restore, documented and proven. The data directory is a
    self-contained, coherent backup target; docs/USAGE.md covers how to snapshot
    it, where the master key must live, and how to restore. A test copies a
    populated data dir elsewhere, reopens it, and confirms every object reads back
    byte-for-byte with history and integrity intact.
  • Readiness endpoint. GET /ready returns 503 when the store can't be read,
    distinct from GET /health (liveness). The Helm chart's readiness probe now
    points at it.
  • Richer metrics. /metrics adds GC counters — sweeps, chunks condemned,
    chunks erased, and reachable chunks from the last sweep — plus logical bytes
    alongside physical, so dedup savings and GC activity are visible to Prometheus.
  • Server-side verify in the crash harness. After every crash, the harness now
    cross-checks each acknowledged object against the server's own POST /verify,
    so recovery (download + re-hash) and the store's integrity check must agree.
  • Fuzzed name handling. A property test throws arbitrary unicode, slashes, and
    lengths straddling the 255-byte filename bound at put/get: they either
    round-trip or reject cleanly, never panic.
  • Structured request logs. Requests carry method/uri/status/latency
    through the HTTP trace layer, kept at debug so health probes don't spam the log;
    enable with RUST_LOG=…,tower_http::trace=debug.

Compatibility

Drop-in over 0.8.0. New endpoint (/ready) and metrics only; on-disk format and
the stable API are unchanged. Helm chart bumped to 0.2.0 / appVersion 0.9.0.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:0.9.0

Known limits

  • Alpha, but close: with this pass the v1 blocks (durability, security, format +
    API freeze, ops) are all done. A 1.0 is a decision away.
  • GET /{pot} (S3 ListObjects) is still not implemented; use native
    /pots/{pot}/objects.
  • Object contents aren't encrypted (secrets at rest are).
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 09:10

barme 0.8.0

Bucket-level S3 operations and a Helm chart — barme is now something you can
point an S3 client's full preflight at, and deploy to Kubernetes in one command.

What changed

  • S3 bucket operations. The S3 door gained the verbs it was missing:

    • PUT /{pot} — CreateBucket (idempotent; a repeat is 200)
    • HEAD /{pot} — HeadBucket (200 if it exists, 404 otherwise)
    • DELETE /{pot} — DeleteBucket (409 if the pot still holds objects, else 204)
    • GET / — ListBuckets (XML list of every pot)

    Pots stay implicit for writes — a first PUT to an unknown pot still lands with
    the default policy — but these give a pot an explicit identity when a client
    provisions or lists one. A pot exists if it has a config or holds objects.
    DeleteBucket refuses a non-empty pot and does the empty-check and delete
    atomically (under the commit locks), so a write racing the delete can't have
    its just-acknowledged object silently wiped.

  • Helm chart (charts/barme). helm install barme ./charts/barme runs a
    single-node store on Kubernetes: Deployment (one replica, Recreate, since the
    data volume is ReadWriteOnce), a PVC for /data, a Secret holding the owner
    credential and master key, a Service for all four doors, and an optional
    (SigV4-safe, no path-rewrite) ingress. Blank credentials are generated on first
    install and preserved across upgrades. Argo CD / helm template users: pin
    auth.masterKey (or use auth.existingSecret) — see the chart README, a
    regenerated master key makes stored secrets unrecoverable.

Compatibility

Drop-in over 0.7.0. New endpoints only; the 0.7.0 on-disk format and stable API
are unchanged. docs/STABILITY.md lists the bucket verbs under the (S3-tracks-AWS)
stable surface.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:0.8.0

Known limits

  • Alpha. Formats may still shift before 1.0 — don't store anything you can't lose.
  • GET /{pot} (S3 ListObjects) is not implemented yet; use the native
    /pots/{pot}/objects to list.
  • The master key protects secrets at rest; object contents aren't encrypted.
  • Doors bind 0.0.0.0; reach a local instance via 127.0.0.1 (IPv4).
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 08:19

barme 0.7.0

Format and API freeze — the groundwork that lets barme evolve without orphaning
data or breaking clients, and the last big block before a v1 that means something.

What changed

  • On-disk format is versioned. A format.json at the data root stamps the
    layout version. On open, a directory written by a newer barme is refused
    (rather than risk misreading a layout it doesn't know), an older one runs its
    migration and rewrites the stamp (the hook is in place; no steps needed yet),
    and a pre-0.7 directory is adopted as v1 with its data intact. The resolved
    version is logged at startup.
  • Manifests enforce their version. Every object already carried a
    manifest_version; reads now refuse a manifest newer than this build
    understands, per object, before trusting its fields.
  • The v1 manifest schema is pinned. A test hashes a fully-fixed manifest and
    asserts its content address, so any silent change to the schema fails CI and
    forces a conscious version bump.
  • The API surface is frozen and documented. docs/STABILITY.md states the
    compatibility promise and lists the stable surface (objects & versions, pots,
    keys, the S3 and CDN doors, presign, ops) versus the experimental surface
    (semantic search, sync, webhooks, image codecs), which is now marked as such in
    the live /docs.

Compatibility

Drop-in. An existing data directory is stamped format v1 on first open under
0.7.0 and keeps working unchanged. From here on, within a major version, data and
the stable API don't break — see docs/STABILITY.md.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:0.7.0

Known limits

  • Alpha. The freeze is the intended contract and is largely in force, but formats
    may still shift before 1.0 — don't store anything you can't lose yet.
  • The master key protects secrets at rest; object contents aren't encrypted.
  • Doors bind 0.0.0.0; reach a local instance via 127.0.0.1 (IPv4), not
    localhost. Put barme behind a firewall or reverse proxy.
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 23:25
2a7a7cb

barme 0.5.1

Finishes the security block: the CORS config knob now works, and expiring share
links are verified end to end.

What changed

  • cors_origins is now enforced. It was a dead config field — both the API
    and CDN doors hardcoded permissive CORS, so any website could script the API
    from a visitor's browser regardless of config. Now ["*"] (the default) stays
    permissive for local use, but a specific list restricts
    Access-Control-Allow-Origin to exactly those origins. Set your console/app
    origins in production.
  • Presigned share links, verified. The CDN share door (/s/{pot}/{key})
    checks the HMAC signature and the expiry, serving a private object only for a
    valid, unexpired link. Now covered by tests: a valid link serves; an expired
    one, a tampered signature, and a signature minted for a different key are each
    refused with 403.

With these, the v1 security block is complete: no default login, secrets
encrypted at rest, constant-time auth compare, verified share links, and a real
CORS boundary.

Upgrading

Drop-in. If you relied on the API being reachable from any browser origin, that
still works by default (cors_origins = ["*"]); set an explicit list to lock it
down.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:0.5.1

Known limits

  • Alpha. Formats and on-disk layout may still change before v1.
  • The master key protects secrets at rest; it does not encrypt object contents.
  • Doors bind 0.0.0.0 by default — put barme behind a firewall or reverse proxy;
    reach a local instance via 127.0.0.1 (IPv4), not localhost.
  • A pot name plus key must encode to under 255 bytes (about 120 key bytes for a
    short pot).
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 19 Jul 11:40

barme 0.5.1

Finishes the security block: the CORS config knob now works, and expiring share
links are verified end to end.

What changed

  • cors_origins is now enforced. It was a dead config field — both the API
    and CDN doors hardcoded permissive CORS, so any website could script the API
    from a visitor's browser regardless of config. Now ["*"] (the default) stays
    permissive for local use, but a specific list restricts
    Access-Control-Allow-Origin to exactly those origins. Set your console/app
    origins in production.
  • Presigned share links, verified. The CDN share door (/s/{pot}/{key})
    checks the HMAC signature and the expiry, serving a private object only for a
    valid, unexpired link. Now covered by tests: a valid link serves; an expired
    one, a tampered signature, and a signature minted for a different key are each
    refused with 403.

With these, the v1 security block is complete: no default login, secrets
encrypted at rest, constant-time auth compare, verified share links, and a real
CORS boundary.

Upgrading

Drop-in. If you relied on the API being reachable from any browser origin, that
still works by default (cors_origins = ["*"]); set an explicit list to lock it
down.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -v barme:/data elroykanye/barme:0.5.1

Known limits

  • Alpha. Formats and on-disk layout may still change before v1.
  • The master key protects secrets at rest; it does not encrypt object contents.
  • Doors bind 0.0.0.0 by default — put barme behind a firewall or reverse proxy;
    reach a local instance via 127.0.0.1 (IPv4), not localhost.
  • A pot name plus key must encode to under 255 bytes (about 120 key bytes for a
    short pot).
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 11:20

barme 0.5.0

Security. barme no longer ships with a working default login, and access-key
secrets are encrypted on disk instead of sitting in plaintext. This closes the
"don't expose it yet" caveat that stood since the first release.

What changed

  • No more default barme/barme. The built-in credential is gone. On a fresh
    store with no credential configured, the daemon mints a random owner and prints
    it once at startup — save it, it isn't shown again. Set your own with
    BARME_ACCESS_KEY / BARME_SECRET_KEY (or [credentials] in barme.toml) and
    that's used instead. An exposed barme is no longer a known-password login.
  • Secrets encrypted at rest. Access-key secrets are stored AES-256-GCM
    encrypted, not as plaintext JSON. Hashing isn't an option here — the S3 door
    verifies AWS SigV4, a symmetric HMAC, so the server must recover the raw secret
    to check a signature (the same reason AWS and MinIO keep recoverable secrets).
    Encryption keeps the key store free of plaintext while preserving S3
    compatibility: the secret is decrypted into memory only to verify a request.
  • Master key. The encryption key is resolved from BARME_MASTER_KEY (64 hex
    chars), else a master.key file in the data dir (created 0600 on first boot),
    else freshly generated and announced. For real deployments set
    BARME_MASTER_KEY in the environment — keeping the key out of the data dir
    protects a stolen backup too. Back the key up: encrypted secrets can't be
    recovered without it.
  • Legacy plaintext key stores migrate automatically. An existing store opened
    with a master key re-encrypts any plaintext secret records in place on startup.
  • Constant-time secret comparison on the native door's Basic auth, closing a
    timing side channel where a == leaked how many leading bytes of a guess were
    right.

Verified

  • SigV4 still round-trips end to end against a secret that never touches disk in
    plaintext — encryption didn't break S3 compatibility.
  • Durability and concurrency unaffected: the crash, abuse, and GC-under-load
    harnesses all pass on the new binary (every acknowledged object survives every
    crash; ~180 objects intact under grace=0 GC).
  • New tests cover encrypt/decrypt, wrong-key and tampered-ciphertext rejection,
    no-plaintext-on-disk, and legacy migration.

Upgrading

Mostly drop-in, with one thing to know:

  • A master.key is created in your data dir on first boot (or set
    BARME_MASTER_KEY yourself beforehand). Back it up. If you already had access
    keys, their secrets are migrated to encrypted form on this first start.
  • If you relied on the barme/barme default, set BARME_ACCESS_KEY /
    BARME_SECRET_KEY explicitly, or grab the auto-generated credential from the
    startup output.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 \
  -e BARME_MASTER_KEY=$(openssl rand -hex 32) \
  -e BARME_ACCESS_KEY=you -e BARME_SECRET_KEY=change-me \
  -v barme:/data elroykanye/barme:0.5.0

(Or run with no credential set and read the generated one from the logs.)

Known limits

  • Alpha. Formats and on-disk layout may still change before v1.
  • The master key protects secrets at rest; it does not encrypt object contents.
  • A pot name plus key must encode to under 255 bytes (about 120 key bytes for a
    short pot).
  • barmed binds IPv4 (0.0.0.0); on a dual-stack host reach it via 127.0.0.1
    rather than localhost.
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.4.2

Choose a tag to compare

@github-actions github-actions released this 17 Jul 23:06

barme 0.4.2

More hardening from the same stress campaign that produced 0.4.1. Three
resilience and concurrency fixes, each with a regression test.

Fixes

  • A corrupt condemned-set file no longer wedges GC. The .condemned file
    (chunk -> when-condemned) was deserialized with the error propagated, so a
    single bad byte in it would fail every future sweep — GC would stop forever and
    the disk would fill without bound. It now heals to empty: the set is disposable
    derived state (mark re-derives reachability every pass; the stamps only gate the
    grace window), so the worst case is a one-grace-period delay in reclaiming
    chunks. This matches how the rest of the collector re-derives its own truth.
  • Concurrent delete and put on one key can't lose the delete. delete now
    takes the same per-key commit lock that writes do. Without it a delete could
    interleave with a put's read-modify-write and be silently undone (the put reads
    the history, the delete removes the file, the put rewrites it and resurrects the
    key). Serializing makes it clean last-writer-wins.
  • A corrupt pointer line no longer orphans the whole key. The pointer file is
    the one mutable, non-content-addressed piece of state, so it's the one place a
    disk bit-flip isn't caught by an address check. A single unparseable line used
    to fail the entire read, taking the key's intact versions and rollback down with
    it. Corrupt lines are now skipped, so the surviving versions stay readable. (A
    corrupt current line resolves to the previous version rather than erroring —
    availability over a hard failure, consistent with the rest of the store.)

Under the campaign, holding up

  • A version-explosion probe (5000 writes to one key) showed flat ~per-write
    cost, no O(n²) cliff
    — the pointer rewrite is dominated by the per-write fsync,
    not by history length. See known limits for the one caveat at extreme counts.
  • New adversarial tests: racing put/delete on one key never corrupts state;
    corrupt condemned set and corrupt pointer line both recover.

Upgrading

Drop-in. On-disk format unchanged; a 0.4.x (or 0.3.x) data dir opens as-is.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 -v barme:/data elroykanye/barme:0.4.2

Known limits

  • Alpha. Formats and on-disk layout may still change before v1.
  • Secret keys are still stored in the clear and the default barme/barme login
    still works out of the box — both land in the next release. Don't expose it yet.
  • A single key's version history has no cap by default (set max_versions per pot
    to bound it). The pointer file grows linearly with versions and is rewritten per
    write, so a key written millions of times becomes a large, slow file. A default
    cap is planned.
  • A pot name plus key must encode to under 255 bytes (about 120 key bytes for a
    short pot).
  • barmed binds IPv4 (0.0.0.0); on a dual-stack host reach it via 127.0.0.1
    rather than localhost.
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 17 Jul 22:43

barme 0.4.1

Correctness under concurrency and garbage collection, found by an aggressive
stress campaign against 0.4.0. Three real defects fixed, all with regression
tests and adversarial harnesses.

Fixes

  • Concurrent writes to one key no longer lose versions. The pointer file is
    read-modify-write, and it had no serialization: 24 threads writing the same key
    landed 1 version in history, not 24 — 23 acknowledged writes silently
    dropped. Writes to a key now take a per-key commit lock (sharded, so different
    keys still run fully parallel and chunking stays off the lock). All 24 versions
    are now kept. This directly backs the store's "every write keeps the previous
    version" promise.
  • GC can no longer erase an in-flight upload's chunks. A streaming upload
    writes all its chunks before committing its pointer, so those chunks are
    unreferenced for the whole upload. GC's own module doc promised a guard against
    reaping young chunks, but the guard wasn't implemented — with a tight grace
    window a sweep could condemn and erase a live upload's chunks, then the client
    got a success for an object missing its bytes. Uploads now pin each chunk
    the instant it's stored and unpin once the pointer commits; GC treats pinned
    chunks as reachable, so a sweep can't touch them no matter how aggressive the
    grace window. A crash still drops the pins, so a crashed upload's orphans are
    collected normally.
  • Malformed pot names return 400, not 500. A pot name containing a slash or
    .. (e.g. /objects/..%2F..%2Fescape/k) is rejected safely by the store, but
    the door surfaced it as a 500. It's a client error and now answers 400 on both
    the native and S3 doors. (The store already contained the input — nothing
    escaped; this is about the right status code.)
  • barmed reports the right version. The daemon crate pinned its own
    0.3.0 instead of inheriting the workspace version, so the 0.4.0 binary
    reported 0.3.0. It now tracks the release version.

Hardening (tests + harnesses)

  • scripts/crash-test.sh gained a hot-GC mode (GC_GRACE=): kill -9 mid-write
    while GC actively sweeps and erases. Verified: 8 crash cycles under a 2s grace
    with 1s sweeps, 62 objects, zero lost.
  • scripts/abuse-test.sh: a battery of hostile HTTP inputs (overlong keys, path
    traversal in keys and pot names, control chars, empty/at-cap/over-cap bodies,
    bad auth, malformed JSON, huge headers) plus uploads under grace=0 GC. The
    server survives every input and kept all ~290 objects intact.
  • New unit/integration tests: in-flight pin survival under aggressive GC, orphan
    collection still works, and concurrent same-key / distinct-key write invariants.

Upgrading

Drop-in. On-disk format unchanged; a 0.4.0 (or 0.3.x) data dir opens as-is.

Docker

docker run -p 7373:7373 -p 7374:7374 -p 7375:7375 -p 9000:9000 -v barme:/data elroykanye/barme:0.4.1

Known limits

  • Alpha. Formats and on-disk layout may still change before v1.
  • Secret keys are still stored in the clear and the default barme/barme login
    still works out of the box — both land in the next release. Don't expose it yet.
  • A pot name plus key must encode to under 255 bytes (about 120 key bytes for a
    short pot).
  • barmed binds IPv4 (0.0.0.0); on a dual-stack host reach it via 127.0.0.1
    rather than localhost.
  • Single node. Image codecs (JPEG XL, AVIF) are routed but not yet transcoding.