12 KiB
SaraView
A self-hosted web file previewer/editor. Obsidian's look, without the parts you don't use, plus image and video previewing. Read-only integration with SaraTag's per-file Book tags is included.
It's made by Sarah, hence the name. :3
Usage
SaraView is for people who want an Obsidian-style notes app they host themselves, people who want to preview and edit files from any browser, and people who want multiple accounts with their own private directories.
Example use-cases:
-
Browsing and editing markdown notes from your phone, without installing anything.
-
Previewing images and videos that live next to your notes.
-
Giving a friend or family member their own login, with a directory only they can see.
Dependencies
Docker + Docker Compose. That's it for running it.
For local development instead: Python 3.11+, and Node.js + npm.
Installation
Here's a step-by-step tutorial.
- Clone or download this repository.
- Edit
SaraViewConf.tomlat the project root. Set your[Roots],[SaraTag], and[Storage]paths. (See Config Info below for what each field does.) - Edit
docker-compose.yml. Add avolumes:line for every root you declared, mount your SaraTag.saratagfolder read-only, and bind the port to your Tailscale interface's IP instead of0.0.0.0if you want it reachable only over the tailnet. - Run
docker compose up --build -d.
The backend serves the built frontend directly, so the whole app is on one
port (8420 by default).
Config Info
Paths in SaraViewConf.toml are resolved as given. Use absolute container
paths when running via Docker (see docker-compose.yml), matching whatever
you mount the volumes to.
[SaraView]
ConfigVersion = 1
ApplicationVersion = "0.1.0-beta"
[Server]
Host = "0.0.0.0"
Port = 8420
[Storage]
DataDirectory = "/data/SaraViewData"
[Roots]
Notes = "/data/notes"
[SaraTag]
Enabled = true
CoreModulePath = "/data/SaraTag/.saratag"
HideInternalFiles = true
InternalPatterns = [".saratag", ".SaraTag*", "*.book.toml"]
-
[Storage] DataDirectoryis where SaraView keeps its own data - Settings, Users, Themes, and so on. This is NOT one of the[Roots]below, so it's structurally unreachable from the file browser regardless of any hidden-file setting. Give it its own persistent volume (seedocker-compose.yml) so it survives rebuilds. -
[Roots]lists the named roots the browser can navigate. Add as many as you like; each becomes a top-level entry point in the frontend's root switcher. -
[SaraTag], ifEnabled, makes SaraView import SaraTag's ownCore.pydirectly (by file path, not by installing it as a package) to resolve Book tag files exactly the way SaraTag itself does. This is read-only - SaraView never writes Book or Lexicon files.
Local Development
Backend:
cd Backend
pip install -r requirements.txt
uvicorn Main:Application --reload --port 8420
Frontend, in a second terminal. Vite proxies /api to the backend.
cd Frontend
npm install
npm run dev
Directories as Files
Every directory gets its own note file. It's a hidden .sv_{DirectoryName}.md,
created automatically the moment you make the directory. Any extension works
if you rename the note later; markdown is just the default.
Click a directory the same way you'd click a file, and its note opens with the same edit/view/save toolbar. There's no separate "directory mode." Renaming or moving a directory keeps its note's name in sync automatically. Deleting a directory takes its note with it.
Browsing what's actually inside a directory is a sidebar-only action. Expand a folder there to see its contents. The "Open directory file on click" setting in Settings decides whether expanding a directory in the sidebar also opens its note in the main pane, or leaves the main pane alone.
Note files are hidden from listings by default, since their name starts
with .sv_. This is independent of the regular "show hidden directories"
setting. Flip on "Show directory note files (.sv_*)" in Settings if you
want to see and manage them directly, like any other file.
SaraTag Integration
SaraView never writes to Book or Lexicon files. It only reads them, by
loading SaraTag's own Core.py directly (by file path, not as an installed
package), so tag resolution always matches what SaraTag itself would show.
Editing tags from SaraView isn't implemented yet. SaraTag's own TUI remains the place to do that for now.
Settings and Themes
Settings (font, font size, active theme, hidden-folder visibility,
breadcrumb visibility) and themes live in Settings.toml and
Themes/*.toml inside the saraview_data volume. Not in any of your
[Roots], so they're never browsable from the app itself.
Three themes ship built in: CatppuccinMocha, Gruvbox, and Forest. Every
theme is just a flat set of named color roles (Background, Surface, Text,
Red, Orange, ... Purple), so creating a custom theme from Settings, or
hand-writing a new file in Themes/, only needs those same role names
filled in.
This is all per-user. Each account gets its own Settings/<Username>.toml
inside the data volume, seeded from the same defaults the first time that
user logs in. Themes themselves are shared across everyone (there's only
one copy of each theme file), but which theme is active is a per-user
choice.
Accounts and Login
On first launch, with no accounts yet, SaraView shows a one-time "create the admin account" screen instead of a normal login. Whoever sets that up first becomes an admin. After that, it's a normal username/password login screen for everyone.
Accounts live in Users.toml in the same saraview_data volume as
Settings and Themes. Passwords are hashed with PBKDF2-SHA256, never stored
in plain text. Admins get a "Users" section inside Settings to create
additional accounts, including other admins.
Sessions are currently in-memory only, so restarting the container logs everyone out. Fine for now with a small, trusted set of tailnet users.
Running on the Server
SaraView runs on SpineS as a Portainer stack built straight from this
repo. Portainer clones the repo, builds the image from the Dockerfile
and starts it, using docker-compose.server.yml. There's no image registry
and no CI: pushing a commit is all a release takes.
Config and data live in plain directories on the server (by default
/media/ZimaOS-HD/AppData/SaraView, holding SaraViewConf.toml and
Data/), not in a Docker volume, so redeploying or removing the stack never
touches them. The files SaraView serves are mounted at /data/files
(default /media/ZimaOS-HD/Storage/Files); the Roots in the server's
SaraViewConf.toml point inside it.
Setting up the stack
SaraViewConf.tomlhas to exist in the config directory before the first deploy: Docker would otherwise create a directory with that name.- In Portainer: Stacks → Add stack → Repository, on the
SpineS environment.
- Repository URL: this repo on Gitea (
http://git.srhtnin.garden/sarah/SaraView) - Repository reference:
refs/heads/main - Compose path:
docker-compose.server.yml - Environment variables: none needed on SpineS. Set
SaraViewDirand/orFilesDirto use other directories. - GitOps updates on, with polling (e.g. every 5 minutes), so new
commits on
mainredeploy on their own.
- Repository URL: this repo on Gitea (
- Stop anything else using port 8420 (e.g. an older SaraView install), then Deploy the stack. The first build takes a few minutes.
Updating
Push to main. With GitOps updates on, Portainer notices the new commit
and rebuilds and redeploys by itself. Otherwise, press Pull and redeploy
on the stack.
Groups and Access Control
Admin isn't a hardcoded flag. It's the built-in "Admin" group, which can't be deleted but is otherwise just a group like any other. Manage groups (create, delete, edit membership) from Settings → Groups (admin-only).
Setting access on a file or directory is not admin-only. Anyone can restrict a file or directory to specific users and/or groups, whether at creation time (the New File/New Directory dialog includes a search-and- checkbox picker) or afterwards via the 🔒 button next to any entry, in either the sidebar tree or the directory-browse pane. If you can currently see something, you're trusted to change who else can.
Admins do not bypass restrictions. Admin is a management group (creating users, managing groups, and so on), not a way to view everyone's private directories. Only direct access to the server's files can see everything.
Restricting is per-file-or-directory. Locking a directory covers everything inside it automatically (there's only ever one restriction record per locked directory; reaching anything underneath still requires being permitted on that ancestor), while locking an individual file affects only that file.
Anyone without access gets a plain 404, both for direct requests and for that entry showing up in a directory listing. A restricted item's existence isn't revealed to people who can't see it. Admins get a global overview of every current restriction from Settings → Locked Directories.
Blame Privacy
Each person can turn off "Show my edits in others' blame view" in their own Settings. When that's off, other users still see that lines were changed, just with the identity redacted, rather than attributing it to someone who asked not to be shown. You can always see your own attribution regardless of this setting.
There's also a per-viewer toggle for showing avatars instead of usernames in the blame gutter, using each author's chosen colour either way.
Desktop Client
Client/ is SaraView as a desktop app, built with Flet and laid out like
SaraFem: a tree of directories and files on the left, the file list on the
right, and an open file in place of the list. It has two modes, picked in Settings >
Connection:
- Local: browses one root directory on your own computer (any path).
Same rules as the server:
.sv_directory notes, SaraTag's own files hidden, new directories get their note. Deleting goes to the trash. - Server: talks to a SaraView server (the one on SpineS) through the same
/apithe web view uses. Logged out you browse as Guest; log in from the connection button in the toolbar to create, rename/move, delete, upload (large files go up in chunks) and edit. Saving records blame for you, locks are enforced by the server as usual, and SaraTag tags show above the file. Download saves a file, or a directory as a .zip.
Config and HTML files are highlighted, and Edit/Save (Ctrl+E, Ctrl+S) work
like the web view. Markdown follows the "Markdown editing" setting (also in
the web view's settings): Live shows it rendered and lets you edit
in place, like Obsidian (click a heading to see and edit its #s; Esc puts
it back), with Source (Ctrl+E) for the plain text; Separate keeps View
and Edit as two modes. Images show in the app;
videos and other files open in their default program (Open Externally).
Rename takes a / to move, like the web view (../Archive/Notes.md).
Shortcuts: Enter opens, Backspace goes up, F2 renames, Delete deletes,
Ctrl+N / Ctrl+Shift+N new file / directory, Ctrl+R refreshes, Ctrl+B
toggles the tree, Alt+Left/Right go back/forward, Esc closes the open file.
Settings live in ~/.config/SaraSuite/SaraView/Config.toml, with the
shared SaraSuite theme, font and title bar like every other Sara program.
A saved login is kept apart in Session.toml (never in a settings export);
server sessions end when the server restarts, and the client then falls
back to Guest.
- From source:
cd Client && python3 -m venv .venv && .venv/bin/pip install -r requirements.txt, thenPackaging/Launch.sh. - AppImage:
Client/Packaging/BuildAppImage.shbuildsdist/SaraView-x86_64.AppImage. - SaraSuite:
Client/Packaging/SaraSuite/is the manifest, kept in sync with SaraSuite'sPrograms/SaraView/. It installs onlyClient/.