Self-hosted personal Markdown notes library: catalog, nested collections, editor & full-text search
1.1K
A self-hosted personal library for Markdown notes: write, upload, organise, read and edit notes, documentation, recipes, journals or snippets from a catalog styled like a library card index. Built to run in Docker on a home server (TrueNAS SCALE and friends), with configurable storage paths.
Sister app of pdf-library: same catalog, nested collections, role-based login, per-user sharing
and Docker deployment — but here the content is editable Markdown, with an editor, rendered
preview, autosave and full-text search.
Your notes are stored as plain .md files on disk, not inside the database. You can read, back up
or move them with any tool you like.
Ctrl/Cmd+S to save immediately..md files at once, with per-file progress and errors.--- ... ---) is preserved verbatim in the file, hidden from the preview and
never used to derive the title.admin (full control) and user (read only), with per-user collection sharing..md.latest, 1.0.0linux/amd64, linux/arm64Create a .env file:
PORT=3000
MAX_UPLOAD_MB=5
# Generate one with: openssl rand -hex 32
JWT_SECRET=
ADMIN_USER=admin
ADMIN_PASSWORD=
STORAGE_HOST_PATH=./storage
DB_HOST_PATH=./data
And a docker-compose.yml:
services:
md-library:
image: tallon43/md-library:latest
container_name: md-library
restart: unless-stopped
ports:
- "${PORT:-3000}:3000"
environment:
PORT: 3000
NOTES_STORAGE_PATH: /data/storage
DB_PATH: /data/db/library.db
MAX_UPLOAD_MB: ${MAX_UPLOAD_MB:-5}
JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET in .env}
ADMIN_USER: ${ADMIN_USER:-admin}
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-}
volumes:
- ${STORAGE_HOST_PATH:-./storage}:/data/storage
- ${DB_HOST_PATH:-./data}:/data/db
Then:
docker compose up -d
docker compose logs -f md-library
| Variable | Description | Default |
|---|---|---|
PORT | Server port | 3000 |
NOTES_STORAGE_PATH | Where the real .md files are stored | /data/storage |
DB_PATH | Path to the SQLite metadata file | /data/db/library.db |
MAX_UPLOAD_MB | Per-file upload and per-save size limit (MB) | 5 |
JWT_SECRET | Secret used to sign the session JWT (required) | — |
SESSION_DAYS | Session lifetime in days (JWT and cookie) | 7 |
ADMIN_USER | Admin user created on first run | admin |
ADMIN_PASSWORD | Admin password. If empty, a random one is generated and printed once in the log | (generated) |
/data/storage — the .md note files./data/db — the SQLite database (metadata and the full-text index).On first run an admin user is created. If you did not set ADMIN_PASSWORD, the generated password
is printed once in the container log — save it, it will not be shown again. There is no public
sign-up; further users are created by the admin from the Users screen.
.md files hold the text, but titles, collections, users and dates
live in the database. If the search index ever falls out of sync with the notes, it rebuilds
itself on startup by reading the files from disk.Content type
Image
Digest
sha256:d6576857b…
Size
77.3 MB
Last updated
8 days ago
docker pull tallon43/md-library