🔗 The Case for Physical Media Ownership →

A page categorizing all of the many, many reasons to buy, use, and store physical media.

The big one for me was:

Google Play Music shut down in December 2020 and was replaced by YouTube Music. Not all user libraries survived the transition intact.

This lead to me spinning up my first self-hosted service, Airsonic1. Since then I've got dozens of services running with 73 TB of spinning metal for backups. I archive all of my purchased books, music, photos, games, and beloved online videos daily. Between all the services and tools that Google has killed and all the content censorship and removal that the linked page has documented, I don't trust anything online at all. "The internet is forever"? Well, not lately, no.

Join us at /r/datahoarder. We have cookies.


  1. Though I have since happily transitioned to Navidrome.

🔗 Stop Using Conventional Commits →

You've almost certainly encountered Conventional Commits before. It may have reared its ugly head in the changelog of an open source project you've used. It may have been the enforced commit format for an open source project you contributed to. A lot of people swear by it. I swear at it.

Even though it is used by a large number of popular open source projects, Conventional Commits is an actively bad standard which encourages focus on the wrong things and fails to deliver on its promises.

I've recently tried to use conventional commits in some personal projects (mainly because Renovate Bot uses them), and I've got to say: I really don't think I like them.

The article gets into it, but e.g., if I expose additional functionality higher up that an already included library provides OOTB, is that a feat or a fix? I also could argue both.

But the argument that sealed it for me was the "if I'm debugging a PROD bug, do I care if it came about a feat or a fix or a chore?" No! I want to know what touched those subsystem's files, dependencies, or configs. chore(dep): upgrade doesn't give me anything; render: dependency upgrade tells me everything.

All that being said, throughout my professional life, I've had a ticketing system1 back every change we made. So I've gotten used to, and have enforced on other projects, this commit message format:

[PROJ-123] a really good one-liner description

 - Additional comments about the change, usually delivered in grammatical English prose. I usually go with bullet points of changes, but that's optional.
 - Basically, I would say that your entire reasoning for the change should be placed in the commit. If it was obviously explained in the code, that's great. Otherwise, it's got to go in the code comments or the commit message.
 -- Another maintainer *hated* code comments because he argued that they quickly became out-of-date. I couldn't argue against that.
 - I then told the story of how I once made a commit message whose body began with "Grab a cup of coffee, and let's talk about this."
 - Commit messages can (and should) be long, y'all

  1. Okay fine. It was always JIRA.

I Don't Understand Docker Volumes

I really don't get Docker volumes over bind mounts.

Docker says they're easier to backup/migrate over bind mounts1, but I don't understand how rsyncing a single directory that contains everything is supposed to be harder than doing whatever this series of commands are in their documentation.

To me, Docker volumes make sense when you're dealing with temporary data, such as a cache. Or when you're needing to process data before making it permanent. Something like a /tmp.

docker compose down should remove volumes by default. I imagine Docker intends docker compose down -v as a full reset, but a single additional small (-v) flag is so easy to inadvertently lose data. Instead they should force the sysadmin to manually delete the data by specifying the volume name after an rm -rf. And by "volume name", I, of course, mean the bind mount.

docker compose down to remove all volumes. docker compose down --keep-temp-volumes to keep the (should be temporary) volumes.

Anyways. I use bind mounts. I prefer them over volumes. If volumes died tomorrow, I would feel nothing but elation.2


  1. "Volumes"

  2. This whole piece came about because I was dealing with a 1TB server that was low on disk space, and I figured I would try docker volume prune to see if it cleared anything up. Reader, even after I brought every container down via -v, I cleared out 700GB+. That shouldn't be possible!!!

Docker Login with Sonatype's Nexus

Sonatype's Nexus is an artifact repository for a variety of formats (e.g., Maven, npm, Nuget, etc.), but I use it primarily for Docker. I cache all the images that I use1 not only for speed but also to keep a copy that I can control the life of. Once it's set up, it usually enters into that "forget it" step. However for dumb-dumb reasons of my own doing, I needed to re-configure my install.

I ran into this last time, and I ran into it again this time. For a hot minute, I could not login to the repository from via docker login; I kept getting a 401 Unauthorized. From the last time I set it up, I remembered there was something completely unintuitive that I needed to do. I figured it out again, and it takes less than 30 seconds to fix. Why Sonatype doesn't set this up automatically when you add a Docker repo, I don't know.

Anyways, for both you and future!me:

You have to mark the Docker Bearer Token Realm as Active.

To do so,

  1. Login as an administrator.
  2. Click Settings, then expand the Security section. Click Realms.
  3. Click the ➕ next to "Docker Bearer Token Realm". It should move to the "Active" column.
  4. Click Save, then try to docker login again.

And that's it.


  1. Maybe not all the images, but everything from Dockerhub (including, and especially, the library), ghcr.io, and lscr.io.