Docs / Self-Hosted Applications / Self-Hosting Trilium Notes Knowledge Base

Self-Hosting Trilium Notes Knowledge Base

By Admin · Mar 11, 2026 · Updated Apr 23, 2026 · 7 views · 4 min read

In this article, we'll walk through the complete process of working with trilium in a server environment. Understanding notes is essential for maintaining a reliable and performant infrastructure.

Prerequisites

  • A reverse proxy configured (Nginx or Traefik)
  • A registered domain name (for public-facing services)
  • Basic familiarity with the Linux command line
  • Root or sudo access to the server
  • A VPS running Ubuntu 22.04 or later (2GB+ RAM recommended)

Docker Compose Setup

The trilium configuration requires careful attention to resource limits and security settings. On a VPS with limited resources, it's important to tune these parameters according to your available RAM and CPU cores.


# docker-compose.yml
version: '3.8'
services:
  trilium:
    image: trilium/trilium:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - trilium_data:/data
      - trilium_config:/config
    environment:
      - TZ=UTC
      - PUID=1000
      - PGID=1000
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=trilium
      - POSTGRES_USER=trilium
      - POSTGRES_PASSWORD=changeme

volumes:
  trilium_data:
  trilium_config:
  db_data:

Each line in the configuration serves a specific purpose. The comments explain the reasoning behind each setting, making it easier to customize for your specific use case.

Initial Configuration

The default configuration works well for development environments, but production servers require additional tuning. Pay particular attention to connection limits, timeout values, and logging settings.


# Reverse proxy configuration
server {
    listen 443 ssl http2;
    server_name trilium.example.com;

    ssl_certificate /etc/letsencrypt/live/trilium.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/trilium.example.com/privkey.pem;

    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;
        proxy_buffering off;
        client_max_body_size 0;
    }
}

The configuration above sets the recommended values for a VPS with 2-4GB of RAM. Adjust the memory-related settings proportionally if your server has different specifications.

Reverse Proxy Integration

It's recommended to test this configuration in a staging environment before deploying to production. This helps identify potential compatibility issues and allows you to benchmark performance differences.


# docker-compose.yml
version: '3.8'
services:
  trilium:
    image: trilium/trilium:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - trilium_data:/data
      - trilium_config:/config
    environment:
      - TZ=UTC
      - PUID=1000
      - PGID=1000
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=trilium
      - POSTGRES_USER=trilium
      - POSTGRES_PASSWORD=changeme

volumes:
  trilium_data:
  trilium_config:
  db_data:

The configuration above sets the recommended values for a VPS with 2-4GB of RAM. Adjust the memory-related settings proportionally if your server has different specifications.

Data Persistence

When scaling this setup, consider vertical scaling (adding more RAM/CPU) first, as it's simpler to implement. Horizontal scaling adds complexity but may be necessary for high-traffic applications.


# Reverse proxy configuration
server {
    listen 443 ssl http2;
    server_name trilium.example.com;

    ssl_certificate /etc/letsencrypt/live/trilium.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/trilium.example.com/privkey.pem;

    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;
        proxy_buffering off;
        client_max_body_size 0;
    }
}

These commands should be run as root or with sudo privileges. If you're using a non-root user, prefix each command with sudo.

Security Implications

It's recommended to test this configuration in a staging environment before deploying to production. This helps identify potential compatibility issues and allows you to benchmark performance differences.

Common Issues and Solutions

  • Permission denied errors: Ensure files and directories have the correct ownership. Use chown -R to fix ownership and chmod for permissions.
  • Service won't start: Check the logs with journalctl -xe -u trilium. Common causes include port conflicts, missing configuration files, or insufficient permissions.

Next Steps

With trilium now set up and running, consider implementing monitoring to track performance metrics over time. Regularly review your configuration as your workload changes and scale resources accordingly.

Was this article helpful?