Self-Hosted Obsidian Sync
Complete guide to setting up Obsidian with free, self-hosted, instant sync using CouchDB and LiveSync plugin
Self-Hosted Obsidian Sync
Set up Obsidian with free, self-hosted, instant synchronization using CouchDB and the LiveSync plugin. This solution provides secure, encrypted note syncing across all your devices without relying on Obsidian's paid sync service.
Architecture Overview
This setup provides end-to-end encrypted synchronization with offline access and real-time collaboration capabilities.
System Components
CouchDB Server Setup
Docker Deployment
Create docker-compose.yml:
version: '3.8'
services:
couchdb-obsidian:
container_name: obsidian-livesync
image: couchdb:3.3.3
environment:
- PUID=99
- PGID=100
- UMASK=0022
- TZ=America/New_York
- COUCHDB_USER=obsidian_user # Change this
- COUCHDB_PASSWORD=secure_password # Change this
volumes:
- ./data:/opt/couchdb/data
- ./config:/opt/couchdb/etc/local.d
ports:
- "5984:5984"
restart: unless-stopped
networks:
- obsidian-net
networks:
obsidian-net:
driver: bridgeDeploy the service:
docker-compose up -d# Create data directories
mkdir -p ./couchdb/{data,config}
# Run CouchDB container
docker run -d \
--name obsidian-livesync \
--restart unless-stopped \
-p 5984:5984 \
-e COUCHDB_USER=obsidian_user \
-e COUCHDB_PASSWORD=secure_password \
-e TZ=America/New_York \
-v ./couchdb/data:/opt/couchdb/data \
-v ./couchdb/config:/opt/couchdb/etc/local.d \
couchdb:3.3.3On Ubuntu/Debian:
# Add CouchDB repository
curl -L https://couchdb.apache.org/repo/keys.asc | sudo apt-key add -
echo "deb https://apache.jfrog.io/artifactory/couchdb-deb/ focal main" | sudo tee /etc/apt/sources.list.d/couchdb.list
# Install CouchDB
sudo apt update && sudo apt install couchdb
# Configure during installation or edit /opt/couchdb/etc/local.iniInitial CouchDB Configuration
Complete the initial setup immediately after deployment to secure your CouchDB instance.
-
Access CouchDB Interface:
- Navigate to
http://your-server-ip:5984/_utils - Use credentials from Docker configuration
- Navigate to
-
Configure Single Node:
- Expand left menu (click
<->icon) - Go to Setup → Configure as Single Node
- Enter admin credentials
- Click Configure Node
- Expand left menu (click
-
Verify Installation:
- Navigate to Verify in left menu
- Click Verify Installation
- Confirm six green checkmarks
Database Creation
# Create database via API
curl -X PUT http://obsidian_user:secure_password@your-server-ip:5984/obsidiandb
# Or via web interface:
# 1. Go to Databases → Create Database
# 2. Name: obsidiandb (or user-specific like obsidiandb_john)
# 3. Choose: Non-partitionedSecurity Configuration
Configure these settings via Configuration in the web interface:
| Section | Name | Value |
|---|---|---|
chttpd | require_valid_user | true |
chttpd_auth | require_valid_user | true |
httpd | WWW-Authenticate | Basic realm="couchdb" |
| Section | Name | Value |
|---|---|---|
httpd | enable_cors | true |
chttpd | enable_cors | true |
cors | credentials | true |
cors | origins | app://obsidian.md,capacitor://localhost,http://localhost |
| Section | Name | Value |
|---|---|---|
chttpd | max_http_request_size | 4294967296 |
couchdb | max_document_size | 50000000 |
Obsidian Configuration
Installing Obsidian
Windows/macOS/Linux:
- Download from obsidian.md
- Install and create new vault
- Choose vault location and name
iOS/Android:
- Install from App Store/Play Store
- Create new vault or open existing
- Grant necessary permissions
Browser Access (limited functionality):
- Access via
obsidian://protocol - Some features may be restricted
- Primarily for emergency access
LiveSync Plugin Installation
-
Enable Community Plugins:
- Settings → Community Plugins
- Turn off Safe Mode
- Click Browse
-
Install LiveSync:
- Search for Self-hosted LiveSync
- Install and enable the plugin
- Open plugin settings
LiveSync Configuration
Test the connection before enabling synchronization to ensure proper configuration.
-
Database Connection (🛰️ icon):
Remote Type: CouchDB URI: http://your-server-ip:5984 Username: obsidian_user Password: secure_password Database Name: obsidiandb -
Test Connection:
- Click Test button
- Verify successful connection
- Click Check and fix any issues
-
Sync Mode (🔄 icon):
- Set to LiveSync
- Enable Periodic Sync if needed
- Configure sync intervals
-
Sync Options:
Sync on Save: Enabled Sync on File Open: Enabled Sync on Start: Enabled Batch Database Update: Enabled
-
Enable End-to-End Encryption:
- Toggle End-to-end encryption
- Generate or enter passphrase
- Important: Save passphrase securely
-
Encryption Settings:
Encrypt File Contents: Yes Encrypt File Names: Optional Encrypt Metadata: Recommended
Advanced Configuration
Reverse Proxy Setup
Use HTTPS for secure access, especially on mobile devices and public networks.
server {
listen 443 ssl http2;
server_name obsidian.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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}# docker-compose.yml addition
labels:
- "traefik.enable=true"
- "traefik.http.routers.obsidian.rule=Host(`obsidian.yourdomain.com`)"
- "traefik.http.routers.obsidian.tls=true"
- "traefik.http.routers.obsidian.tls.certresolver=letsencrypt"
- "traefik.http.services.obsidian.loadbalancer.server.port=5984"# cloudflared config
tunnel: your-tunnel-id
credentials-file: /path/to/credentials.json
ingress:
- hostname: obsidian.yourdomain.com
service: http://localhost:5984
- service: http_status:404Multi-User Setup
# Create user-specific databases
curl -X PUT http://admin:password@server:5984/obsidiandb_alice
curl -X PUT http://admin:password@server:5984/obsidiandb_bob
# Create users with database access
curl -X PUT http://admin:password@server:5984/_users/org.couchdb.user:alice \
-H "Content-Type: application/json" \
-d '{"name": "alice", "password": "alice_password", "roles": [], "type": "user"}'Troubleshooting
Common Issues
Always backup your vault before troubleshooting sync issues.
Cannot Connect to Database:
# Check CouchDB status
curl http://your-server:5984/
# Verify database exists
curl http://user:pass@your-server:5984/_all_dbs
# Test authentication
curl -u user:pass http://your-server:5984/obsidiandbCORS Errors:
- Verify CORS configuration in CouchDB
- Check origins setting includes Obsidian protocols
- Restart CouchDB after configuration changes
Conflict Resolution:
- Open LiveSync settings
- Go to Conflict Resolution
- Choose resolution strategy:
- Automatic: Use newer version
- Manual: Review each conflict
- Keep Both: Create duplicate files
Manual Conflict Resolution:
Conflicted files appear with suffix:
- note.md (conflict-2024-02-09-14-30-15)
- note.md (conflict-2024-02-09-14-30-20)Slow Sync Performance:
- Reduce batch size in LiveSync settings
- Enable compression in CouchDB
- Optimize network connection
- Consider local CouchDB instance
Large Vault Issues:
# Increase CouchDB limits
curl -X PUT http://admin:pass@server:5984/_node/_local/_config/couchdb/max_document_size -d '"100000000"'
curl -X PUT http://admin:pass@server:5984/_node/_local/_config/chttpd/max_http_request_size -d '"8294967296"'Monitoring and Maintenance
# Monitor CouchDB logs
docker logs -f obsidian-livesync
# Check database size
curl http://user:pass@server:5984/obsidiandb | jq '.doc_count, .disk_size'
# Compact database
curl -X POST http://user:pass@server:5984/obsidiandb/_compact
# Backup database
curl http://user:pass@server:5984/obsidiandb/_all_docs?include_docs=true > backup.jsonSecurity Best Practices
Access Control
Backup Strategy
#!/bin/bash
# Automated backup script
BACKUP_DIR="/backup/obsidian"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="obsidiandb"
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup database
curl -u user:pass http://server:5984/$DB_NAME/_all_docs?include_docs=true > $BACKUP_DIR/backup_$DATE.json
# Compress backup
gzip $BACKUP_DIR/backup_$DATE.json
# Clean old backups (keep 30 days)
find $BACKUP_DIR -name "backup_*.json.gz" -mtime +30 -delete
echo "Backup completed: backup_$DATE.json.gz"Migration and Updates
Migrating Existing Vault
-
Export Current Vault:
- Copy all files to temporary location
- Note any custom configurations
-
Setup New Sync:
- Configure LiveSync on primary device
- Wait for initial sync completion
-
Add Other Devices:
- Install Obsidian and LiveSync
- Use same CouchDB credentials
- Allow initial sync to complete
Updating Components
# Update CouchDB container
docker-compose pull
docker-compose up -d
# Verify update
curl http://server:5984/ | jq '.version'- Check for updates in Community Plugins
- Update LiveSync plugin
- Review changelog for breaking changes
- Test sync functionality
- Update Obsidian application
- Verify plugin compatibility
- Test all sync functionality
- Update mobile apps if needed
Performance Optimization
CouchDB Tuning
# Optimize for Obsidian workload
curl -X PUT http://admin:pass@server:5984/_node/_local/_config/couchdb/delayed_commits -d '"false"'
curl -X PUT http://admin:pass@server:5984/_node/_local/_config/couchdb/max_dbs_open -d '"500"'
# Enable compression
curl -X PUT http://admin:pass@server:5984/_node/_local/_config/httpd/compression -d '"snappy"'Network Optimization
- Use local network for primary sync
- Configure QoS for sync traffic
- Consider CDN for global access
- Implement connection pooling
Conclusion
This self-hosted Obsidian sync solution provides:
- Cost-effective: No subscription fees
- Privacy-focused: Your data stays on your servers
- Flexible: Customizable to your needs
- Reliable: Offline access with conflict resolution
- Secure: End-to-end encryption available
Regular maintenance and monitoring ensure optimal performance and data safety for your self-hosted Obsidian sync setup.