Important
⚠️ As always, export your database before upgrading. Safety first!
Warning
This release will refuse to start if your secrets are still the example ones.
PASSJWT and SESSION_SECRET used to ship with placeholder values in .env.example and in
the Unraid template (SomeComplexPassword, AnotherComplexSecret,
ChangeThisToAComplexPassword, ChangeThisToAComplexSecret). Those strings are published,
so an instance still running one is signing its sessions with a secret anyone can read.
If your container restarts in a loop after updating, read its logs: the message names the
variable to fix. Generate each one with openssl rand -hex 32, use two different values,
and restart. Everyone is logged out once, which is expected.
Five pull requests this cycle, from three people, and the release ended up being mostly about images: putting several of them on an item, printing something you can stick on a sleeve, and making sure the page they live on actually renders. Thank you @ArtwoXYZ, @Siebe-Uy and @Kianuss :D
🖼 Every Item Gets a Gallery
Items used to have one main image and, for some modules, a second one. Now every item type, built-in or custom, has an ordered gallery: add as many images as you want from your computer, from a URL or from the search providers, drag the thumbnails to reorder them, and the first one is the cover everywhere.
- The item page follows. A scrollable thumbnail strip under the cover, and a lightbox with arrows, keyboard and swipe.
- Uploads are real files now. An image you upload from your computer is stored on disk under
public/uploads/itemsinstead of being stuffed into MongoDB as text. Existing items keep working untouched, and a ZIP backup migrates the old ones for you (see below). - Nothing breaks upstream.
cover_imageanduser_imagestill mean what they always meant, so an integration or a metadata refresh that only knows those fields keeps working.
Built by @ArtwoXYZ
🏷 Print Labels for Your Shelves
A new Print label button on every item page: a QR code that opens the item's page when scanned, or its barcode if it has one. And on the collection page, tick as many items as you like and print them all on one sheet, laid out to fill A4 across as many pages as needed.
Handy for boxes in the attic, crates at a record fair, or just knowing what's inside a sleeve without pulling it out.
thanks @Siebe-Uy for this one, it's a lot of small print-layout details done right.
📈 See What Your Collection Is Worth Over Time
The Estimate modal now remembers. Each time you run an estimate, the total is saved as a snapshot, and a chart shows how the value of your collection has moved since.
Snapshots are stamped with the currency the estimate actually ran in, server-side, so a collection whose members read in different currencies keeps one series per currency instead of drawing a trend that never happened. If yours is empty but someone else's isn't, the page says so rather than inviting you to start over.
thanks @Siebe-Uy again :)
🎯 Filters on the Wishlist
The wishlist was the one shelf with no filters. It now has the same ones as the collection (type, format, location, genre, artist, decade, sort) plus the items-per-page selector.
Filtering down to nothing keeps the controls on screen, so you can always get back out. That sounds obvious and it is exactly what the first version got wrong.
Built by @Kianuss, their second contribution here!
💾 Backups That Carry Your Images
Now that uploads are files on disk, a JSON backup alone can't move an instance to another machine: it would carry the paths and leave the pictures behind. So both the whole-instance and the per-collection backup gained a ZIP export that packs backup.json together with every local image it references.
- The JSON format still works, both ways, for every dump DVinyl has ever produced. Nothing you already have becomes unreadable.
- Old inline images are migrated for you. If your database still holds images from before file storage, exporting a ZIP moves them into the archive, and restoring it puts them on disk. Your live database is never touched by an export.
- The archive reader only accepts what DVinyl writes. Nothing is extracted by the path stored in the ZIP, so a hand-crafted archive can't write outside the uploads folder, and every restored image is re-checked and given a fresh name.
🛠 Fixes
-
The whole interface no longer collapses when a CDN can't be reached. DVinyl loaded Tailwind, Font Awesome, Flowbite, Chart.js, the barcode scanner and its fonts from public CDNs. An ad blocker, a DNS filter, a company network or simply an instance with no outbound internet was enough to leave every page with no layout at all. All of it is now served by your own instance, so DVinyl renders the same whether or not it can reach the internet. Reported by @FoxXxHater
-
The barcode scanner reads what your camera sees. The scanner was decoding a 250×150 thumbnail of the video feed, which is why a barcode that the reference ZXing demo picks up instantly could sit in frame forever without registering, especially on iPhone. It now decodes the full-resolution camera frame with ZXing directly. Reported by @ArtwoXYZ
-
Signing out of an SSO-only instance actually signs you out. With
OIDC_DISABLE_LOCAL_LOGIN=true, logging out cleared the cookie and then immediately bounced you back through the provider, which handed the same identity straight back. You now land on the login page instead, and the server-side session is destroyed too. Reported by @StelianMorariu -
A field you named yourself stops printing an error. Custom card fields were being sent through the translation layer whatever they held, so a collection that named a field something i18next didn't recognise got an error string in the card instead of the value. Fixed by @ArtwoXYZ
-
An item id can no longer be opened by the wrong module. Handing a record's id to the films route answered with the record. Each module now only answers for its own items, everywhere: detail, edit, delete and label.
-
The app can be installed as a PWA again. The service worker never finished installing, and cached things it had no business caching. It now installs, and only ever stores static assets, never a page rendered for a signed-in user.
-
A rejected image URL no longer blocks the whole form. Adding an image DVinyl couldn't fetch used to stop the save entirely, taking the rest of your edits with it.
-
A metadata refresh stops growing the gallery. Each refresh was sliding the replaced cover into the gallery as an extra entry, one stale URL per refresh, forever. The new cover now takes the old one's place.
-
Errors say which provider failed. A lookup failure always blamed Discogs, whichever service had actually timed out.
-
POST /setuprefuses to run on an instance that already has users, and a few smaller ones: a favicon on the label pages, theMONGODB_URLtypo in the startup error, uploaded images served withnosniff, and abandoned uploads swept on a timer instead of only at boot.
Same as always: nearly every line above started as one of your issues, and half of them arrived
with the code attached. Thank you @ArtwoXYZ and @Siebe-Uy for the pull requests, @Kianuss for
coming back with a second one, and @FoxXxHater and @StelianMorariu for reports that were clear
enough to fix from.
Love u all <3