Skip to content
blindpassasjerPublic

About

A self-hosted vinyl, CD and cassette collection manager. Your database is the source of truth; Discogs is the metadata source.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Cratefolk logo

Cratefolk

A self-hosted vinyl, CD and cassette collection manager. Your database is the source of truth; Discogs is the metadata source.

Live demo · Quick start · Build it yourself · Features · License

License: Apache-2.0 Docker image Self-hosted Node


Cratefolk keeps track of the vinyl records, CDs and cassettes you own, the ones you want, and the ones you're selling. Add a release by searching Discogs (one search box for name, catalog number or barcode) and Cratefolk stores the metadata and cover in your own SQLite database, so your collection keeps working, and stays yours, even if Discogs changes or goes away.

It runs on your own machine, NAS or VPS with one docker compose up. No subscriptions, no ads, no third party holding your collection.

Try the live demo → — a static build with sample records and a mocked, browser-only backend (see Demo mode), so you can click around without installing anything.

Screenshots

Collection, dark mode Collection, light mode

A record with a copy marked for sale Public for-sale page

Features

  • 💿 Vinyl, CDs and cassettes — one search box for artist/album, catalog number or barcode (vinyl by default, or include every format), or scan the barcode with your phone's camera; the exact pressing, tracklist, label and cover are saved locally, and CDs and cassettes get a small badge on their cover. Not on Discogs? Add the record by hand, with your own cover photo and tracklist (you can edit or delete these later). Adding a record you already own asks first
  • 🗂️ Every copy is its own entry — own two copies of a record? Grade each one separately (media and sleeve, Goldmine scale) and add notes
  • 📦 Crates — group records any way you like ("Jazz", "90s", "Listening room"); a copy can live in several
  • 💡 Trivia on every record — a "Did you know?" box with facts from the album's Wikipedia article, falling back to the artist's, then to facts worked out from the record itself, so there is always something to read. It's fetched when you add a record, and links to its source
  • 🔍 Instant search and filters — search artist, title, label, catalog number or barcode as you type (press / to jump to it), filter by format, decade and country, sort, and resize the covers with a slider
  • ❤️ Wishlist — track the pressings you're after, see the current Discogs marketplace price and number of copies for sale, and move a record to your collection with one click ("Got it")
  • 🏷️ For sale — mark any copy as for sale with an asking price, filter your collection by it, and share a public "records I'm selling" page with grades and prices
  • 🔗 Share links — a public, read-only link for your whole library, a single crate, your wishlist or your for-sale list. Notes stay private, and you can revoke a link at any time
  • 📈 Stats — records by decade, format, genre, artist and label, what you added recently, and the value of your for-sale copies
  • 🔄 Discogs sync — connect your own Discogs account (Account → Discogs, with a personal access token; Cratefolk never asks for your password). "Sync now" merges your collection and wantlist both ways: records missing on either side are added, and for copies on both, grades and notes follow whichever side changed since the last sync (Cratefolk wins if both did). New records, wishlist items, grades and notes are also sent to Discogs as you make them, which you can switch off. Deletions only sync if you turn on "Also sync deletions"; otherwise nothing is ever deleted on either side, and a record you delete here simply won't come back at the next sync
  • 📊 Excel export — download your collection, a crate, the for-sale list or the wishlist as .xlsx
  • 👥 Multiple users — the admin creates accounts (and can set a password or hand out a one-time reset link), or opens registration so people can sign up themselves; everyone gets their own private collection
  • 🤝 Browse and share with friends — opt in to let other users browse your collection or wishlist (read-only, never your grades, notes or prices), and mark copies you co-own with someone, which then show in both your collections
  • 📰 Friends' activity feed — a collapsible sidebar feed of what friends add, wishlist, put up for sale and sell (only what they share, and they can opt out), plus a "Mark as sold" button for your own copies
  • 💱 Prices in your currency and a light/dark theme that follows your system
  • 🐳 One container — the API, the web app and an SQLite database, nothing else to run

Quick start (Docker Compose)

You need Docker with the Compose plugin. The image is published to GitHub Container Registry for linux/amd64 and linux/arm64, so it runs on a regular PC, a Raspberry Pi and most NAS boxes.

  1. Get the compose file and the example settings:

    git clone https://github.com/blindpassasjer/cratefolk.git
    cd cratefolk
    cp .env.example .env

    Don't want to clone? You only need docker-compose.yml and a .env file next to it.

  2. Edit .env:

    • ADMIN_EMAIL and ADMIN_PASSWORD — your admin login (required)
    • DISCOGS_TOKEN — a personal access token from discogs.com/settings/developers. It works without one, but Discogs then allows fewer requests per minute and withholds search thumbnails, so setting it is recommended
    • COOKIE_SECURE=true — only if you serve Cratefolk over HTTPS
  3. Start it:

    docker compose up -d
  4. Open http://localhost:6170 (or http://<your-server>:6170) and sign in with the admin account from step 2.

That's it. The database is created and migrated automatically on first start.

  • The admin account is created from ADMIN_EMAIL / ADMIN_PASSWORD on every start, and its password is re-synced from the environment, so changing the variable and restarting is how you reset it.
  • Sign-up is closed by default: the admin creates accounts under Users, and can switch registration on there if you want people to create their own accounts.
  • To use another port, change the left side of '6170:6170' under ports: in docker-compose.yml.
  • If you use env_file: .env, do not put DATA_DIR or PORT in it, and keep DATA_DIR: /data under environment: so nothing can redirect the database outside the data folder.

Upgrading

git pull                  # if you cloned the repo, to pick up compose file changes
docker compose pull
docker compose up -d

Database migrations run automatically when the container starts. Releases are tagged X.Y.Z; the latest tag always points at the newest release, and you can pin a version in docker-compose.yml (for example ghcr.io/blindpassasjer/cratefolk:0.3.0) if you prefer to upgrade deliberately.

Where your data lives

Everything is stored in a plain folder next to your docker-compose.yml, not in an opaque Docker volume, so you can browse, back up or move it like any other files:

What Where
Users, records, copies, crates, wishlist, share links (SQLite) ./data/cratefolk.db
Cover images fetched from Discogs ./data/covers/
Key that encrypts users' Discogs tokens ./data/secret.key

Backups

Stop the container so the database isn't being written to, copy the folder, and start it again:

docker compose stop
cp -a data "data-backup-$(date +%F)"
docker compose start

data/secret.key is what protects the Discogs tokens stored in the database, so keep your backups private. Without it the saved tokens can't be read and users would have to connect Discogs again.

To restore, stop the container, put the backed-up folder back as ./data, and start it again. Moving Cratefolk to a new machine is the same thing: copy data/ over, along with your .env.

Behind a reverse proxy / HTTPS

Cratefolk speaks plain HTTP on port 6170. To serve it over HTTPS, put a reverse proxy with a certificate in front of it (Caddy, Traefik, Nginx Proxy Manager, or your NAS's built-in one all work) and set COOKIE_SECURE=true in .env so the session cookie is only sent over HTTPS. HTTPS is also required for barcode scanning: browsers only allow camera access on secure pages (or localhost), so the scan button is hidden when Cratefolk is served over plain HTTP.

Configuration

Variable Default Description
ADMIN_EMAIL — (required) Email of the admin account, created on every start
ADMIN_PASSWORD — (required) Password of the admin account, re-synced on every start
DISCOGS_TOKEN empty Discogs personal access token for searching; raises the rate limit and enables search thumbnails. Syncing uses each user's own token, set under Account → Discogs
SECRET_KEY generated Optional passphrase for encrypting users' Discogs tokens. By default a random key is created in data/secret.key
COOKIE_SECURE false Set to true when served over HTTPS
TRUST_PROXY false Set to true only behind a reverse proxy that sets X-Forwarded-For; used for login rate limiting
PORT 6170 Port the server listens on. Preset in the Docker image, only set it for local runs
DATA_DIR ./data Where the database and covers are stored. Preset to /data in the Docker image
WEB_DIR ../web/dist Where the built web app is served from. Preset in the Docker image

Build it yourself

Pick whichever fits: build the Docker image from source, or run it directly with Node.js.

Option A: Build the Docker image from source

Handy if you want to run a modified version or a commit that isn't released yet. You only need Docker and Git.

git clone https://github.com/blindpassasjer/cratefolk.git
cd cratefolk
cp .env.example .env        # then set ADMIN_EMAIL and ADMIN_PASSWORD
docker compose up -d --build

--build makes Compose build the image from the Dockerfile in this folder instead of pulling the published one. To build the image on its own:

docker build -t cratefolk .

To build for another architecture (for example a Raspberry Pi from a PC), use docker buildx build --platform linux/arm64 -t cratefolk ..

Option B: Run it with Node.js (no Docker)

You need Node.js 20 or newer and npm.

git clone https://github.com/blindpassasjer/cratefolk.git
cd cratefolk
npm ci                      # install dependencies
npm run build               # builds the web app and the server

export ADMIN_EMAIL=admin@example.com
export ADMIN_PASSWORD=change-me-please
export DISCOGS_TOKEN=...    # optional, but recommended
npm start                   # http://localhost:6170

The server serves the built web app itself, so there is nothing else to run. Data is stored in apps/server/data/ unless you set DATA_DIR to somewhere else (use an absolute path). To keep it running in the background, use a process manager such as systemd or pm2.

better-sqlite3 is a native module. npm ci normally downloads a prebuilt binary; if there isn't one for your platform it compiles from source, which needs a C/C++ toolchain (build-essential and python3 on Debian/Ubuntu).

Demo mode

The live demo is a static build deployed to GitHub Pages by .github/workflows/deploy-demo.yml on every push to main. GitHub Pages can only serve static files, so the demo build replaces the real API client in apps/web/src/api.ts with a mock (apps/web/src/demo/mockApi.ts) that runs entirely in your browser:

  • A catalogue of sample records stands in for Discogs search. Covers are loaded from the Cover Art Archive when you're online, with generated artwork as the fallback, so no cover images are bundled.
  • Your changes (adding records, grading copies, crates, for-sale prices, share links) are saved to localStorage on your own device. Nothing is sent to a server.
  • Any email and password signs you in, and Excel export isn't available.
  • Reset demo data in the banner at the top starts over.

Build it yourself with:

npm run build:demo          # output in apps/web/dist, served from /cratefolk/

or run it as a dev server (served from /) with npm run dev:demo. If you fork the repo, set VITE_DEMO_BASE to your Pages subpath (for example VITE_DEMO_BASE=/my-fork/) and enable Settings → Pages → Source: GitHub Actions on your fork.

If you change the shape of an API response, update the mock to match, or the demo will drift from the real app.

Development

npm install
export ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=change-me-please
npm run dev        # API on :6170, web on :5173 (proxies /api)

Open http://localhost:5173. Layout: apps/server (Hono + SQLite), apps/web (React + Vite + Tailwind). npm run typecheck checks both. Database migrations live in apps/server/src/db.ts and run on start.

Tech stack

React 18 · Vite · Tailwind CSS 4 · Hono · SQLite (better-sqlite3) · Zod · TypeScript. One small codebase, one container, no external services beyond the Discogs API.

Support

Cratefolk is free and open source. If it's useful to you, you can buy me a coffee or Vipps me.

Contributing

Issues and pull requests are welcome. The codebase is small enough that most changes are straightforward to review.

License

Apache-2.0

About

A self-hosted vinyl, CD and cassette collection manager. Your database is the source of truth; Discogs is the metadata source.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages