Skip to main content
  1. Writing/

Building Evergreen Markdown Notes

·652 words

Some of the more traditional approaches to taking digital notes work quite well in 99% of cases - I think most of the tools on the market are doing a marvelous job. But I often caught myself needing something more, specifically for notes that I wanted to write once and frequently refer to later (e.g. details about specific projects that don’t change often). Dedicated note applications are great for in-flux notes that need handwriting, exploration, random images, but are a bit unwieldy when it comes to managing content in a highly-structured manner. Clearly, my time building had an influence on my authoring preferences - I needed Markdown.

I’ve already been a heavy user of Hugo2, so I thought I could re-purpose it for knowledge management, because why not. Lucky for me, someone much more skilled and knowledgeable than myself has already crafted the perfect theme for this - Docsy3. This theme structures all raw Markdown notes in a way that makes it look like you’re reading a technical documentation website (which, I can only assume, was the original intent of the theme).

Just like I did with DocFX back in the day, I wrapped the entire thing in a Docker container, and the Dockerfile ended up being much shorter than I originally anticipated:

FROM ubuntu:20.10
SHELL ["/bin/bash", "-c"] 
RUN apt-get update \
    && apt-get install nodejs --yes \
    && apt-get install npm --yes \
    && apt-get install wget --yes \
    && apt-get install socat --yes \
    && apt-get install git --yes \
    && mkdir hugotools \
    && cd hugotools \
    && wget \
    && yes | dpkg -i hugo*.deb \
    && hugo version \
    && mkdir site \
    && cd site \
    && hugo new site . \
    && rm -rf content \
    && rm -rf config.toml \
    && npm install -D --save autoprefixer \
    && npm install -D --save postcss-cli \
    && git clone --recurse-submodules --depth 1 themes/docsy \
    && echo -e "socat TCP-LISTEN:1900,fork,reuseaddr TCP:localhost:1313 &\n cd hugotools/site\nhugo server --buildDrafts" >>
ENTRYPOINT ["sh", "/hugotools/site/"]

You can always get the most up-to-date script from the GitHub repository4.

So what’s going on behind all this spaghetti of bash commands? Not a lot, actually.

  1. Installing required Node.js dependencies.
  2. Downloading and installing the latest release of Hugo5.
  3. Initializing a new site folder inside the container.
  4. Removing placeholder configuration and content.
  5. Installing npm dependencies that are required for Docsy.
  6. Cloning Docsy in a local themes folder.
  7. Creating an entrypoint script on the fly that creates a port binding and builds the site.

That’s it. To build the container, run the following command in the folder with the Dockerfile:

docker build .

Once built, you can bootstrap a new container based on the newly-created image:

docker run -it -p 1900:1900 -v /D/content:/hugotools/site/content -v /D/config.toml:/hugotools/site/config.toml <YOUR_IMAGE_HASH>

This last command maps the exposed port to a local port, and then mounts two items - the directory with content (all Markdown files), and the existing Docsy configuration file, that you can model after the one in their example repository4.

One caveat, and this is a problem that I need to still figure out how to solve - on Windows, live file updates are not caught by Hugo, so you need to re-build the notes every time the container starts. This is not a problem with mounted directories and files on macOS and Linux. But other than this - it’s a reliable and scalable solution to managing notes in Markdown with a good theme that renders the content for you like a full-blown documentation site.

You can check out the video I put together for a quick overview:

  1. This is one of the biggest technical documentation sites on the planet. I’ve worked on it a bit short of 5 years. ↩︎

  2. Among other things, this is the engine my blog is running on↩︎

  3. Can be downloaded here: ↩︎

  4. ↩︎ ↩︎

  5. You can always grab it here: ↩︎