Trilium Notes Deployment & Usage Guide
1. Prerequisites
System Requirements
- OS: Linux (x64/ARM64), macOS (10.15+), Windows (10+)
- Node.js: 18.x LTS or higher (for building from source)
- npm: 8.x+ or yarn
- Git: For cloning repository
- Docker: 20.10+ and Docker Compose v2 (for containerized deployment)
- Build tools: Python 3, make, g++, and libssl-dev (for native module compilation on Linux)
Optional but Recommended
- Reverse proxy: Nginx or Caddy (for SSL termination in production)
- SSL certificate: Let's Encrypt or commercial certificate
- PM2: For process management in production server deployments
- Backup solution: Regular backups of data directory
2. Installation
Option A: Download Pre-built Binaries (Recommended for Desktop Users)
- Visit the latest release page
- Download the appropriate package for your OS:
- Windows:
Trilium-Next-windows-x64-<version>.zip - macOS:
Trilium-Next-mac-x64-<version>.ziporTrilium-Next-mac-arm64-<version>.zip - Linux:
Trilium-Next-linux-x64-<version>.tar.gzorTrilium-Next-linux-arm64-<version>.tar.gz
- Windows:
- Extract the archive
- Run the executable:
- Windows: Double-click
Trilium.exe - macOS: Double-click
Trilium.app(may need to right-click → Open due to Gatekeeper) - Linux: Run
./triliumfrom terminal
- Windows: Double-click
Option B: Docker Deployment (Recommended for Server)
# Pull the latest stable image
docker pull triliumnext/trilium:latest
# Run with persistent data storage
docker run -d \
--name trilium \
-p 8080:8080 \
-v /path/to/trilium-data:/home/node/trilium-data \
-e NODE_ENV=production \
-e TRILIUM_SECRET=$(openssl rand -base64 32) \
triliumnext/trilium:latest
Important: The /home/node/trilium-data volume must be persistent to retain your notes.
Option C: Build from Source
# Clone the repository
git clone https://github.com/TriliumNext/Trilium.git
cd Trilium
# Install dependencies (using npm)
npm ci
# Build the application
npm run build
# The built application will be in the `dist/` directory
Note: Building from source requires Node.js 18+ and may take 10-30 minutes depending on your system.
3. Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 8080 | HTTP server port |
DATA_DIR | ./data | Path to data directory (relative to working dir or absolute) |
NODE_ENV | production | Environment: production or development |
TRILIUM_SECRET | Random generated | Secret key for encryption and sessions (MUST be set in production) |
TRILIUM_DB | sqlite | Database type: sqlite (default) or mysql/postgres (experimental) |
TRILIUM_DB_PATH | $DATA_DIR/trilium.db | SQLite database path |
TRILIUM_SYNC_SERVER | - | URL of sync server for synchronization |
OPENAI_API_KEY | - | API key for AI features (optional) |
ANTHROPIC_API_KEY | - | API key for Claude AI (optional) |
TRILIUM_LOG_LEVEL | info | Logging level: debug, info, warn, error |
TRILIUM_HTTPS | false | Enable HTTPS (requires SSL certificates) |
TRILIUM_SSL_CERT | - | Path to SSL certificate file |
TRILIUM_SSL_KEY | - | Path to SSL private key file |
Setting Environment Variables
Docker:
docker run -d \
-e TRILIUM_SECRET=your-secret-key-here \
-e PORT=8080 \
-v ./data:/home/node/trilium-data \
triliumnext/trilium:latest
Direct Node.js:
export TRILIUM_SECRET=your-secret-key-here
export PORT=8080
npm start
Systemd Service (Linux server):
[Unit]
Description=Trilium Notes
After=network.target
[Service]
Type=simple
User=trilium
WorkingDirectory=/opt/trilium
Environment="TRILIUM_SECRET=your-secret-key-here"
Environment="PORT=8080"
Environment="DATA_DIR=/var/lib/trilium"
ExecStart=/usr/bin/node /opt/trilium/dist/server/server.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
Initial Setup
On first launch, Trilium will:
- Create the data directory (if it doesn't exist)
- Initialize the database
- Generate an admin user account
- Open the setup wizard at
http://localhost:8080
Important: Save the admin credentials shown during first setup. There is no password recovery mechanism.
4. Build & Run
Development Mode
# Install dependencies
npm ci
# Run in development mode with hot reload
npm run dev
# Or run server and client separately
npm run dev:server
npm run dev:client
The development server will be available at http://localhost:8080 with hot module replacement enabled.
Production Build
# Clean previous builds
npm run clean
# Build for production
npm run build
# Start the server
npm start
# or
node dist/server/server.js
Build Targets
The project uses a monorepo structure with multiple packages:
# Build all packages
npm run build
# Build specific package
npm run build --workspace=@triliumnext/commons
npm run build --workspace=apps/server
npm run build --workspace=apps/client
# Run tests
npm test
npm test --workspace=apps/server
5. Deployment
Docker Deployment (Production)
Create a docker-compose.yml:
version: '3.8'
services:
trilium:
image: triliumnext/trilium:latest
container_name: trilium
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./data:/home/node/trilium-data
- ./logs:/home/node/trilium-logs
environment:
- NODE_ENV=production
- TRILIUM_SECRET=${TRILIUM_SECRET:-change-me-in-production}
- PORT=8080
- TRILIUM_LOG_LEVEL=info
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Deploy with:
docker-compose up -d
Nginx Reverse Proxy with SSL
server {
listen 80;
server_name notes.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name notes.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/notes.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/notes.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_cache_bypass $http_upgrade;
proxy_read_timeout 3600s;
}
}
Self-Hosted Sync Server
Trilium supports self-hosted synchronization. Deploy the sync server separately:
# Clone sync server repository
git clone https://github.com/TriliumNext/trilium-sync.git
cd trilium-sync
# Configure environment variables (see sync server README)
cp .env.example .env
# Edit .env with your settings
# Build and run
npm ci
npm run build
npm start
Then configure your Trilium instance with TRILIUM_SYNC_SERVER environment variable pointing to your sync server.
Mobile Frontend
Trilium includes a touch-optimized mobile frontend. Access it via:
- Same URL as desktop, but with mobile-optimized UI
- Or configure a separate subdomain/mobile-specific path
No additional deployment needed - it's built into the same application.
6. Troubleshooting
Common Issues
1. Database is Locked
Symptoms: Error messages about database being locked or busy.
Solution:
# Check permissions on data directory
ls -la /path/to/trilium-data/
# Ensure correct ownership (if running as specific user)
chown -R trilium:trilium /path/to/trilium-data
# If using Docker, check volume permissions
docker exec trilium ls -la /home/node/trilium-data/