Website docs update

This commit is contained in:
Zef Hemel
2026-07-23 14:53:28 +02:00
parent a99e5d98be
commit b667e35fe3
12 changed files with 185 additions and 164 deletions
+19 -31
View File
@@ -3,21 +3,27 @@ tags: getting-started
references:
- bin/silverbullet/src/config.rs
- bin/silverbullet/src/server.rs
- server/src/multi/users.rs
- server/src/multi/access.rs
---
How you authenticate depends on how the server is running (see [[Space Manager#Boot modes]]):
To be secure it is recommended you enable authentication. Here are the options.
* **Accounts (the default).** A fresh install manages people through named accounts in `users.json` and controls who can reach each space. This is the recommended setup — see [[#Accounts]].
* **Single-space mode.** One folder served as one space, authenticated by a single set of environment-variable credentials — see [[#Single-space mode]].
* **No authentication.** A single-space server with no credentials set is open to anyone who can reach it.
# Default: no authentication
Out of the box, SilverBullet runs **unauthenticated** — anyone who can reach the server’s port can read and write your entire space. There are no built-in default credentials. This is intentional: for `localhost` use it’s the simplest possible setup. As soon as your server is reachable from anywhere else, you need to turn authentication on yourself.
# Accounts
When the server runs in the default [[Space Manager|multi-space]] mode, authentication is account-based:
# Single-user authentication
SilverBullet’s built-in auth is a single set of credentials, set via the `SB_USER` environment variable in `username:password` form. There is intentionally no notion of multiple users or signup flow — a SilverBullet [[Space]] is a personal space.
* Every person has an **account** (username + password).
* Each [[Space]] is either **public** (no login) or requires login, and lists the **members** allowed in. Admins can reach every space and the admin UI.
* Accounts, spaces, and access are all managed in the `/.spaces` surface, which every account can open (admins additionally get the Users tab and space create/edit screens).
* When no space is bound to `/`, the server root provides an account-facing index of the spaces available to the current user.
If you need multi-user style access control (different people, SSO, MFA, …), put SilverBullet behind an [[Authentication Proxy]] (Authelia, Authentik, Cloudflare Access, etc.) and let that handle identity.
# Single-space mode
[[Space Manager#Single-space mode|Single-space mode]] serves one folder as one space, authenticated the classic way: a single set of credentials set via the `SB_USER` environment variable in `username:password` form.
For running many separately-authenticated spaces from one server, see [[Multi-Space Mode]].
# Enabling authentication
## Enabling authentication
Set `SB_USER` when starting the server. For the [[Install/Binary]]:
```shell
@@ -32,28 +38,10 @@ docker run -e SB_USER=pete:1234 ...
This allows `pete` to log in with password `1234`. When authentication is enabled, SilverBullet shows a login page on first access.
## Changing the user or password
There’s nothing to “reset” — just restart the server with a different `SB_USER`. Existing browser sessions get invalidated on the next request and you (or whoever) will be prompted to log in again.
# API
For programmatic access via the [[HTTP API]], you can use bearer token authentication. In single-space mode, this token is configured with an environment variable, see [[Install/Configuration]]. In multi-space mode, new API tokens can be issued via the [[Space Manager]] UI.
# Remember me
The login page has a "Remember me" checkbox. When checked, the session persists across browser restarts. The session duration defaults to 7 days and can be configured:
* `SB_REMEMBER_ME_HOURS`: Sets session duration in hours (default: 168, i.e. 7 days)
# Lockout protection
To prevent brute-force attacks, SilverBullet locks out clients after too many failed login attempts:
* `SB_LOCKOUT_LIMIT`: Number of failed attempts before lockout (default: 10)
* `SB_LOCKOUT_TIME`: Duration of lockout in seconds (default: 60)
# API authentication
For programmatic access via the [[HTTP API]], you can use bearer token authentication:
* `SB_AUTH_TOKEN`: Sets a token for `Authorization: Bearer <token>` style authentication
This is useful for scripts, automation, or integrating SilverBullet with other tools.
# Authentication proxy
Alternatively, or in addition, you can use an [[Authentication Proxy]] to delegate authentication to an external system (like Authelia, Authentik, or a reverse proxy's built-in auth). This is common in more complex self-hosted setups.
# Authentication proxies
Alternatively, or in addition, you can use an [[Authentication Proxy]] to delegate authentication to an external system (like Authelia, Authentik, or a reverse proxy's built-in auth). This is common in more complex self-hosted setups. In accounts mode, pair a proxy with **public** spaces so the proxy owns identity; in single-space mode, put the proxy in front of an open server.
For all authentication-related configuration options, see [[Install/Configuration#Authentication]].
+15 -13
View File
@@ -3,33 +3,35 @@ An attempt at documenting the changes/new features introduced in each release.
## Edge
Whenever a commit is pushed to the `main` branch, within ~5 minutes, it will be released as a docker image with the `:v2` tag, and a binary in the [edge release](https://github.com/silverbulletmd/silverbullet/releases/tag/edge). If you want to live on the bleeding edge of SilverBullet goodness (or regression) this is where to do it.
* **Multi-space mode**: set `SB_MULTI_SPACE=1` (plus `SB_USER` for admin credentials) to serve any number of spaces from one process. Spaces are bound to a URL prefix or hostname. See [[Multi-Space Mode]].
* **Baked sections**: bake `${...}` Lua expressions and widgets into
HTML-comment-delimited markdown (`<!--#lua EXPR -->` … `<!--/lua-->`). See [[Baked Sections]].
* [[Space Manager]]: multi-space hosting with multiple accounts is here. A fresh install pointed at an empty folder opens a browser-based first-run **setup wizard** that creates an admin account and your first space, then serves it in place with no restart. One server can host any number of [[Space|spaces]], each bound to a URL prefix or hostname.
* [[Baked Sections]]: bake `${...}` Lua expressions and widgets into
HTML-comment-delimited markdown (`<!--#lua EXPR -->` … `<!--/lua-->`).
* Space Lua: **code complete now shows documentation** (where available), all available via [[API/spacelua]] reflection APIs.
* Backend and CLI have been ported to Rust ([see background on this](https://no.silverbullet.plus/tech-stacks)), both should be behavior preserving (that is: you shouldn’t really notice):
* The server backend (previously written in Go) has now been replaced by an adapted version of SilverBullet+‘s backend written in Rust, more unifying those code bases.
* CLI client also reimplemented/backported to Rust as well.
* The server backend (previously written in Go) has now been replaced by an adapted version of [SilverBullet+](https://silverbullet.plus/)’s backend written in Rust, more unifying those code bases.
* CLI client reimplemented/back-ported to Rust as well.
* This means the project is now all TypeScript + Rust.
* The goal is to make do this without regressions, but watch for any issues.
* [[Frontmatter]] in the editor now has configurable folding: by default long frontmatter blocks fold automatically, and `frontmatterFolding` options let you disable auto-folding, always fold frontmatter, or change the line threshold. A subtle right-side marker folds or unfolds the whole block, and folded frontmatter previews any `tags` value as tag chips. This is configurable via the [[Configuration Manager]] as well.
* Pulling the "this was experimental card" for the CLI: removed the `sb get` command and the `/.runtime/objects/*` REST API, including their dedicated client-side query bridge. Use `sb query`, `sb eval`, or `sb script` for indexed-object access. This added too much complexity and another query language.
* Fix: major typing/navigation slowdown on pages with many internal links in large spaces.
* Fix: the service worker precached client assets *through* the browser's HTTP cache, so a stale client could be copied into its cache and then served as though it were the current build — leaving a "A new version of SilverBullet client is available." notification that no reload could clear (only a hard reload, which bypasses the service worker, showed the real client; the next normal reload brought the notification back). Precaching now bypasses the HTTP cache.
* The server now sets `Cache-Control` on client assets, which matters if you run SilverBullet behind a CDN. Previously it set none at all, so a proxy applied its own default to everything (Cloudflare's is 4 hours) — which was wrong in both directions: `client.js`, `main.css` and `service_worker.js` keep stable filenames and so could be served stale for hours after an upgrade (producing a "new version available" notification that reloading could not clear), while the content-hashed chunks, which can never change without their URL changing, expired every few hours for no reason. Entry points now revalidate (`no-cache`, answered by a cheap 304 when unchanged) and hashed chunks are cached for a year as `immutable`.
* New `index.describeSchema()` and `index.tagSchema(tag)` Space Lua APIs that expose indexed object-type / tag schemas as raw JSON Schema to scripts, widgets, and the `sb describe` CLI: `describeSchema()` returns a map of tag name → JSON Schema (only tags that declare a schema), and `tagSchema(tag)` returns a tag's JSON Schema or `nil` if undefined or schema-less.
* New `system.reboot()` Space Lua syscall: makes edited-on-disk changes live.
* Lua: Space Lua comments are now parsed and retained in the AST instead of being stripped before parsing.
* The server now sets `Cache-Control` on client assets, which matters if you run SilverBullet behind a CDN.
* Lua: Space Lua comments are now parsed and retained in the AST instead of being stripped before parsing (part of the enabler for code complete with documentation).
* Fix: first-ever load of an authenticated space no longer shows a spurious "Could not process config and no cached copy, please connect to the Internet" alert before redirecting to the login page (the login redirect aborted the remaining boot requests, which were misread as being offline).
* Fix: frontmatter link live preview now follows the editor's regular markdown preview behavior: raw YAML syntax stays visible when markdown syntax rendering is enabled, and only the link currently being edited is revealed in clean mode.
* Fix: tags shown in folded frontmatter now navigate to their tag pages instead of unfolding the frontmatter block.
* Frontmatter in the editor now has configurable folding: by default long frontmatter blocks fold automatically, and `frontmatterFolding` options let you disable auto-folding, always fold frontmatter, or change the line threshold. A subtle right-side marker folds or unfolds the whole block, and folded frontmatter previews any `tags` value as tag chips.
* Fix: write-mode commands (those requiring read-write, e.g. the baking commands) are now hidden in the command palette and their keybindings disabled on **per-page** read-only pages (`perm: ro`), not just in fully read-only spaces.
* Runtime API: the embedded headless-Chrome runtime now logs its lifecycle (when it launches on first use, when it becomes ready, and on crash/restart), and forwards the headless page‘s `console.*` output to the server log by default (disable with `SB_CHROME_LOG_CONSOLE=0` see [[Install/Configuration]]).
* HTML comments (both inline `<!-- ... -->` and block comments, including the baked-section `<!--#lua … -->` / `<!--/lua-->` markers) now render in a subtle gray and slightly smaller font in the editor, like code comments.
* New [[API/codeWidget]] Lua API: register a renderer for a fenced code block language from Lua (e.g. ` ```mermaid `), previously only possible with plugs. A `render(body)` function receives the code block contents and returns a widget (or markdown/HTML).
* HTML comments (both inline `<!-- ... -->` and block comments, including the baked-section `<!--#lua … -->` / `<!--/lua-->` markers) now render in a subtle gray and slightly smaller font in the editor, like code comments.
* Fix: Space Lua now correctly truncates a parenthesized expression to a single value (Lua 5.4 semantics). Previously `(string.gsub(...))` and other parenthesized multi-return calls leaked their extra return values into `return`, call-argument, and assignment positions (e.g. `table.insert(t, (string.gsub(...)))` inserted two elements). Parentheses now yield exactly one value.
* Fix: Lua pattern matching lost capture groups, because `ipairs` dropped `nil` values from the result table (by [henrikx](https://github.com/henrikx)).
* Fix: `lintObjects` threw when a page's `pageMeta` was undefined (by [josh-j](https://github.com/josh-j)).
* Fix: `mq.poll` materialized the entire queue on every poll (by [josh-j](https://github.com/josh-j)).
* Fix: on Safari/WebKit, the first keystroke right after a paste could be inserted at the wrong position (e.g. pasting a URL inside `[text]()` and then pressing `)` produced `[text]()url)` instead of typing over the closing bracket). WebKit left the typing caret at the pre-paste position; the editor now re-syncs it after a paste.
* Navigating to a page via a link now always opens it fresh (at the top, or at an explicit `#header`/`@pos` pointer in the link) instead of restoring your previous cursor and scroll position. Returning to a page via browser Back/Forward or the [[Page Picker]] still restores where you were. Plugs/Lua can opt into restoring with the new `editor.open` syscall (see [[API/editor]]).
* Fix: modals now set `box-sizing`, so their padding no longer pushes content past the intended width (by [Federico Scodelaro](https://github.com/pudymody)).
* Favicon definitions cleaned up and documented following current best practices (by [Jorge Marin](https://github.com/chipironcin)).
* The server now compresses `GET` responses, reducing transfer sizes over slow connections.
## 2.9.0
* New [[Object/relation]] indexed object capturing generalized object-to-object relationships. This is a successor to [[Object/link]], which still exists as a virtual collection built on top of `relation`.
+5 -5
View File
@@ -6,8 +6,8 @@ references:
- bin/sb/src/main.rs
---
> **note** Not the server
> `sb` is the optional **CLI client** — it talks to an already-running SilverBullet instance over HTTP. If you’re looking for the actual server binary, that’s [[Install/Binary]] (`silverbullet`), not this. You do not need `sb` to use SilverBullet.
> **note** This is **not** the server
> `sb` is the optional **CLI client**, it talks to an already-running SilverBullet instance over HTTP. If you’re looking for the actual server binary, that’s [[Install/Binary]] (`silverbullet`), not this. You do not need `sb` to use SilverBullet.
The SilverBullet CLI is a companion command-line tool for interacting with a running SilverBullet instance from your terminal. It communicates with the server via the [[Runtime API]], letting you evaluate Lua expressions, run scripts, open an interactive REPL, tail logs, and more — without touching a browser.
@@ -117,9 +117,9 @@ Self-update the CLI binary to the latest stable or edge release.
# Authentication
The CLI supports three authentication methods, configured per-space during `space add`:
* **Token** — sends an `Authorization: Bearer <token>` header. Use this with `SB_AUTH_TOKEN` on the server.
* **Password** — authenticates via `POST /.auth` (username/password), then uses the returned session cookie. Use this with `SB_USER` on the server.
* **None** — no authentication (for local or trusted-network setups).
* **Token** — sends an `Authorization: Bearer <token>` header. Use this with `SB_AUTH_TOKEN` on a [[Space Manager#Single-space mode|single-space]] server, or with a per-account [[Space Manager#API tokens|API token]] on an accounts-based server.
* **Password** — authenticates via `POST /.auth` (username/password), then uses the returned session cookie. Use this with `SB_USER` on a single-space server, or with an account username/password on a space you’re a member of.
* **None** — no authentication (for local or trusted-network setups, or public spaces).
Credentials are encrypted at rest using AES-256-GCM with PBKDF2 key derivation.
+2
View File
@@ -29,4 +29,6 @@ On the client, all of SilverBullet’s local data storage is built on a small ke
A strong 256-bit cryptographic key is derived (using _PBKDF2_) on the client from your username/password combo entered upon login. This key is kept in the service worker for SilverBullet clients to obtain so that the user is not required to constant log in when refreshing a tab, or opening new SilverBullet tabs and windows.
On an account-managed multi-space server, every prefix uses the server's shared encryption salt. Prefixes have separate service-worker scopes, so a newly opened space asks the server's other same-origin SilverBullet workers for the in-memory key. As long as another unlocked space remains open, moving between spaces does not require entering the password again; once every worker has discarded the key, the login page is required to unlock client storage again even if the server session cookie is still valid.
Since we need deterministic and stable encryption for data store keys, we use _AES-CTR_ with a fixed counter. For values we use _AES-GCM_ with randomized ivs.
+8 -7
View File
@@ -1,9 +1,9 @@
#getting-started
Excited to use SilverBullet? Here are three ways for you to deploy it.
Excited to use SilverBullet? Here are a few ways for you to deploy it.
> **note** Note
> There is now a fourth option: the (commercial) [desktop app](https://silverbullet.plus) version of SilverBullet.
> There is now an additional option: the (commercial) [desktop app](https://silverbullet.plus) version of SilverBullet.
# localhost (desktop, laptop)
While this is not an ideal deployment (it limits accessing your space to _just your own machine_), it is an easy way to get started (although [SilverBullet+](https://silverbullet.plus) may be an even lower-friction option to consider): simply run the SilverBullet server on your own laptop or desktop.
@@ -12,7 +12,7 @@ Steps:
1. Install SilverBullet following the instructions of one of these options:
* [[Install/Binary]] — a single self-contained binary
* [[Install/Docker]] — a docker container
3. Access it via `http://localhost:3000`
3. Access it via `http://localhost:3000` and go through the setup flow.
4. Follow [[Getting Started]] to learn the basics
Is that working out for you? Great, then proceed to deploy SilverBullet _properly_ on a server so you can also access it from other devices (like your phone).
@@ -27,15 +27,16 @@ There are three things to take care of, in this order (follow the links in each
* [[Install/Docker]] — a docker container
2. Be sure you enable [[Authentication]] for security
3. Deploy a [[TLS]] layer front of SilverBullet: browsers require `https://` (or `localhost`) for SilverBullet’s service worker, crypto, and clipboard APIs to work, so _you cannot_ reach a remote SilverBullet server over plain `http://`.
5. Once that’s all set up, follow [[Getting Started]] to learn the basics of using SilverBullet itself.
Hosting more than one space? Rather than running a separate server process per space, consider [[Multi-Space Mode]]: one process serves any number of spaces, each with its own URL, authentication, and admin UI.
4. Once that’s all set up, go through the setup flow and then follow [[Getting Started]] to learn the basics of using SilverBullet itself.
# Cloud
While [[Self Hosted]] is the intended path, if this is too much hassle for you. There is a simpler option by using [PikaPods](https://www.pikapods.com/pods?run=silverbullet). For a small fee (about $1.50 per month), you can run your instance there. PikaPods handles deployment, upgrades and backups and exposes SilverBullet securely via TLS.
While [[Self Hosted]] is the intended path, if this is too much hassle for you. There is a simpler option by using [PikaPods](https://www.pikapods.com/pods?run=silverbullet). For a small fee (about $2 per month), you can run your instance there. PikaPods handles deployment, upgrades and backups and exposes SilverBullet securely via TLS.
PikaPods contribute a part of their revenue back to the projects they host, so it’s a source of [[Funding]] for SilverBullet itself.
# First run
When you point the server at an **empty** folder — or one that doesn’t exist yet — it opens a browser-based setup wizard that creates an admin account and your first space — see [[Space Manager]].
# Notes on file systems
## Case insensitive file systems (Mac and Windows)
It is _highly discouraged_ to run SilverBullet (in real use) on a _case insensitive_ file system. SilverBullet assumes your file system is _case sensitive_ and acts accordingly.
+13 -17
View File
@@ -22,42 +22,38 @@ We start by [downloading the `silverbullet-server-*` zip for your platform from
Unzip this archive somewhere convenient. You’ll get a single `silverbullet` executable.
Then, create a folder to hold your [[Space]] (your notes will live here):
Then, create a folder to hold your data (your server configuration and space files will live here):
```bash
mkdir my-space
mkdir sb-data
```
Run the server, pointing it at that folder:
```bash
./silverbullet my-space
./silverbullet sb-data
```
It listens on `http://localhost:3000` by default. To pick a different port, use `-p`:
Since `sb-data` is empty, this opens a first-run setup wizard for accounts and your first space — see [[Space Manager]]. Point the server at a folder that already holds pages instead, and it’s served immediately as a classic single space.
The server listens on `http://localhost:3000` by default. To pick a different port, use `-p`:
```bash
./silverbullet -p 3001 my-space
```
And to bind on an address other than `127.0.0.1` (e.g. to make it reachable on your LAN), use `-L`:
```bash
./silverbullet -L 0.0.0.0 my-space
```
To force classic single-space behavior add `--single`:
```bash
./silverbullet --single my-space
```
> **note** Note
> If you want to access SilverBullet from another machine, you need [[TLS]] _and_ you should enable [[Authentication]] first.
Now, open `http://localhost:3000` in your browser and head to [[Getting Started]] to learn the basics.
# Authentication
By default the server runs **unauthenticated** — anyone who can reach the port can read and write your space. This is fine for `localhost`, but as soon as you expose the server to anything else, set the `SB_USER` environment variable:
```bash
SB_USER=admin:somepassword ./silverbullet my-space
```
See [[Authentication]] and [[Install/Configuration]] for the full picture (lockout policy, API tokens, etc.).
# Configuration
The server is configured primarily through environment variables. The flags `-p` and `-L` above are the only command-line flags. Everything else is in [[Install/Configuration]].
Now, open `http://localhost:3000` in your browser and you’ll be guided through the initial [[Space Manager]], once that’s all done, head to [[Getting Started]] to learn the basics.
# Upgrading
You can upgrade your SilverBullet install based on the version you’d like to run.
+14 -16
View File
@@ -5,6 +5,9 @@ references:
---
SilverBullet is primarily configured via environment variables. This page gives a comprehensive overview of all configuration options. You can set these ad-hoc when running the SilverBullet server, or e.g. in your [[Install/Docker|docker-compose file]].
> **note** Single-space vs. multi-space
> The environment variables below configure a **single-space** server (one folder, one space). A fresh install pointed at an empty folder instead runs the [[Space Manager|setup wizard]] and stores per-space settings in `spaces.json` — the variables marked _single-space only_ below don’t apply there. Setting any of them (or passing `--single`) selects single-space mode. See [[Space Manager#Boot modes]].
# General configuration
* `SB_INDEX_PAGE`: Sets the default page to load, defaults to `index`.
@@ -20,28 +23,22 @@ SilverBullet is primarily configured via environment variables. This page gives
* `SB_URL_PREFIX`: Host SilverBullet on a particular URL prefix, e.g. `SB_URL_PREFIX=/notes`
# Authentication
SilverBullet supports basic authentication for a single user.
> **note** Note
> These variables configure authentication for a **single-space** server. In [[Space Manager|multi-space]] mode, accounts live in `users.json` and access is per space, so setting `SB_USER` alongside a `spaces.json` is an error — see [[Authentication]].
* `SB_USER`: Sets single-user credentials, e.g. `SB_USER=pete:1234` allows you to login with username “pete” and password “1234”.
* `SB_AUTH_TOKEN`: Enables `Authorization: Bearer <token>` style authentication on the [[HTTP API]].
* `SB_USER` (single-space only): Sets single-user credentials, e.g. `SB_USER=pete:1234` allows you to login with username “pete” and password “1234”.
* `SB_AUTH_TOKEN` (single-space only): Enables `Authorization: Bearer <token>` style authentication on the [[HTTP API]]. In multi-space mode this is replaced by per-account [[Space Manager#API tokens|API tokens]].
* `SB_LOCKOUT_LIMIT`: Specifies the number of failed login attempt before locking the user out (for a `SB_LOCKOUT_TIME` specified amount of seconds), defaults to `10`
* `SB_LOCKOUT_TIME`: Specifies the amount of time (in seconds) a client will be blocked until attempting to log back in, defaults to `60`.
* `SB_REMEMBER_ME_HOURS`: Sets the session duration in hours when "Remember me" is checked during login, defaults to 7 days.
# Storage
SilverBullet supports storage backends for keeping your [[Space]] content. Right now the only supported backend is to use your local disk.
## Disk storage
This is the default and simplest backend to use: a folder on disk. It is configured as follows:
* `SB_FOLDER`: Sets the folder to expose. In the docker container, this defaults to `/space`.
# Run mode
* `SB_READ_ONLY` (==Experimental==): If you want to run the SilverBullet client and server in read-only mode (you get the full SilverBullet client, but all edit functionality and commands are disabled), you can do this by setting this environment variable to a non-empty value. Upon the server start a full space index will happen, after which all write operations will be disabled.
* `SB_READ_ONLY`: If you want to run the SilverBullet client and server in read-only mode (you get the full SilverBullet client, but all edit functionality and commands are disabled), you can do this by setting this environment variable to a non-empty value. Upon the server start a full space index will happen, after which all write operations will be disabled.
# Multi-space mode
* `SB_MULTI_SPACE`: Set to `1` to run the server in [[Multi-Space Mode]], serving any number of spaces (each with its own binding, auth, and settings in `spaces.json`) instead of a single space. Requires `SB_USER` for admin credentials; most other per-space `SB_*` variables (e.g. `SB_READ_ONLY`, `SB_NAME`) are ignored since those become per-space settings.
# Spaces and accounts
Hosting more than one space is is configured through `spaces.json`, `users.json`, and the admin UI rather than environment variables — see [[Space Manager]].
To force the classic single-space server on an empty folder, pass `--single` (or set any of the single-space `SB_*` variables above).
# Runtime API
* `SB_RUNTIME_API`: The [[Runtime API]] is enabled automatically when Chrome/Chromium is detected on the system. Set to `0` to explicitly disable. Not available in read-only mode.
@@ -51,7 +48,8 @@ This is the default and simplest backend to use: a folder on disk. It is configu
* `SB_CHROME_LOG_CONSOLE`: Forward the headless Chrome page’s `console.*` output to the server log (so you can see what the runtime is doing). Enabled by default; set to `0` to disable. The same log is also available via `/.runtime/logs` (e.g. `sb logs`).
# Security
SilverBullet enables plugs to run shell commands. This is potentially unsafe. If you don’t need this, you can disable this functionality:
> **note** Note
> These variables configure authentication for a **single-space** server. In [[Space Manager|multi-space]] mode, these options are enabled at a per-space level from the UI
* `SB_SHELL_BACKEND`: Enable/disable running of shell commands from plugs, defaults to `local` (enabled), set to `off` to disable. It is only enabled when using a local folder for [[#Storage]].
* `SB_SHELL_WHITELIST`: Allow only a specific list of shell commands (just the first command name, not arguments). When not set, allows all shell commands. Example: `SB_SHELL_WHITELIST="git pandoc"`
+3 -6
View File
@@ -4,10 +4,9 @@ references:
- Dockerfile
- docker-entrypoint.sh
---
Docker is a convenient and secure way to install server applications either locally or on a server you control.
[Docker](https://www.docker.com/) is a convenient and secure way to install server applications either locally or on a server you control. If you don’t have docker already running on your machine and are macOS user, consider giving [OrbStack](https://orbstack.dev/) a try — it’s a super nice docker experience.
Conveniently, SilverBullet is published as a [docker image on GHCR](https://github.com/silverbulletmd/silverbullet/pkgs/container/silverbullet). The image comes in two flavors:
Conveniently, SilverBullet is published as a [docker image on GHCR](https://github.com/silverbulletmd/silverbullet/pkgs/container/silverbullet). The image comes in a few flavors:
* 64-bit Intel
* 64-bit ARM (e.g. for Raspberry Pis and Apple Silicon macs)
@@ -17,14 +16,13 @@ Conveniently, SilverBullet is published as a [docker image on GHCR](https://gith
> To access SilverBullet outside of `localhost` you will need to set up [[TLS]].
# Release channels
Every release version of SilverBullet is tagged with its version number, but there are two release channels you can use (they automatically update):
Every release version of SilverBullet is tagged with its version number, but there are two release channels you can use:
* `:latest` always points to the latest _release_
* `:v2` always points to the latest _edge build_ (the last commit to `main`), use this if you want to live on the bleeding edge.
# Container
* The container binds to port `3000`, so be sure to port-map that, e.g. via `-p 3000:3000` (note: the first `3000` is the external port)
* By default SilverBullet runs _unauthenticated_, this is not safe at it allows anybody on your network to access your instance freely. Therefore, in a docker setup **always** set the `SB_USER=username:password` environment variable (see below).
* The container uses whatever is volume-mapped to `/space` as the space root folder. You can connect a docker volume, or a host folder to this, e.g. `-v /home/myuser/space:/space`
* SilverBullet will detect the UNIX owner (UID and GID) of the folder mapped into `/space` and run the server process with the same UID and GID so that permissions will just magically work. If you’d like to override this UID, set the `PUID` and `PGID` environment variables (see [[Install/Configuration]] for details).
* The Docker image is based on [Alpine](https://alpinelinux.org/). If you'd like to install additional packages into it, see [[#Installing additional packages]] below.
@@ -89,7 +87,6 @@ docker run -d --restart unless-stopped \
--name silverbullet \
-p 3000:3000 \
-v ./space:/space \
-e SB_USER=user:password \
ghcr.io/silverbulletmd/silverbullet:latest
```
-63
View File
@@ -1,63 +0,0 @@
---
tags: maturity/beta
references:
- bin/silverbullet/src/multi.rs
- server/src/multi/config.rs
- server/src/multi/validate.rs
- server/src/multi/dispatch.rs
- server/src/multi/admin_api.rs
- server/src/auth/cookie.rs
---
Multi-space mode lets a single SilverBullet server host any number of [[Space|spaces]], each with its own URL, authentication, and configuration, replacing a fleet of separate server processes with one process, one config file, and one admin UI.
# Enabling
Multi-Space is a server wide mode that is disabled by default it. By setting the `SB_MULTI_SPACE=1` you enable it. In this mode setting up SB_USER-bsed authentication (used for the admin account) is mandatory.
For instance:
```shell
SB_MULTI_SPACE=1 SB_USER=admin:s3cret silverbullet /var/lib/silverbullet
```
Notes:
* `SB_USER` is **required**: it becomes the admin credential for the management UI (and the default credential for spaces using `inherit` auth).
* The folder passed in holds `spaces.json` (all space configs), the admin auth state, and, potentially the space folders themselves under `spaces/` (although folders outside this folder can be configured as well).
* `SB_HOSTNAME`/`SB_PORT` configure the main listener. Space-level variables like `SB_READ_ONLY` or `SB_NAME` are ignored in this mode: those settings live per space.
On first start no spaces exist: visiting `/` redirects to the admin UI at `/.admin/`, where you log in with the `SB_USER` credentials and create your first space.
# Bindings
Each space is reachable one of two ways:
* **URL prefix**: e.g. `/work` on the main listener. The prefix must contain at least one path segment (a bare `/` is not allowed) and prefixes must not overlap (`/work` and `/work/sub` cannot coexist); prefixes starting with `/.` are reserved.
* **Hostname**: e.g. `notes.example.com`, matched on the `Host` header of the main listener. Point wildcard DNS or per-host reverse-proxy rules at the server.
# Per-space authentication
Every space has an auth mode:
* **inherit** (default): the space accepts the admin credentials. Because it inherits the full admin credential set, it also accepts the admin `SB_AUTH_TOKEN` as a bearer token for API access.
* **custom**: a space-specific username and password. Passwords are stored as hashes in `spaces.json`. There is no password recovery, just set a new password from the admin UI if lost.
* **none**: an open space, e.g. a public read-only wiki (be sure to enabled “read only” mode for these).
Session cookies are scoped per space, so logging into one space never affects another, even on the same hostname.
# The spaces.json format
`spaces.json` maps a generated ID to each space's configuration. It is managed by the admin UI, but hand-editing is fine while the server is stopped (changes on disk are read at startup). All single-space server settings have per-space equivalents: `readOnly`, `shell`, `runtimeApi` (off by default here), `indexPage`, `description`, `themeColor`, `headHtml`, `spaceIgnore`, `logPush`.
```json
{
"8b1c9e4e-…": {
"name": "Work notes",
"folder": "spaces/8b1c9e4e-…",
"binding": { "prefix": "/work" },
"auth": { "mode": "inherit" },
"readOnly": false
}
}
```
Deleting a space from the admin UI removes it from this file only, files on disk are never deleted.
# Notes and limitations
* Multi-space mode always requires admin authentication, there is no open variant.
* Spaces share one OS process and user: this mode is built for a household/team of trusted spaces, not hostile multi-tenancy.
* The runtime API (`runtimeApi`) launches one headless Chrome per enabled space, lazily, it is off by default.
+1 -3
View File
@@ -27,7 +27,6 @@ ${query[[
order by f.awesomeness desc
select templates.featureItem(f)
]]}
_(The template generating the feature bullet items can be found in [[^Library/Website Templates]])_
Neat huh? A few more use cases.
@@ -60,8 +59,7 @@ Want to see even more? Here is a whole [playlist with instruction videos](https:
# [[Install]]
As mentioned, SilverBullet is a [[Self Hosted]] web application. This is great if you care about [[Data Sovereignty]], but it does mean you need to [[Install]] it on a server yourself. Perhaps you do this on a Raspberry Pi you didn’t have a use for, or a VPS somewhere in the cloud. SilverBullet is distributed as a single self-contained server [[Install/Binary]] or [[Install/Docker]] container.
> **note** Note
> Alternatively, there is now also a [desktop edition](https://silverbullet.plus) named “SilverBullet+“ that you may want to try.
Want a **pure desktop app experience**? Give [SilverBullet+](https://silverbullet.plus) a try.
While this is a bit more complicated to set up than simply downloading desktop app or signing up for an account with some online service, self hosting is a path to both [[Data Sovereignty]] and to access your content from any device with a modern [[Browser]].
+102
View File
@@ -0,0 +1,102 @@
---
references:
- bin/silverbullet/src/boot.rs
- server/src/multi/setup.rs
- server/src/multi/setup_api.rs
- server/src/multi/users.rs
- server/src/multi/config.rs
- server/src/multi/admin_api.rs
- server/src/multi/access.rs
- server/src/multi/space_index.rs
---
A single SilverBullet server can host any number of [[Space|spaces]] — each with its own URL, access rules, and configuration — managed a web-based management UI called _Space Manager_.
# Setup wizard
When a server boots with an empty data folder it will run in set mode. Setup mode has two steps:
1. **Account creation**: creates the first administrator account.
2. **Space creation**: creates your first space.
Once finished, the server writes `users.json` and `spaces.json` and redirects you to your newly created space. To return to the space manager, simply open the `/.spaces` URL.
# Accounts
Each account has a username, password, admin flag and any number of API tokens.
* **Admins** can reach the admin UI and manage spaces, accounts, and tokens. They can also log into *every* space.
* **Non-admin accounts** are ordinary users: they can log into any space they are a member of (see [[#Access]]).
There is no self-service signup. Admins create accounts. There is no password recovery either, an admin sets a new password from the _Users_ tab. Fancier features like SSO integration etc may be implemented later.
# Spaces
Spaces have a name and point to a folder where its content is kept. By default this will be inside the SilverBullet data folder, but you can pick any folder you like.
## Bindings
Each space is reachable one of two ways:
* **URL prefix**: e.g. `/work`. A bare `/` binds a space at the root (allowed once). Prefixes must not overlap (`/work` and `/work/sub` can’t coexist, nor can two spaces both bind `/`).
* **Hostname**: e.g. `notes.example.com`, matched on the `Host` header of the main listener. Point wildcard DNS or per-host reverse-proxy rules at the server.
## Access
Each space controls who can read and write it through two fields:
* **`public`** — when true, no login is required. Anyone who can reach the URL can read *and edit* the space, so combine it with `readOnly` for a public wiki, or use it only behind an [[Authentication Proxy]]. When false (the default), the space requires a login.
* **`members`** — the accounts allowed to log into a non-public space. Admins are implicitly members of every space and don’t need listing.
# Space index
When no space is bound to the server root (`/`), opening `/` redirects to `/.spaces` instead of opening a space. Any account can log in there. Ordinary accounts see public spaces and spaces where they are members; administrators see every space, plus the admin screens covered in [[#Admin UI]].
# Boot modes
On startup the server inspects the data folder, the `--single` flag, and legacy `SB_*` environment variables, then picks its run mode.
Detection rules:
1. **`spaces.json` present -> multi-space.** The folder is a configured multi-space server.
2. **`--single` command line flag -> single-space.** Forces single space mode. `silverbullet --single ./new-dir` gives you an instant single space, unauthenticated (unless `SB_USER` is set).
3. **A `SB_*` variable is set -> single-space.** Any of `SB_USER`, `SB_AUTH_TOKEN`, `SB_READ_ONLY`, `SB_NAME`, `SB_INDEX_PAGE`, `SB_URL_PREFIX`, and friends selects single-space mode, so existing deployments keep working untouched.
4. **The folder is non-empty -> single-space.** An existing notes folder is served as a single space, exactly as before.
5. **Empty folder, no flags, no legacy env -> setup wizard.** A brand-new server — or a server pointed at a folder that hasn’t been created yet — puts up the [[#Setup wizard]].
# Programmatic setup
You can provision a server without the browser wizard. Both paths run the same logic and refuse to run twice (once `users.json` exists).
**CLI `setup` subcommand**:
```shell
silverbullet setup /var/lib/silverbullet \
--admin admin:s3cretpw \
--space "Notes" --at / --space-folder spaces/notes
```
* `--admin user:pass` (required) creates the admin account.
* `--space NAME` creates a first space (omit to create none).
* `--at` is its binding (`/` for the root, or a prefix like `/notes`; default `/`).
* `--space-folder` is where its files live (default `spaces/<id>`).
**HTTP setup API**: while a server is in setup mode, `POST /.setup/api/complete` accepts the same payload the wizard sends:
```json
{
"adminUsername": "admin",
"adminPassword": "s3cretpw",
"space": { "name": "Notes", "prefix": "/", "folder": "" }
}
```
`GET /.setup/api/status` reports the server's absolute data root, which the wizard uses to prepopulate the folder field. On success the server hot-swaps into the multi-space stack, just like the wizard.
# Migrating a single-space server to accounts
To convert an existing [[#Single-space mode]] server (one folder of notes, configured by `SB_USER` etc.) into an account-managed space:
1. Stop the server.
2. Start it pointed at a **fresh, empty folder** (with none of the legacy `SB_*` variables set) so it boots into the [[#Setup wizard]].
3. In the wizard, create your admin account. On the space step, tick **“Use an existing folder on this server”** and point it at your existing notes folder (an absolute path, or one relative to the new server root).
4. Finish. Your notes are now served as a space, with accounts and the admin UI in front.
Nothing in your old notes folder is modified beyond seeding an index page if one is missing.
# Single-space mode
Single-space mode is the “classic” SilverBullet server: one folder, one space, configured entirely by environment variables, with no `spaces.json`, `users.json`, nor admin UI. Pick it with `--single`, or simply by pointing the server at a folder that already has content (or by setting any legacy `SB_*` variable). See [[Authentication#Single-space mode]] for its authentication options and [[Install/Configuration]] for the full environment-variable surface. If the target folder doesn’t exist yet, the server creates it and serves an empty space.
# Notes and limitations
* Spaces share one OS process and user. This mode is built for a household or team of trusted spaces, not hostile multi-tenancy.
* Authentication is shared across the server, while authorization remains per space. Password changes and account deletion revoke that user's sessions immediately; membership and admin-role changes also take effect on the next request.
* The runtime API (`runtimeApi`) launches one headless Chrome per enabled space, lazily; it is off by default.
+3 -3
View File
@@ -8,10 +8,10 @@ description: Rudamentary Git integration
author: Zef Hemel
uri: https://github.com/zefhemel/silverbullet-libraries/blob/main/Git.md
---
name: Mermaid diagrams
name: Diagrams
author: Zef Hemel
description: Mermaid diagram support
uri: https://github.com/silverbulletmd/silverbullet-mermaid/blob/main/PLUG.md
description: Support or (mermaid) diagrams in Sivlerbullet
uri: https://github.com/silverbulletmd/silverbullet-diagram/blob/main/Mermaid.md
---
name: Excalidraw diagrams
author: Logesh