A Side Quest in Knowledge Management: Adding NoteDiscovery: Part 6 of “Building a Resilient Home Server” Series

Part 6 of “Building a Resilient Home Server” Series

Where We Left Off

In Part 5, I added comprehensive monitoring to the server—Prometheus, Grafana, Loki, Promtail, Alertmanager, and ntfy. The server could now tell me when things went wrong before I noticed them myself.

But there was something else I’d been wanting to add: a better way to manage notes.

The Problem

I’d installed Obsidian a while back as a way to keep some notes—mostly blog stuff. Barely used it, honestly. The app was fine, but it felt like overkill for what I needed. I just wanted to jot down ideas, keep track of blog topics, maybe organize some technical notes.

Then someone mentioned NoteDiscovery in a discussion about self-hosted tools.

The pitch was simple: web-based markdown editor. No special apps needed. Just open a browser, write in markdown, done. All your notes stored as plain text files that you can sync however you want.

That sounded appealing.

I also had a bunch of long-term notes scattered across my phone’s notes app—things I didn’t need regular access to, but wanted to keep. Converting those to markdown and having them accessible from anywhere? Even better.

So I decided to give NoteDiscovery a shot. Worst case, I’d learn something about integrating non-NixOS services. Best case, I’d have a lightweight knowledge base that didn’t require installing anything beyond a web browser.

Enter NoteDiscovery

NoteDiscovery is a Python-based web interface for markdown notes. It’s designed to work with Obsidian vaults, but really it just serves markdown files with a clean UI, support for internal links, and basic editing capabilities.

Perfect for what I needed. Let’s add it to the server.

The Initial Setup

NoteDiscovery isn’t packaged for NixOS, so I needed to create a custom systemd service. The approach:

  1. Clone the NoteDiscovery repository
  2. Set up a Python virtual environment
  3. Install dependencies
  4. Point it at my notes folder
  5. Run it as a systemd service

I created two services in services.nix:

notediscovery-setup – A one-time service that clones the repo and sets up the Python environment

notediscovery – The main service that runs the web interface

systemd.services.notediscovery-setup = {

  description = "NoteDiscovery One-Time Setup";

  wantedBy = [ "multi-user.target" ];

  after = [ "network-online.target" ];

  serviceConfig = {

    Type = "oneshot";

    RemainAfterExit = true;

    User = "notediscovery";

    Group = "notediscovery";

  };

  path = with pkgs; [ git python3 ];

  script = ''

    if [ ! -d /var/lib/notediscovery/.git ]; then

      echo "Cloning NoteDiscovery..."

      ${pkgs.git}/bin/git clone https://github.com/gamosoft/NoteDiscovery.git /var/lib/notediscovery

    fi

    if [ ! -d /var/lib/notediscovery/venv ]; then

      echo "Creating Python virtual environment..."

      ${pkgs.python3}/bin/python3 -m venv /var/lib/notediscovery/venv

      /var/lib/notediscovery/venv/bin/pip install -r /var/lib/notediscovery/requirements.txt

    fi

  '';

};

Created the notediscovery user, added it to the configuration, rebuilt.

NoteDiscovery started. I could access it at http://notes.home via Nginx.

But I couldn’t see any notes.

Challenge 1: The Config Structure Mystery

NoteDiscovery needs a YAML config file. I created one based on the documentation:

app:

  notes_path: "/home/ppb1701/Obsidian/ppb"

Rebuilt. Still no notes.

Checked the logs:

KeyError: 'storage'

Turns out the config structure had changed between versions. The documentation was outdated. The actual config needed:

storage:

  notes_dir: "/home/ppb1701/Obsidian/ppb"

  cache_dir: "./cache"

  plugins_dir: "./plugins"

Lesson learned: when documentation doesn’t match reality, check the source code.

Challenge 2: The Duplicate Config Gotcha

I had created notediscovery-config.yaml in /etc/nixos/ for version control. But I also needed it in /etc/nixos/private/ for the actual configuration.

I ended up with two config files. Changes to one didn’t affect the other. NoteDiscovery was reading the wrong one.

The fix: keep the config in /etc/nixos/private/notediscovery-config.yaml (the real one with paths), and create an example version in /etc/nixos/private-example/ for the repository.

Lesson learned: single source of truth. Don’t duplicate configs across directories.

Challenge 3: Permission Hell (Part 1)

NoteDiscovery was now reading the config, but still couldn’t access the notes:

PermissionError: [Errno 13] Permission denied: '/home/ppb1701/Obsidian/ppb'

Right. NixOS systemd hardening.

I had ProtectHome = true in the service config, which blocks access to /home.

The solution: move the notes folder out of /home and into /var/lib/obsidian/ppb/.

Updated Syncthing to sync to the new location. Updated NoteDiscovery’s config. Rebuilt.

NoteDiscovery could now see the notes.

Challenge 4: The Path Within a Path

I could read notes. But when I tried to save an edit:

Failed to save note. Please try again.

Logs showed:

PermissionError: [Errno 13] Permission denied: '/var/lib/obsidian/ppb/ppb/Welcome.md'

There was a duplicate ppb in the path.

Actual directory structure:

/var/lib/obsidian/ppb/

├── ppb/

├── .obsidian/

├── .git/

My notes weren’t at /var/lib/obsidian/ppb/; they were at /var/lib/obsidian/ppb/ppb/.

The fix: update both config files to the correct path.

Challenge 5: Write Permissions

Config path was correct, but saves still failed with permission errors.

The notediscovery user could read files, but not write to them.

The solution was to create a shared group and set proper permissions:

sudo groupadd obsidian-users

sudo usermod -aG obsidian-users ppb1701

sudo usermod -aG obsidian-users notediscovery

sudo chown -R ppb1701:obsidian-users /var/lib/obsidian/ppb/ppb

sudo chmod -R 775 /var/lib/obsidian/ppb/ppb

Rebuilt. Tested.

It saved.

Challenge 6: Missing Config Sections

Everything was working. Then a new error appeared:

KeyError: 'search'

NoteDiscovery expected a search section in the config, even though it appeared optional in the documentation.

The fix: add the missing section.

Lesson learned: even “optional” config sections might be required by the code.

Monitoring NoteDiscovery

My first instinct was to scrape NoteDiscovery directly with Prometheus. That immediately triggered alerts.

The problem: NoteDiscovery doesn’t expose Prometheus metrics. Prometheus was getting HTML, not metrics.

The solution: use blackbox_exporter for HTTP health checks instead of direct scraping.

Now Prometheus probes NoteDiscovery (and other web services) via HTTP and alerts if they stop responding.

Lesson learned: monitor services appropriately. Web UIs need HTTP probes, not metrics scraping.

What’s Working Now

  • NoteDiscovery serving notes at http://notes.home
  • Read and write access from any browser
  • Syncthing syncing the vault
  • HTTP health monitoring via blackbox_exporter
  • Alerts when NoteDiscovery goes down
  • All configs declarative and in Git

The Lessons

NixOS security is strict by default, and that’s a good thing.

Check actual file paths instead of assuming directory structures.

Avoid duplicate configs. One source of truth saves time and sanity.

Monitor the right thing. Not everything exposes metrics.

Use groups and permissions when multiple services need access to shared data.

What’s Next

The server is in a good place now:

  • AdGuard Home filtering ads
  • Syncthing syncing files
  • NoteDiscovery serving my knowledge base
  • Comprehensive monitoring watching everything

There’s more I want to add (Nextcloud is on the list), but for now I’m taking another break. The server is stable, the monitoring is solid, and I’ve got other projects calling my name.

That’s the beauty of NixOS—it’ll be exactly where I left it when I come back.

← Back to Series
Main Server (nixos): Codeberg
Second Server (nixos2): Codeberg
ISO can be gotten here.


What do you think about NixOS for a home server?

Find me on Mastodon at @ppb1701@ppb.social