English
Get started

← All templates · Notes and wikis

Deploy Trilium Notes in one click

A hierarchical knowledge base for large collections of personal notes

A self-hosted alternative to Notion, Evernote, and Obsidian.

What is Trilium Notes?

Trilium Notes is a free, open-source note-taking app built for large personal knowledge bases, an alternative to Notion, Evernote and Obsidian for people who want their notes on their own server. Notes form a tree as deep as you like, and one note can sit in several places at once. Besides rich text with tables, images and math, a note can be code, an Excalidraw canvas, a mind map, a geo map or a relation map, and attributes and scripts turn notes into small tools. Every note keeps its revisions, and full-text search finds it again.

The server is almost the same app in the browser, with a touch-friendly view for phones, and the desktop apps for Windows, macOS and Linux sync with it. Protected notes are encrypted with your password, a note can be shared publicly by a link, and a web clipper saves pages from the browser. This template makes a new, empty knowledge base with the password given before Trilium answers anyone. The catch: Trilium is for one person, with one password and no accounts for others, and it has no official mobile app.

Hosting Trilium Notes on Pethost

  1. You sign in to Pethost with a passkey, GitHub or Google. No machine yet? You pick a plan, and the link waits until it is ready.
  2. New project opens at Trilium Notes. You fill in what it asks for and click Create project: Password.
  3. In a minute or two Trilium Notes is live at its own address with HTTPS. Its secrets are made at random, and its data is in the nightly backup.
  4. It is a project like any other: you or your agent can change it, roll it back or restore it.

Questions about Trilium Notes

Is Trilium Notes free?

Yes. Trilium is open source under the AGPL-3.0 license and has no paid tier: its server, desktop apps and sync are all free.

What is TriliumNext?

The community project that carried Trilium on. Trilium’s original developer, Zadam, handed it the Trilium repository, and it now publishes the app as Trilium Notes again. A database from the original Trilium opens in it without special steps.

Trilium vs Obsidian: which one to choose?

Obsidian keeps Markdown files in a folder on each device, is closed source and sells its sync. Trilium keeps notes in a database on your server, is open source and syncs its desktop apps with your server for free. Obsidian’s strengths are plugins and plain files; Trilium’s are the note tree, cloning and its many note types.

Is there a Trilium app for phones?

There is no official one. The server has a mobile interface for phone browsers, and community apps exist: TriliumDroid and Pocket Trilium for Android, and Trinote for iOS.

Can I import my notes from Evernote or Markdown?

Yes. Trilium imports Evernote’s ENEX exports and Markdown files, and exports notes as Markdown or HTML, so your notes can leave as easily as they came.

How much memory and disk does Trilium Notes need?

Trilium is light: about 100 MB of memory; its database grows with your notes and attachments, and its own daily, weekly and monthly backups sit beside it. On Pethost the Starter plan is enough for it, with room for other apps beside it.

Trilium Notes Docker Compose file

The template is this compose.yaml and the variables written into the project’s .env as it is created. Pethost runs the file as it is written.

Containers: trilium (triliumnext/trilium:v0.106.1).

Volumes, in the nightly backup: data.

services:
  trilium:
    image: triliumnext/trilium:v0.106.1
    restart: unless-stopped
    environment:
      ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      # Requests come through the proxy: the client's own address is the one it forwards, so that
      # a stranger's wrong passwords do not lock everyone out of signing in.
      TRILIUM_NETWORK_TRUSTEDREVERSEPROXY: uniquelocal
    # A new Trilium offers its setup to whoever opens it first, then asks them for the password.
    # So while it has no password, it runs on port 8081, which nobody reaches: a new knowledge base
    # is made there with the password given, and only then does Trilium answer on 8080.
    command:
      - sh
      - -c
      - |
        set -e
        if ! node -e '
          const { DatabaseSync } = require("node:sqlite");
          const db = new DatabaseSync(process.env.TRILIUM_DATA_DIR + "/document.db", { readOnly: true });
          const row = db.prepare("select value from options where name = ?").get("passwordVerificationHash");
          process.exit(row?.value ? 0 : 1);
        ' 2>/dev/null; then
          TRILIUM_PORT=8081 node ./main.mjs &
          setup=$$!
          node -e '
            const base = "http://127.0.0.1:8081";
            const setUp = async () => {
              const status = await fetch(base + "/api/setup/status").then((r) => r.json());
              if (!status.isInitialized) {
                const made = await fetch(base + "/api/setup/new-document?skipDemoDb", {
                  method: "POST",
                  headers: { "content-type": "application/json" },
                  body: JSON.stringify({ locale: "en" })
                });
                if (!made.ok) throw new Error("new-document: " + made.status + " " + (await made.text()));
              }
              const password = process.env.ADMIN_PASSWORD;
              const set = await fetch(base + "/set-password", {
                method: "POST",
                body: new URLSearchParams({ password1: password, password2: password }),
                redirect: "manual"
              });
              if (set.status !== 302) throw new Error("set-password: " + set.status + " " + (await set.text()));
            };
            (async () => {
              let failure;
              for (let i = 0; i < 180; i++) {
                try {
                  return await setUp();
                } catch (error) {
                  failure = error;
                  await new Promise((done) => setTimeout(done, 1000));
                }
              }
              console.error(failure);
              process.exit(1);
            })();
          '
          kill $$setup
          wait $$setup || true
        fi
        chown -R node:node /home/node
        exec su -c "node ./main.mjs" node
    volumes:
      - data:/home/node/trilium-data

volumes:
  data:

More in Notes and wikis