The Quest for Fluid Notes: My Obsidian LiveSync Configuration and Triumphs

Overview

This document summarizes the setup, issues encountered, and resolutions implemented during the deployment of Obsidian Self-hosted LiveSync using Docker and CouchDB. Building a self-hosted sync solution provides complete data sovereignty while avoiding subscription costs.

Why Self-Host Obsidian Sync?

Advantages of Self-Hosting

Data Sovereignty: - Complete control over your notes and attachments - No third-party access to sensitive information - Compliance with personal/corporate data policies - Geographic control of data storage

Cost Savings: - Obsidian Sync: $8/month = $96/year - Self-hosted: One-time setup, minimal hosting costs - ROI: Breaks even in 2-3 months

Learning Opportunities: - Hands-on experience with Docker - Database management skills - Network configuration practice - Troubleshooting real-world systems

Flexibility: - Custom backup strategies - Unlimited storage (limited only by your server) - Integration with existing homelab infrastructure - Advanced configuration options

Setup Goals

Primary Objectives

  • ✅ Enable secure, efficient syncing of Obsidian vaults across devices
  • ✅ Use Dockerized CouchDB as the backend database
  • ✅ Implement End-to-End Encryption (E2EE) version 2 for data security
  • ✅ Handle multi-OS file system case sensitivity gracefully

Target Architecture

Devices (Windows/Linux/Android/iOS)
    ↓
Obsidian App + LiveSync Plugin
    ↓
HTTPS/Internet
    ↓
CouchDB (Docker Container)
    ├── Database: obsidian
    ├── Port: 5984
    └── Storage: Persistent volume

Initial Setup

Step 1: Deploy CouchDB with Docker

# docker-compose.yml
version: '3.8'

services:
  couchdb:
    image: couchdb:latest
    container_name: couchdb-for-obsidian
    restart: unless-stopped
    environment:
      - COUCHDB_USER=admin
      - COUCHDB_PASSWORD=your_secure_password_here
    volumes:
      - ./data:/opt/couchdb/data
      - ./config:/opt/couchdb/etc/local.d
    ports:
      - "5984:5984"
    networks:
      - obsidian-sync

networks:
  obsidian-sync:
    driver: bridge
# Deploy CouchDB
docker-compose up -d

# Verify it's running
docker ps | grep couchdb

# Check logs
docker logs -f couchdb-for-obsidian

Step 2: Create Obsidian Database

# Access CouchDB web interface
# Navigate to: http://<server-ip>:5984/_utils

# Login with credentials from docker-compose.yml
# Click "Create Database"
# Database name: obsidian
# Partitioned: No

Step 3: Install LiveSync Plugin in Obsidian

  1. Open Obsidian
  2. Settings → Community Plugins → Browse
  3. Search: “Self-hosted LiveSync”
  4. Install and Enable
  5. Configure plugin:
    • Remote Database URL: http://<server-ip>:5984/obsidian
    • Username: admin
    • Password: Your CouchDB password
    • Device name: laptop-primary (or descriptive name)

Key Issues & Resolutions

Issue 1: Missing Docker Compose

Problem: docker-compose command not found when managing Docker containers.

Symptoms:

$ docker-compose up -d
bash: docker-compose: command not found

Resolution:

# Install Docker Compose on Ubuntu
sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Set executable permissions
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker-compose --version

# Alternative: Use docker compose (V2 plugin)
docker compose version

Issue 2: CORS Configuration for CouchDB

Problem: Native fetch API failed with CORS error during LiveSync.

Error Message:

Access to fetch at 'http://server-ip:5984/obsidian' from origin 'app://obsidian.md' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.

Resolution:

# Access CouchDB container
docker exec -it couchdb-for-obsidian bash

# Edit local.ini configuration
nano /opt/couchdb/etc/local.d/local.ini

# Add CORS configuration:
[httpd]
enable_cors = true

[cors]
origins = *
credentials = true
methods = GET, PUT, POST, HEAD, DELETE
headers = accept, authorization, content-type, origin, referer

# Exit container
exit

# Restart CouchDB
docker restart couchdb-for-obsidian

# Verify CORS headers
curl -I http://localhost:5984/obsidian

Issue 3: Configuration Mismatch - Chunk Size

Problem: Local LiveSync client reported customChunkSize mismatch (local 60 vs remote 0).

Error in Obsidian:

Configuration mismatch detected:
- Local chunk size: 60
- Remote chunk size: 0
This may cause sync issues.

Resolution:

  1. In Obsidian Settings → Self-hosted LiveSync:
    • Scroll to Advanced Settings
    • Set Custom Chunk Size: 60
    • Click Save
  2. Accept Remote Update Prompt:
    • When prompted: “Configuration mismatch, accept remote settings?”
    • Click “Use local settings” (preferred)
    • Or click “Use remote settings” if remote is trusted
  3. Verify Consistency Across All Devices:
    • Repeat on each device
    • Ensure all use same chunk size (60 recommended)

Why 60? - Balance between efficiency and compatibility - Works well with most network conditions - Recommended by LiveSync documentation

Issue 4: Filename Case Sensitivity

Problem: Potential sync conflicts due to file name case sensitivity across Linux, Windows, and Android devices.

Scenario:

Linux: Creates "MyNote.md" and "mynote.md" (two different files)
Windows: Sees only one file (case-insensitive filesystem)
Result: Sync conflict!

Resolution:

In Obsidian LiveSync Settings:

Settings → Self-hosted LiveSync → Advanced

handleFilenameCaseSensitive:
- Set to FALSE if syncing with Windows/macOS/Android
- Set to TRUE only if ALL clients use case-sensitive filesystems

Best Practice: - Use consistent naming convention (e.g., all lowercase) - Avoid creating files with names differing only in case - Document your naming convention in vault

Issue 5: End-to-End Encryption Algorithm Update

Problem: Older E2EE version detected with known vulnerabilities.

Warning Message:

You are using E2EE v1 which has known security issues.
Please upgrade to E2EE v2 for improved security.

Resolution:

  1. Backup Your Vault:

    # Create backup before upgrade
    tar -czf obsidian-backup-$(date +%Y%m%d).tar.gz ~/path/to/vault
  2. Upgrade to E2EE v2:

    • Settings → Self-hosted LiveSync → Encryption
    • Click “Upgrade to E2EE v2”
    • Confirm upgrade
    • New passphrase required - save securely!
  3. Update All Clients:

    • Ensure all devices run LiveSync plugin version 0.25.0+
    • Update plugin on each device
    • Enter new E2EE v2 passphrase

Security Improvements in v2: - Stronger encryption algorithms - Improved key derivation - Better protection against brute-force attacks

Issue 6: Vault Rebuild Confirmation

Problem: Sync metadata rebuild required due to remote database corruption or config changes.

When This Happens: - After major plugin updates - After database restoration - After changing encryption settings - After resolving sync conflicts

Resolution:

  1. Backup Current State:

    # Export vault
    cp -r ~/vault ~/vault-backup-$(date +%Y%m%d)
  2. Confirm Rebuild in LiveSync:

    • Settings → Self-hosted LiveSync
    • Click “Rebuild database”
    • Confirm: “Are you sure?”
    • Wait for process to complete (may take several minutes)
  3. Verify Rebuild Success:

    • Check sync status indicator (should show green)
    • Make test change on one device
    • Verify it syncs to other devices

What Rebuild Does: - Recreates local sync metadata - Re-indexes all files - Resolves inconsistencies - Does NOT delete your notes (safe operation)

Issue 7: Connectivity Issues with CouchDB

Problem: Could not connect to server messages during sync attempts.

Possible Causes: 1. CouchDB container not running 2. Network firewall blocking port 5984 3. Incorrect URL in LiveSync settings 4. Certificate issues (if using HTTPS)

Resolution:

Verify Container Status:

# Check if container is running
docker ps | grep couchdb

# If not running, start it
docker start couchdb-for-obsidian

# Check logs for errors
docker logs --tail 50 couchdb-for-obsidian

Check Network Connectivity:

# Test from client machine
curl http://<server-ip>:5984

# Expected response:
# {"couchdb":"Welcome","version":"3.x.x"}

# Test database access
curl http://<server-ip>:5984/obsidian

Verify Firewall Settings:

# On server, allow port 5984
sudo ufw allow 5984/tcp

# On pfSense:
# Firewall → Rules → LAN → Add
# Allow TCP 5984 to CouchDB server IP

Check LiveSync URL Configuration: - Settings → Self-hosted LiveSync - Remote Database URL: http://<server-ip>:5984/obsidian - Ensure NO trailing slash - Username and password correct

Step-by-Step Workflow Summary

Complete Setup Checklist

  1. Server Preparation:
  2. Database Configuration:
  3. LiveSync Plugin Setup:
  4. Initial Sync:
  5. Multi-Device Setup:
  6. Ongoing Maintenance:

Performance Optimization

LiveSync Settings:

Sync Mode: Automatic
Sync Interval: 30 seconds (balance responsiveness and battery)
Batch Size: 50 (default, increase for faster sync)
Chunk Size: 60 (for compatibility)
Timeout: 120 seconds

Advanced:
- Compress database: Yes
- Use chunked sync: Yes
- Verify checksum: Yes (slower but safer)

Database Maintenance

# Compact database (reduces size)
curl -X POST http://admin:password@localhost:5984/obsidian/_compact \
     -H "Content-Type: application/json"

# View database stats
curl http://admin:password@localhost:5984/obsidian

# Backup database
curl -X GET http://admin:password@localhost:5984/obsidian/_all_docs?include_docs=true \
     > obsidian-backup-$(date +%Y%m%d).json

Security Best Practices

1. Use HTTPS for Remote Access

# Nginx reverse proxy configuration
server {
    listen 443 ssl;
    server_name sync.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:5984;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2. Restrict Access by IP

# In CouchDB local.ini
[httpd]
bind_address = 192.168.1.100  # Only accept connections from specific IP

# Or use firewall
sudo ufw allow from 192.168.1.0/24 to any port 5984

3. Enable E2EE v2

  • Always use End-to-End Encryption
  • Use strong passphrase (20+ characters)
  • Store passphrase in password manager
  • Don’t share passphrase insecurely

Troubleshooting Tips

Sync Not Working

  1. Check sync status indicator in Obsidian
  2. Review LiveSync logs (Settings → Show log)
  3. Verify network connectivity to CouchDB
  4. Check CouchDB container logs
  5. Rebuild database if persistent issues

Conflicts Appearing

  1. Review conflict files in .conflicts/ folder
  2. Manually resolve conflicts
  3. Delete resolved conflict files
  4. Consider adjusting sync interval

High CPU/Memory Usage

  1. Reduce sync frequency
  2. Compact CouchDB database
  3. Limit vault size (separate large media files)
  4. Upgrade server hardware if needed

References

Notes

Maintain configuration consistency across devices and apply updates promptly to ensure secure, reliable synchronization of your Obsidian vault. Regular backups of both the vault and CouchDB database are essential for disaster recovery.

Conclusion

Self-hosting Obsidian sync with CouchDB provides complete control over your notes while saving subscription costs. The initial setup requires attention to detail, but once configured properly, it provides reliable, encrypted synchronization across all your devices.

Key Takeaways: - CORS configuration is critical for web access - Consistent chunk size prevents sync errors - E2EE v2 provides strong security - Regular database maintenance ensures performance - Proper backups prevent data loss

Document created: 2025-10-25