Portainer Templates logo

Portainer Templates

SilverBullet SilverBullet

Container

DocumentsProductivityWiki

Notes app for Markdown pages you can program, with two-way links, tasks, queries over everything you've written and Lua scripting for your own commands and widgets. Source: https://github.com/silverbulletmd/silverbullet

Image details

Architecture: amd64, arm64, arm/v7
Image size: 38 MB
User: silverbulletmd

Source details

Stars: 6k
Forks: 516
Language: TypeScript
License: MIT
Updated: 6 hours ago

Configuration

Type
Container
Platform
linux
Image
ghcr.io/silverbulletmd/silverbullet:latest-slim
Ports
3300:3000/tcp
Volumes
/data
Restart
unless-stopped

Notes

Open http://<your-host>:3300 and the setup wizard asks for an admin account, then your first space (at /notes by default). There's no setup code, so whoever gets there first owns the server - do it straight after deploying, and from the address you'll actually use, since the admin dashboard always sends you back there (change it under Admin --> Server). Over plain http on anything but localhost it runs online-only, so no offline use, local encryption or single sign-on. Put it behind an HTTPS proxy to get those back. Accounts, settings and every page (as plain Markdown files) live in the volume. This is the slim image, so if you want the Runtime API, which needs Chromium, use the latest tag instead. Docs: docs.silverbullet.md

Standalone Install

Select an install method, to see config/commands for deploying SilverBullet

Installation method

Install on Portainer

Import all app templates into your Portainer instance, for easy 1-click deploys

  1. Ensure both Docker and Portainer are installed, and up-to-date
  2. Log into your Portainer web UI
  3. Under Settings → App Templates, paste the below URL
  4. Head to Home → App Templates, and the list of apps will show up
  5. Select SilverBullet, fill in any config options, and hit Deploy

Template Import URL

https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json
Show Me demo

More install options in our documentation, or see silverbulletmd/silverbullet for app-specific guidance.

GitHub Repo stars Docker Pulls GitHub Downloads (all assets, all releases) GitHub contributors Ask DeepWiki

SilverBullet

SilverBullet is a Programmable, Private, Browser-based, Open Source, Self Hosted, Personal Knowledge Database — a fancy term for a "notes app on steroids".
Yowza! That surely is a lot of adjectives to describe a browser-based Markdown editor programmable with Lua.
Let’s get more specific.
SilverBullet combines a clean live-preview editor with wiki-style linking, a built-in database and query language, and a fully integrated Space Lua scripting environment, turning your notes into a programmable system that grows with you.
In SilverBullet you keep your content as a collection of Markdown Pages (called a Space). You navigate your space using the Page Picker like a traditional notes app, or through Links like a wiki (except they are bi-directional).
If you are the writer type, you’ll appreciate SilverBullet as a clean Markdown editor with Live Preview. If you have more of an outliner personality, SilverBullet has Outlining tools for you. Productivity freak? Have a look at Tasks. More of a database person? You will appreciate Objects and Queries (SLIQ).
And if you are comfortable programming a little bit — now we’re really talking. You will love dynamically generating content with Space Lua (SilverBullet’s Lua dialect), or to use it to create custom Commands, Page Templates or Widgets.
You were told there’s no such thing as a silver bullet. You were told wrong.
Much more detail can be found on silverbullet.md

Installing SilverBullet

Check out the instructions.

Developing SilverBullet

SilverBullet's frontend ("client") is written in TypeScript and built on top of the excellent CodeMirror 6 editor component. Additional UI is built using Preact. ESBuild is used to build the frontend.
The server backend is written in Rust (a Cargo workspace). It serves the pre-built client bundle, the file/space HTTP API, authentication, and a headless-Chrome runtime for server-side Lua.

Code structure

  • bin/silverbullet/: The standalone silverbullet server binary (Rust) (this is the one you generally run)
  • bin/sb/: The sb CLI client (Rust)
  • bin/plug-compile.ts: the plug compiler
  • client/: The SilverBullet client (browser, TypeScript)
  • server/: The SilverBullet server library (Rust): HTTP router, handlers, auth, runtime seam
  • server-common/: Shared Rust crate (space primitives, shared types)
  • server-runtime-chrome/: Headless-Chrome runtime backend (Rust)
  • plugs: Set of built-in plugs (TypeScript) that are distributed with SilverBullet
  • libraries: A set of libraries (space scripts, page templates, slash templates) distributed with SilverBullet (Space Lua)
  • plug-api/: Useful APIs for use in plugs and published to NPM
lib/: Useful libraries to be used in plugs syscalls/: TypeScript wrappers around syscalls types/: Various (client) types that can be references from plugs
  • scripts/: Useful scripts
  • docs/: documentation (published as docs.silverbullet.md and bundled as Desktop's Help)

Requirements

  • Node.js 24+ and npm 10+: Used to build the frontend (client) and plugs
  • Rust (stable, via rustup): Used to build the server

The project includes .nvmrc and .node-version files. If you use nvm
or another Node version manager, it will automatically use the correct Node.js version:
nvm use  # If using nvm

First, install dependencies:
make setup

To create a (release) build:
make

This will produce silverbullet and cli binaries in ./target/release/, run ./target/release/silverbullet to run the server.

Development workflow

SilverBullet has two halves you rebuild independently:
  • The client (TypeScript: client/) is built by ESBuild into client_bundle/, which the server then serves.
  • The server (Rust: server/, server-common/, server-runtime-chrome/, bin/silverbullet/) is a compiled binary.

Run the server in development with cargo run. A debug build serves the client bundle live from client_bundle/ on disk (a release build embeds it instead):
npm run build
cargo run <PATH-TO-YOUR-DATA-FOLDER>

When you change only the client (TypeScript in client/): you do not need to restart the server. Rebuild just the client bundle and reload the page in your browser — the debug server serves the freshly-built bundle straight from disk:
npm run build

To build a self-contained release binary (with the client bundle embedded), and run it:
make
./target/release/silverbullet <PATH-TO-YOUR-DATA-FOLDER>

Useful development tasks

# Clean all generated files
make clean
# Typecheck and lint all code
make check
# Format all code
make fmt
# Run all tests
make test
# Run benchmarks
make bench

Build a docker container

Note, you do not need Node.js nor Rust locally installed for this to work:
docker build -t silverbullet .

To run:
docker run -p 3000:3000 -v <PATH-TO-YOUR-DATA-FOLDER>:/data silverbullet

Serve SilverBullet on your own domain behind Caddy, Nginx or Traefik. Fill in your domain and copy the result. It's a starting point, some apps need their own base URL or extra headers set too.

Proxying silverbullet.example.com to http://silverbullet:3000

Add this to your Caddyfile

silverbullet.example.com {
	reverse_proxy http://silverbullet:3000
}

Check the logs first

Nine times out of ten the logs tell you exactly what went wrong.

  • In Portainer, go to Containers, click the container, then Logs. Or run docker logs silverbullet
  • Exit codes help too: 137 means killed, usually out of memory. 126 or 127 means the command inside the image is broken.

Port already in use

If deployment fails with "Bind for 0.0.0.0:3300 failed: port is already allocated", something else on your server is using that port.

  • Find what's using it: sudo ss -tlnp | grep :3300
  • Stop the other service, or pick a different host port. In 3300:3000 only the left number is yours to change, the right one belongs to the app.

Running but the page won't load

The container is up but nothing appears in your browser.

  • Use your server's real IP: http://your-server-ip:3300. The 0.0.0.0 link Portainer shows isn't a real address.
  • Give it a minute after first deploy, silverbullet can take a while to initialise.
  • Make sure your firewall allows the port, e.g. sudo ufw allow 3300

Image won't pull

Test the pull directly on the host: docker pull ghcr.io/silverbulletmd/silverbullet:latest-slim

  • "manifest unknown" means the tag no longer exists.
  • "toomanyrequests" is the Docker Hub rate limit. Log in with docker login to raise it.
  • "no space left on device" means a full disk. Reclaim space with docker system prune

"exec format error"

This means the image was built for a different CPU architecture than your server.

  • This image supports: amd64, arm64, arm/v7
  • Check yours with uname -m: x86_64 is amd64, aarch64 is arm64. Raspberry Pi and other ARM boards are the usual culprits.

Container keeps restarting

The unless-stopped restart policy relaunches the app after every crash, so the real error can scroll past.

  • Check the logs right after a restart, the last few lines before it died are the useful ones.
  • Get the exit code with docker inspect silverbullet --format '{{.State.ExitCode}}'
  • Still stuck? Redeploy once with the restart policy set to no so the failure stays visible.

Raise an issue

Found something which isn't working as it should? Here's how to report it.

A single container

SilverBullet runs as one container, the simplest kind of app here. Just the one image to pull and nothing else wired up alongside it.

The app image

An image is the app packed up ready to go, everything SilverBullet needs bundled into one download. This template pulls ghcr.io/silverbulletmd/silverbullet:latest-slim, which Docker fetches once (about 38 MB) and then starts your own copy from.

Where the image comes from

Docker pulls its images from registries, public libraries of ready-built apps. SilverBullet's comes from the GitHub Container Registry, published by silverbulletmd.

Version tags

The bit after the colon in the image name is the version tag. This one pins latest-slim, so every redeploy gives you that exact build until you bump it yourself.

Which machines it runs on

Every image is built for particular CPU types. This one ships for amd64, arm64, arm/v7, so it runs on both regular x86 servers and ARM boards like a Raspberry Pi.

Ports

A port is the door the app answers on. A mapping like 3300:3000 means it's reachable on port 3300 of your server, where the left number is yours to change and the right one belongs to the app. Once it's running, open http://your-server-ip:3300 in a browser. It opens:

  • 3300:3000, likely the web interface

Volumes

A volume is where SilverBullet keeps its files so they survive an update or a restart. Without one, anything it saves would sit inside the container and vanish the moment it's recreated. This template mounts:

  • /data as a volume Docker manages for you

Restart policy

The restart policy here is unless-stopped, so Docker restarts SilverBullet after a crash or reboot, but leaves it off when you stop it on purpose. You can change this on the deploy screen. The choices are no (never restart), on-failure (only after a crash), unless-stopped (restart unless you stop it), and always (bring it back no matter what).

Networking

Nothing custom is set, so SilverBullet sits on Docker's default bridge network: its own private space that reaches the outside world only through the ports it publishes.

Container name

Once it's deployed, Portainer names the container silverbullet. That's what you'll spot in the containers list and use in commands like docker logs silverbullet.

Platform

The platform is linux, the kind of system the container is built to run on. Docker and Portainer handle this on a normal Linux server.

Open source license

SilverBullet is open source, released under the MIT license. In plain terms the code is out in the open, so you're free to run it and change it to fit what you need.

Portainer app templates

Zooming out, this whole page comes from a Portainer app template: a short recipe telling Portainer how to set SilverBullet up. Add the template list to Portainer once, then deploying SilverBullet is a click rather than a wall of config.