Over the past couple of days, I fell in love with Obsidian.

However, what pains me is the fact that both Obsidian Sync and Obsidian Publish are locked behind a paywall, with seemingly no option to self-host either of them. Luckily, the community already stepped up and did a lot of the heavy lifting for me.


There are only a few simple reasons as to why I wanted to do this:

  1. Both of these services cost money. I have very strong opinions on subscription services, especially if they are arbitrarily paywalled (as they are in this case). The proposition for both does not seem too enticing to me either, as both have their very own limitations that make me question whether or not investing is worth it:

    • I update this blog very infrequently, so paying 8$/mo just for a fun side-project seemed like a bit too much for me.
    • The file limitations with Obsidian Sync seem very low and arbitrary for me, so I don’t see the point in spending 4-8$/mo here.
  2. I’d be sending all of my data to a foreign server. If Obsidian truly is meant to be a “second brain”, I want that brain to be within my control.

  3. I have the infrastructure needed to accomplish this, so why not put it to good use?


Alright then, let’s discuss how I’ve set my plan into action:

Obsidian Sync

At first I looked into self-hosting Obsidian Sync, since this is the more vital one of the two services two me. Having my notes synced between my phone, laptop and tablet is crucial in my life as a student.

I initially looked into the self-hosted livesync plugin. It looks and feels solid enough, and after installing a CouchDB instance on my server things worked out well. However, I soon found myself battling numerous merge conflicts after just a couple file moves (and a very flaky user experience), I soon looked at other options.

I then moved onto the remotely save plugin (in conjunction with a WebDAV server, as S3 scares me), which did away with most of the issues I’d been having.

More importantly though, this created a full and unencrypted mirror of my data on my server, which is perfect for combining with some static-site generator!

Sidenote: “remotely save” does also include the option to encrypt your notes, I just chose not to in order to make this setup as seamless and possible.

Obsidian Publish

After looking for a suitable static-site generator, I stumbled across quartz, which is a very easy to use, batteries-included static-site generator that is meant to be used with Obsidian. Fantastic!

I had some issues with installation, most notably that I had to fork the repository in order to get an up-to-date container image, but after that, things worked out flawlessly!

The final result

In total, I’m running two services (plus traefik, which handles all of the routing on my server) in order to make this setup work. The following docker-compose.yaml is an attempt to simplify what I’ve set up here:

    image: traefik:v2.10
    restart: unless-stopped
    profiles: ["all"]
      - /etc/server/traefik/traefik.yaml:/etc/traefik/traefik.yaml
      - /var/run/docker.sock:/var/run/docker.sock:ro
	  - 80:80
	  - 443:443
    image: micromata/dave
    restart: unless-stopped
    profiles: ["all", "obsidian"]
      - ./dave.yaml:/config.yaml:ro
      - ./obsidian:/data
	  - "traefik.enable=true"
	  - "traefik.http.services.webdav.loadbalancer.server.port=8000"
	  - "traefik.http.routers.webdav.tls=true"
	  - "traefik.http.routers.webdav.service=webdav"
	  - "traefik.http.routers.webdav.rule=PathPrefix(`/webdav`)"
    image: ghcr.io/phntxx/notes
    restart: unless-stopped
    profiles: ["all", "obsidian"]
	  - ./obsidian/vault/Blog:/app/content
	  - "traefik.enable=true"
	  - "traefik.http.routers.notes.tls=true"
	  - "traefik.http.routers.notes.rule=PathPrefix(`/blog`)"