Files
nvrl 4eb663e2d7 docs: a guide, a wiki and screenshots
The README grew a section per feature and is a good reference, but nothing
said where to begin. docs/wiki now has a getting-started page, a guide that
walks through one day with the workspace and explains each part where it comes
up, and a page per part of the app, each with screenshots of what it
describes.

Three pages are read out of the code rather than written, so they cannot drift
from it: the keys and commands from Help.svelte and commands.ts, the same lists
`:help` draws; the settings from .env.example, which gains a heading for the
vault, trash and history settings so they no longer sit under mail; and the
API from the README's table. `make wiki` writes them, and `--check` fails when
one is stale or a link between pages leads nowhere. `--publish` lays the pages
out for a GitHub wiki: links without `.md`, images beside them, `[[` escaped so
the wiki does not take a command's help text for a link to a page.

The screenshots are taken by `make screenshots`: the debug binary on a
temporary data directory, with a password made up for the run, filled with an
example workspace over the API, and a headless Chromium driven over the
DevTools protocol through the views the docs show. Nothing outside the
temporary directory is touched but docs/images, and the pictures are cut to
256 colours, a third of their size, which a dark UI does not show.

The README opens with the banner, a CI badge, the guide, the features grouped
by what they are for, and six of the screenshots.
2026-10-21 12:07:32 +02:00

5.6 KiB

Configuration

Every setting is an environment variable, read at start, usually from a .env file beside the binary (cp .env.example .env). The older DIARY_<NAME> spelling of each is still accepted. A value that is set but cannot be read stops the start with the reason rather than falling back to the default.

Basics

setting example what it does
WORKSPACE_USER narl The one and only account. Both are checked in constant time on login.
WORKSPACE_PASSWORD change-me See the row above.
WORKSPACE_SECRET replace-with-32-random-characters Signs session cookies. Rotate it to log every device out. 32+ random chars. Generate one with: openssl rand -base64 32
WORKSPACE_DATA_DIR ./data Where the SQLite database and uploaded media live.
WORKSPACE_BIND 127.0.0.1:4242 Address to listen on. Put a TLS terminating reverse proxy in front of this.
WORKSPACE_SESSION_DAYS 30 How long a login lasts, in days.
WORKSPACE_MAX_UPLOAD_MB 1024 Largest upload, in megabytes: one request, or what an imported zip unpacks to. Uploads stream to disk, so this bounds the disk, not the memory.
WORKSPACE_SECURE_COOKIE 0 Set to 1 once the app is served over HTTPS: the cookie gets Secure and the __Host- prefix (everyone is logged out once), and browsers are told to use HTTPS only (HSTS). The server refuses to start with the example secret or password above still in place.

SFTP mount

setting example what it does
WORKSPACE_SFTP_BIND 127.0.0.1:2222 Off until this is set. Once it's up, register a key with :sshkey add <name> <ssh-ed25519 ...> in the app, then sshfs -P <port> anything@host:/ mnt/ (the username is ignored — only the key decides who gets in). On the mount, mkdir at the root makes a space and anywhere else a folder; a new .md file is a new document. A leading # Heading is the document's title. Editor temp, swap and backup files are kept in memory for the session only, and renaming one onto a .md name saves it into that document. Under Docker, bind 0.0.0.0 (not 127.0.0.1) as the app listens inside the container — the host-side address in compose.yml's ports: is what actually restricts who can reach it.

Proton Drive backup

Off until :backup login <username> in the workspace (or narl-workspace proton-login) stores a session under WORKSPACE_DATA_DIR. These only shape how often the mirror runs.

setting example what it does
WORKSPACE_PROTON_DEVICE narl-workspace The device the server registers in Proton Drive; its sync root is the folder the diary is mirrored into.
WORKSPACE_BACKUP_INTERVAL_MIN 60 Backstop between runs, in minutes. 0 leaves it change-driven only.
WORKSPACE_BACKUP_DEBOUNCE_SEC 300 How long the diary must be quiet after a change before it is mirrored, so a writing session uploads once rather than after every save.
WORKSPACE_BACKUP_PRUNE 0 Set to 1 to let a deletion here trash the mirrored file there. Off by default: a backup that forgets on command is one accident from being none.
WORKSPACE_SESSION_KEY_FILE /run/secrets/session_key Seal the stored Proton session under a key kept off the data volume, so a copy of the volume alone carries no usable session. Point it at a Docker secret (see compose.override.yml.example); openssl rand -base64 32 makes the key. Losing the key costs a new proton-login, nothing more. Unset by default.

Notification mail

Off until WORKSPACE_SMTP_URL is set. Nothing is even queued while it is unset.

setting example what it does
WORKSPACE_SMTP_URL smtps://mail.example.org:465 The relay. smtps://host:465 is implicit TLS, smtp://host:587?tls=required is STARTTLS, and a bare smtp://host:1025 is plain — which only belongs on a local mail catcher. Credentials may live in the URL or in the two variables below. Unset by default.
WORKSPACE_SMTP_USER See the row above. Unset by default.
WORKSPACE_SMTP_PASSWORD See the row above. Unset by default.
WORKSPACE_MAIL_FROM workspace@example.org Where the mail comes from and goes to. FROM defaults to TO. Unset by default.
WORKSPACE_MAIL_TO you@example.org See the row above. Unset by default.
WORKSPACE_TIMEZONE Europe/Berlin "Did I write today?" and "is this due today?" are local-day questions, and the answer changes with the timezone rather than with a fixed offset.
WORKSPACE_REMINDER_AT 20:00 When to ask about the diary, if nothing was written in it that day. off turns it into no reminder at all.
WORKSPACE_CARD_DUE_AT 08:00 When to mail about cards that are due today or already overdue.
WORKSPACE_DIGEST_AT sun 18:00 Weekday and time of the weekly digest.
WORKSPACE_MAIL_KINDS reminder,card_due,digest,login Which of the four kinds may be sent. Drop one from the list to switch it off.

Vault, trash and history

setting example what it does
WORKSPACE_VAULT_IDLE_MIN 15 Minutes the vault stays open with nothing using it, before it locks itself. It also locks on logout and whenever the server restarts.
WORKSPACE_TRASH_DAYS 30 Days a deleted document, folder, file or space waits in the trash, where :trash can bring it back, before it and its files are deleted for good.
WORKSPACE_REVISION_DAYS 90 Days a document's earlier versions are kept for :history. The newest 20 of every document are kept however old they are.