Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Trilium Ubuntu
GUIDEInstall Guides

How to Install Trilium Notes on Ubuntu 24.04 — Self-Hosted Personal Knowledge Base

23 min read

How to Install Trilium Notes on Ubuntu 24.04 — Self-Hosted Personal Knowledge Base

Your personal notes, research, and half-finished ideas are some of the most valuable data you own. Handing them to Notion, Evernote, or Google Keep means trusting a third party with your thinking — and betting that they stay in business, honor their privacy promises, and do not quietly change terms next quarter. Trilium Notes flips the relationship. You host it on your own VPS, the database sits on your disk, and the desktop client syncs back to a server you control. This guide walks through a production-ready Trilium deployment on Ubuntu 24.04 with Docker, a Nginx reverse proxy, Let's Encrypt TLS, and desktop client sync.

Need a reliable VPS first? Our Starter VPS plan comes with 2 vCPU, 4 GB RAM, and NVMe storage — more than enough for Trilium plus a few other self-hosted tools.

Table of Contents

  • What is Trilium Notes?
  • Why Self-Host Your Knowledge Base Instead of Using Notion or Evernote?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Install Docker
  • Step 3: Create the Persistent Data Volume
  • Step 4: Run the Trilium Server Container
  • Step 5: Verify the Installation
  • Step 6: Configure Nginx as a Reverse Proxy
  • Step 7: Enable TLS with Let's Encrypt
  • Step 8: Complete First-Time Setup in the Browser
  • Step 9: Install and Sync the Desktop Client
  • Step 10: Configure Automatic Backups
  • Hardening and Maintenance
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Trilium Notes?

    Trilium Notes is an open-source hierarchical note-taking application built for serious knowledge workers, researchers, and anyone who has outgrown flat-file markdown editors. Rather than a folder of .md files, Trilium stores everything in a single SQLite database and organizes notes as a tree — with the twist that any note can appear in multiple places (clones), and notes can link to each other both as children and as semantic relations.

    Under the hood Trilium is a Node.js server that exposes a web UI on port 8080 and a sync API that desktop clients connect to. The server persists notes, attachments, revisions, and backup snapshots under a single data directory controlled by the TRILIUM_DATA_DIR environment variable. This single-directory design makes backup, restore, and migration trivial — you copy one folder and the whole knowledge base travels with you.

    Trilium's feature set is unusually deep for a self-hosted notes app. You get a rich WYSIWYG editor with math support (KaTeX), code blocks with syntax highlighting, Excalidraw-style drawings, mermaid diagrams, file attachments, and a full-text search that indexes every note instantly. More advanced capabilities include relation maps (visualize links between notes), scripting (write JavaScript inside a note to query the database, build dashboards, or automate workflows), promoted attributes (turn notes into typed database rows), per-note encryption with client-side keys, and note revisions (automatic versioning of every edit). It is, effectively, a personal Notion that you own outright.

    The project by Zadam has been widely adopted for personal wikis, research vaults, journaling, project management, and second-brain systems. In 2024 the community forked active development into TriliumNext (still published under the original Docker image family), which continues shipping improvements while preserving compatibility with existing databases.

    Why Self-Host Your Knowledge Base Instead of Using Notion or Evernote?

    Handing your notes to a SaaS provider is convenient until it is not. Here is the honest case for self-hosting:

    • Your data is actually yours — With Notion, Evernote, or Google Keep, your notes live on servers you cannot audit, encrypted with keys you do not hold, under terms that can change at any time. With Trilium on your VPS, the SQLite file sits on your disk. You can inspect it, copy it, encrypt it, or delete it. No one else has a copy.
    • No subscription creep — Notion's Plus plan is USD 10/user/month. Evernote Personal is USD 14.99/month. Multiply by years. A Starter VPS at roughly EUR 7.99/month hosts Trilium plus a dozen other self-hosted tools, with no per-user fees and no quota meter.
    • No vendor lock-in — Trilium exports to HTML, Markdown, or a portable .zip of the entire tree. Your notes are not trapped in a proprietary cloud format. Migration away is a single command.
    • Works offline and on slow links — The desktop client holds a full local database. You can write 500 notes on a plane and sync them later. SaaS web apps degrade badly on poor connectivity.
    • Genuine privacy, not marketing privacy — Cloud providers regularly update privacy policies, train AI on user content, or respond to government requests. A Trilium instance on your VPS has none of that exposure. Per-note encryption adds a second layer even against a server compromise.
    • Performance that scales with your hardware — Notion becomes noticeably sluggish past a few thousand notes. Trilium's SQLite backend handles tens of thousands of notes on modest hardware without pagination or loading spinners.
    • Extensible by default — Scripting, custom CSS, import/export, REST API, and a stable data format mean you can bend Trilium to your workflow instead of waiting for a product team to ship a feature.

    Cost Comparison Over 3 Years

    ServiceMonthly Cost3-Year CostData OwnershipExport Quality
    Notion PlusUSD 10USD 360Cloud-onlyMarkdown (imperfect)
    Evernote PersonalUSD 14.99USD 539Cloud-onlyENEX (proprietary)
    Obsidian SyncUSD 10USD 360Local files + cloud syncNative Markdown
    Trilium on Starter VPSEUR 7.99EUR 180Full — your diskHTML / Markdown / ZIP
    The VPS hosts Trilium plus anything else you want to run.

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to your server
    • A registered domain name pointed at your VPS IP (for TLS)
    • At least 1 GB of RAM (2 GB recommended for comfortable multi-device sync)
    • 10 GB of free disk space (Trilium itself is tiny; attachments grow with use)
    Recommended Plan: Starter VPS
    >
    Trilium is lightweight, but a good foundation matters for reliability. Our Starter VPS is ideal:
    >
    - 2 vCPU cores
    - 4 GB RAM
    - 50 GB NVMe SSD
    - Unmetered bandwidth
    - From EUR 7.99/month
    >
    Plenty of headroom for Trilium plus Nginx, backups, and a handful of other small services.

    Connect to your server via SSH:

    bash
    ssh root@your-server-ip

    Point an A record for notes.yourdomain.com at your server's IP before proceeding. TLS issuance in Step 7 depends on DNS resolving correctly.

    Step 1: Update System Packages

    Refresh the package index and upgrade installed packages:

    bash
    sudo apt update && sudo apt upgrade -y

    If a new kernel was installed, reboot before continuing:

    bash
    sudo reboot

    Reconnect via SSH once the server is back up.

    Step 2: Install Docker

    Trilium ships an official Docker image, which is the cleanest way to run it on Ubuntu 24.04. Install Docker Engine from Docker's official apt repository.

    Install prerequisites:

    bash
    sudo apt install -y ca-certificates curl gnupg

    Add Docker's official GPG key and repository:

    bash
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc

    echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    Install Docker Engine:

    bash
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

    Verify Docker is running:

    bash
    sudo systemctl status docker

    Expected output includes Active: active (running).

    Step 3: Create the Persistent Data Volume

    Trilium stores its notes database, attachments, backups, and configuration in a single directory. We mount that directory from the host so container restarts and image upgrades never lose data.

    Create the host directory:

    bash
    sudo mkdir -p /var/lib/trilium-data
    sudo chown -R 1000:1000 /var/lib/trilium-data

    The 1000:1000 ownership matches the node user inside the official Trilium image. Getting this right prevents the permission errors that are the number one cause of failed first-time starts.

    Step 4: Run the Trilium Server Container

    Launch the trilium-server container with the data directory mounted and the TRILIUM_DATA_DIR environment variable pointed at it:

    bash
    sudo docker run -d \
      --name trilium \
      --restart unless-stopped \
      -p 127.0.0.1:8080:8080 \
      -v /var/lib/trilium-data:/home/node/trilium-data \
      -e TRILIUM_DATA_DIR=/home/node/trilium-data \
      -e TZ=UTC \
      zadam/trilium:latest

    What each flag does:

    • --name trilium — friendly name for future docker logs trilium and docker restart trilium.
    • --restart unless-stopped — container auto-starts on reboot and restarts on crash.
    • -p 127.0.0.1:8080:8080 — binds port 8080 to the loopback interface only. Nginx will front it; the world never talks to Trilium directly.
    • -v /var/lib/trilium-data:/home/node/trilium-data — persists the notes database on the host.
    • -e TRILIUM_DATA_DIR=/home/node/trilium-data — tells the Trilium process where to read and write data inside the container.
    • -e TZ=UTC — timestamps in note revisions and backups use UTC. Change if you prefer local time.
    Watch the first-boot logs to confirm Trilium initialized the database:

    bash
    sudo docker logs -f trilium

    Expected output (abbreviated):

    text
    Starting Trilium...
    App data path: /home/node/trilium-data
    DB not initialized, initializing...
    Schema version 228
    Listening on port 8080

    Press Ctrl+C to stop tailing the logs. The container keeps running.

    Step 5: Verify the Installation

    Confirm the container is healthy:

    bash
    sudo docker ps --filter name=trilium

    Expected output:

    text
    CONTAINER ID   IMAGE                  STATUS          PORTS                      NAMES
    a1b2c3d4e5f6   zadam/trilium:latest   Up 2 minutes    127.0.0.1:8080->8080/tcp   trilium

    Test the local endpoint responds:

    bash
    curl -I http://127.0.0.1:8080

    Expected output:

    text
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=utf-8

    Inspect the data directory to confirm Trilium is writing to it:

    bash
    sudo ls -la /var/lib/trilium-data

    You should see document.db, log/, backup/, and a config.ini file.

    Step 6: Configure Nginx as a Reverse Proxy

    Exposing a Node.js app directly on port 80 is fine in dev; in production Nginx handles TLS, compression, WebSocket upgrades, rate limiting, and graceful restarts. Trilium's sync protocol also uses WebSockets for live updates, so the proxy must pass the upgrade headers correctly.

    Install Nginx:

    bash
    sudo apt install -y nginx

    Create the site config:

    bash
    sudo tee /etc/nginx/sites-available/trilium > /dev/null <<'EOF'
    server {
        listen 80;
        server_name notes.yourdomain.com;

    # Trilium supports large attachments; lift the upload cap. client_max_body_size 250m;

    location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;

    # WebSocket support for live sync. proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

    proxy_read_timeout 600s; proxy_send_timeout 600s; } } EOF

    Replace notes.yourdomain.com with your actual hostname.

    Enable the site and reload:

    bash
    sudo ln -s /etc/nginx/sites-available/trilium /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx

    Open ports 80 and 443 on the firewall if UFW is active:

    bash
    sudo ufw allow 'Nginx Full'

    Visit http://notes.yourdomain.com in a browser. You should see the Trilium setup screen. Do not complete setup yet — finish TLS first.

    Step 7: Enable TLS with Let's Encrypt

    Install Certbot:

    bash
    sudo apt install -y certbot python3-certbot-nginx

    Issue a certificate and let Certbot rewrite the Nginx config for HTTPS:

    bash
    sudo certbot --nginx -d notes.yourdomain.com

    When prompted:

    • Enter an email address for expiry notifications.
    • Agree to the terms.
    • Choose option 2 to redirect all HTTP traffic to HTTPS.
    Certbot installs a cron job that renews certificates automatically. Verify it works:

    bash
    sudo certbot renew --dry-run

    Expected output ends with Congratulations, all simulated renewals succeeded.

    Reload Nginx to be safe:

    bash
    sudo systemctl reload nginx

    Your Trilium instance is now reachable at https://notes.yourdomain.com with a valid TLS certificate.

    Step 8: Complete First-Time Setup in the Browser

    Open https://notes.yourdomain.com and choose "New document" if this is a fresh install (choose "Sync from server" only if you are migrating an existing database).

    Set:

    • Username — for the web UI login
    • Password — strong, unique, stored in your password manager
    • Sync password — a separate credential used by desktop clients to authenticate their sync connection. Can be the same as the login password but does not have to be.
    Click Finish setup. Trilium creates the root tree, seeds a few example notes, and drops you into the editor.

    Create your first real note to confirm everything persists:

  • Click the + in the tree to add a child note.
  • Title it Hello Trilium.
  • Type a few lines.
  • Click away — Trilium autosaves every few seconds.
  • Reload the browser. The note should still be there.
  • Step 9: Install and Sync the Desktop Client

    The web UI is excellent, but the desktop client is faster, works offline, and gives you a system tray icon for quick capture.

    Download the client for your OS from the Trilium releases page. Builds are provided for Windows, macOS, and Linux (AppImage, deb, rpm).

    Install and launch it. On first start you will see two choices:

  • Set up local-only instance — creates a standalone database on your machine, no server.
  • Set up a sync instance — connects to your server and mirrors its database.
  • Choose sync instance and fill in:

    • Server address — https://notes.yourdomain.com
    • Username — your web UI username
    • Password — your sync password (not the web login password, if you chose different ones)
    Click Connect. The client pulls the full note tree, builds its local index, and lands on the same notes you saw in the browser. Edits now flow in both directions: edit in the browser on one machine, the tree updates in the desktop client within a second or two.

    Repeat on each device. You can connect as many desktops as you like to the same server — macbook, desktop, work laptop — and all of them stay in sync.

    Step 10: Configure Automatic Backups

    Trilium writes automatic nightly backups into /var/lib/trilium-data/backup/ inside the container (which maps to the same path on the host). These are full SQLite snapshots — restoring is a matter of stopping the container and replacing document.db.

    For off-server protection, sync the data directory to a remote location. A simple cron-based rsync works well:

    bash
    sudo tee /etc/cron.daily/trilium-backup > /dev/null <<'EOF'
    #!/bin/bash
    rsync -az --delete /var/lib/trilium-data/ backup-user@backup-host:/backups/trilium/
    EOF
    sudo chmod +x /etc/cron.daily/trilium-backup

    For encrypted, deduplicated backups, restic or borg are better choices and integrate cleanly with S3-compatible object storage.

    Test your backup workflow by restoring to a second VPS at least once. An untested backup is not a backup.

    Hardening and Maintenance

    Keep Trilium Updated

    Pull the latest image and recreate the container periodically:

    bash
    sudo docker pull zadam/trilium:latest
    sudo docker stop trilium
    sudo docker rm trilium
    

    Re-run the docker run command from Step 4.

    Because the data lives in a host volume, image upgrades never touch your notes.

    Restrict Access with Fail2Ban

    Install Fail2Ban to block brute-force attempts against the login form:

    bash
    sudo apt install -y fail2ban

    Default Nginx filters cover most attack shapes. For custom rules, add a jail referencing Trilium's Nginx access log.

    Per-Note Encryption

    In the web UI, right-click any note and choose Protect subtree. You will be prompted for a protection password (separate from login). Encrypted notes are ciphered inside the SQLite file and decrypted only in-memory in the client. Even a full server compromise cannot reveal their contents without the protection password.

    Resource Limits

    Trilium is frugal, but set a memory ceiling to be safe:

    bash
    sudo docker update --memory 1g --memory-swap 1g trilium

    Troubleshooting

    ProblemCauseSolution
    Container exits immediatelyData directory permissions wrongsudo chown -R 1000:1000 /var/lib/trilium-data && sudo docker restart trilium
    502 Bad Gateway from NginxTrilium container not running, or wrong portsudo docker ps; check logs with sudo docker logs trilium
    Desktop client cannot syncSync password wrong, or TLS certificate invalidRe-enter sync password; verify certificate in browser first
    Changes in browser do not appear in desktop clientWebSocket upgrade not proxiedConfirm proxy_set_header Upgrade and Connection "upgrade" lines in Nginx config
    Disk filling upBackup directory growing without boundRotate backups: find /var/lib/trilium-data/backup -name 'backup-*.db' -mtime +30 -delete
    Upload fails on large attachmentNginx client_max_body_size too lowRaise to 500m in the site config and reload Nginx
    Sync conflicts after restoring backupTwo instances divergedPick one as source of truth, run "Sync from server" on the other to overwrite local

    Viewing Logs

    Container logs:

    bash
    sudo docker logs -f trilium

    Nginx access and error logs:

    bash
    sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

    FAQ

    What are the minimum server requirements for Trilium Notes?

    Trilium is very lightweight. It runs comfortably on a VPS with 1 vCPU and 1 GB of RAM for a single user with a few thousand notes. For multi-device sync with large attachments (PDFs, images, videos) and frequent writes, 2 vCPU and 2 GB of RAM provide a noticeably smoother experience. Disk usage is dominated by attachments and revision history — plan for 10 GB to start and monitor growth. CPU is rarely the bottleneck; Trilium is I/O bound on the SQLite file, so NVMe storage matters more than clock speed.

    Is Trilium Notes still maintained?

    The original project by Zadam entered maintenance mode in 2024 after years of active development. The community forked the code as TriliumNext, which continues shipping features, security patches, and UI improvements. The Docker image used in this guide remains the canonical path and TriliumNext preserves full compatibility with existing databases. If you want the newest features, switch the image tag to triliumnext/notes:latest in the docker run command — the rest of the setup is unchanged.

    How does the desktop client sync with the server?

    The desktop client holds a local SQLite copy of your notes and syncs bidirectionally with the server over HTTPS. On first setup you enter the server URL, username, and sync password; the client pulls the full database. After that, each edit is queued locally and pushed to the server, while changes from other clients are pulled on a short polling interval plus WebSocket notifications for near-real-time updates. Offline edits are queued and synced the next time the client reaches the server. Conflicts (same note edited in two places simultaneously) are resolved by last-write-wins with the losing version kept in note revisions.

    Can I encrypt my notes end-to-end?

    Yes. Trilium supports per-note encryption with a user-supplied protection password. Encrypted notes (marked with a shield icon) are stored ciphered in the SQLite database and decrypted only in the client with your password — the server never sees plaintext. Combined with TLS on the sync channel, this gives genuinely end-to-end protection for sensitive notes like credentials, journal entries, or legal material. Unprotected notes are still stored on the server in readable form, so protect anything truly sensitive.

    How do I back up my Trilium database?

    Trilium writes automatic backups every day, week, and month into the backup/ subdirectory of the data folder. Full restoration is a matter of stopping the container, copying a backup-*.db file over document.db, and restarting. For off-server protection, sync the entire /var/lib/trilium-data directory to remote storage with rsync, restic, or borg on a daily cron schedule. You can also use the built-in Export function to produce a portable .zip archive of all notes in HTML or Markdown. Always test restores on a second VPS at least once before relying on them.

    Can multiple users share one Trilium instance?

    Trilium is designed as a single-user personal knowledge base — there is no multi-user permission model. For shared team wikis, look at BookStack or Outline, both of which are purpose-built for teams. You can, however, run multiple Trilium containers on the same VPS on different ports and domains, each with its own data volume — a reasonable setup for a family or small group where each person wants their own private notes base on shared infrastructure.

    How does Trilium compare to Obsidian, Logseq, or a wiki?

    Obsidian and Logseq are local-first markdown editors — your notes are .md files in a folder, and sync requires a third-party service (Obsidian Sync, iCloud, Syncthing) or paid plugin. Trilium is server-first with a SQLite backend, a hierarchical tree structure, relation maps, scripting, and a built-in web client. It trades the pure-markdown portability for a richer database-backed model. Compared to a traditional wiki like Wiki.js, Trilium is faster to capture into (no page-creation ceremony) and better for personal research, while Wiki.js shines for publishing structured documentation to a wider audience. Pick based on workflow: Obsidian for portable markdown, Wiki.js for team docs, Trilium for a deep personal second brain.

    Next Steps

    With Trilium running, here are useful directions to take your self-hosted knowledge stack further:

    • Install a team wiki alongside personal notes — BookStack is the companion piece when you need shared documentation that non-technical teammates can edit. Run it on the same VPS behind a second Nginx vhost.
    • Publish docs with Wiki.js — If some of your notes are destined for a public-facing documentation site, deploy Wiki.js and use Trilium's export to seed the initial content.
    • Add a team document editor with Outline — For collaborative real-time editing closer to the Notion experience, Outline pairs well with Trilium: personal thinking stays in Trilium, published team knowledge lives in Outline.
    • Connect an AI assistant — Point a local LLM at your Trilium export for natural-language search across your notes. Our Ollama install guide covers the model side.
    • Monitor the stack — Drop Uptime Kuma onto the same VPS and configure HTTPS checks against https://notes.yourdomain.com so you know the moment anything breaks.
    • Explore Trilium scripting — Open the user manual in the Trilium tree and read the scripting section. You can query the note database, build dashboards, and automate workflows using plain JavaScript inside a note. It is genuinely magical once you internalize it.

    Start with the right foundation.
    >
    A self-hosted knowledge base is only as reliable as the VPS under it. Our Starter plan gives you NVMe storage, DDoS protection, and 99.9% uptime — the things you want backing years of accumulated notes.
    >
    - 2 vCPU cores
    - 4 GB RAM
    - 50 GB NVMe SSD
    - Ubuntu 24.04 LTS ready
    - From EUR 7.99/month
    >
    Deploy Your Starter VPS Now

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket