This commit is contained in:
Andras Schmelczer 2025-11-22 11:19:08 +00:00
parent 56c1f4d58b
commit 50a95b114d
19 changed files with 4663 additions and 1 deletions

581
docs/config/advanced.md Normal file
View file

@ -0,0 +1,581 @@
# Advanced Configuration
Advanced topics for optimizing and customizing your VaultLink deployment.
## Database Optimization
### SQLite Tuning
While VaultLink handles most SQLite configuration automatically, you can optimize for specific workloads.
#### WAL Mode
VaultLink uses Write-Ahead Logging (WAL) mode by default for better concurrency.
**Benefits**:
- Readers don't block writers
- Writers don't block readers
- Better performance for concurrent access
**Maintenance**:
```bash
# Checkpoint WAL to main database (run periodically)
sqlite3 databases/vault.db "PRAGMA wal_checkpoint(TRUNCATE);"
```
#### Database Size Management
Over time, databases can grow with version history:
```bash
# Check database size
du -h databases/*.db
# Vacuum to reclaim space (offline only)
sqlite3 databases/vault.db "VACUUM;"
# Analyze for query optimization
sqlite3 databases/vault.db "ANALYZE;"
```
**Schedule maintenance**:
```bash
#!/bin/bash
# monthly-maintenance.sh
for db in databases/*.db; do
echo "Optimizing $db"
sqlite3 "$db" "PRAGMA optimize;"
sqlite3 "$db" "PRAGMA wal_checkpoint(TRUNCATE);"
done
```
### Version History Cleanup
To limit database growth, implement version history pruning (requires custom script):
```bash
#!/bin/bash
# prune-old-versions.sh
# Keep only last 100 versions per document
for db in databases/*.db; do
sqlite3 "$db" <<EOF
DELETE FROM versions
WHERE id NOT IN (
SELECT id FROM versions
WHERE document_id = versions.document_id
ORDER BY version DESC
LIMIT 100
);
EOF
done
```
## Performance Tuning
### Connection Pool Sizing
Calculate optimal `max_connections_per_vault`:
```
max_connections = (concurrent_users × avg_operations_per_user) + buffer
```
**Example**:
- 20 concurrent users
- 2 operations per user on average
- 25% buffer
```
max_connections = (20 × 2) × 1.25 = 50
```
### Timeout Configuration
Adjust timeouts based on network characteristics:
**Fast local network**:
```yaml
database:
cursor_timeout_seconds: 30
server:
response_timeout_seconds: 30
```
**Slow or unreliable network**:
```yaml
database:
cursor_timeout_seconds: 180
server:
response_timeout_seconds: 120
```
**Mobile clients**:
```yaml
database:
cursor_timeout_seconds: 300 # Longer for intermittent connections
server:
response_timeout_seconds: 180
```
## Reverse Proxy Configuration
### Nginx with SSL
Complete Nginx configuration for production:
```nginx
# Rate limiting
limit_req_zone $binary_remote_addr zone=vaultlink:10m rate=10r/s;
upstream vaultlink {
server localhost:3000;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name sync.example.com;
ssl_certificate /etc/letsencrypt/live/sync.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sync.example.com/privkey.pem;
# SSL security settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Rate limiting
limit_req zone=vaultlink burst=20 nodelay;
# Client body size (match server config)
client_max_body_size 512M;
# Timeouts
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 3600s; # WebSocket long-lived connections
# WebSocket headers
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;
# Disable buffering for WebSocket
proxy_buffering off;
location / {
proxy_pass http://vaultlink;
}
# Health check endpoint
location /health {
proxy_pass http://vaultlink/vaults/health/ping;
access_log off;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name sync.example.com;
return 301 https://$server_name$request_uri;
}
```
### Caddy with Auto SSL
Caddy handles SSL automatically:
```caddy
sync.example.com {
reverse_proxy localhost:3000 {
# WebSocket support
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
# Timeouts
transport http {
read_timeout 3600s
write_timeout 90s
}
}
# Rate limiting (requires caddy-rate-limit plugin)
rate_limit {
zone dynamic {
match {
remote_ip
}
rate 10r/s
burst 20
}
}
}
```
### Traefik Configuration
Using Docker labels:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.vaultlink.rule=Host(`sync.example.com`)"
- "traefik.http.routers.vaultlink.entrypoints=websecure"
- "traefik.http.routers.vaultlink.tls.certresolver=letsencrypt"
- "traefik.http.services.vaultlink.loadbalancer.server.port=3000"
# Middleware for timeouts
- "traefik.http.middlewares.vaultlink-timeout.timeout.request=3600s"
```
## Docker Optimizations
### Resource Limits
Limit container resources:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '1.0'
memory: 2G
```
### Logging Configuration
Optimize Docker logging:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
```
### Volume Optimization
Use named volumes for better performance:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
volumes:
- vaultlink-data:/data
- vaultlink-logs:/data/logs
volumes:
vaultlink-data:
driver: local
driver_opts:
type: none
o: bind
device: /mnt/fast-ssd/vaultlink
vaultlink-logs:
driver: local
```
## High Availability
### Health Checks
Comprehensive health monitoring:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/vaults/health/ping || exit 1"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
```
Monitor health in production:
```bash
#!/bin/bash
# health-monitor.sh
while true; do
if ! curl -sf http://localhost:3000/vaults/health/ping > /dev/null; then
echo "Health check failed at $(date)" | mail -s "VaultLink Down" admin@example.com
# Optionally restart
# docker restart vaultlink-server
fi
sleep 30
done
```
### Backup Automation
Automated backup script:
```bash
#!/bin/bash
# backup-vaultlink.sh
BACKUP_DIR="/backup/vaultlink"
DATA_DIR="/data"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR/$DATE"
# Backup databases (with WAL checkpoint)
for db in "$DATA_DIR"/databases/*.db; do
sqlite3 "$db" "PRAGMA wal_checkpoint(TRUNCATE);"
cp "$db" "$BACKUP_DIR/$DATE/"
[ -f "${db}-wal" ] && cp "${db}-wal" "$BACKUP_DIR/$DATE/"
[ -f "${db}-shm" ] && cp "${db}-shm" "$BACKUP_DIR/$DATE/"
done
# Backup configuration
cp "$DATA_DIR/config.yml" "$BACKUP_DIR/$DATE/"
# Compress backup
tar -czf "$BACKUP_DIR/vaultlink-$DATE.tar.gz" -C "$BACKUP_DIR" "$DATE"
rm -rf "$BACKUP_DIR/$DATE"
# Clean old backups
find "$BACKUP_DIR" -name "vaultlink-*.tar.gz" -mtime +$RETENTION_DAYS -delete
# Upload to remote storage (optional)
# rclone copy "$BACKUP_DIR/vaultlink-$DATE.tar.gz" remote:backups/
```
Schedule with cron:
```cron
0 2 * * * /opt/vaultlink/backup-vaultlink.sh
```
### Restore from Backup
```bash
#!/bin/bash
# restore-vaultlink.sh
BACKUP_FILE="$1"
DATA_DIR="/data"
if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup-file.tar.gz>"
exit 1
fi
# Stop server
docker stop vaultlink-server
# Extract backup
tar -xzf "$BACKUP_FILE" -C /tmp/
BACKUP_DATE=$(basename "$BACKUP_FILE" .tar.gz | cut -d- -f2-)
# Restore databases
cp /tmp/"$BACKUP_DATE"/databases/*.db "$DATA_DIR/databases/"
# Restore config (careful!)
# cp /tmp/$BACKUP_DATE/config.yml "$DATA_DIR/"
# Cleanup
rm -rf /tmp/"$BACKUP_DATE"
# Start server
docker start vaultlink-server
echo "Restore complete. Check server logs."
```
## Monitoring and Metrics
### Prometheus Metrics
While VaultLink doesn't expose metrics natively, monitor Docker:
```yaml
# docker-compose.yml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
labels:
- "prometheus.io/scrape=true"
- "prometheus.io/port=3000"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- 8080:8080
```
### Log Analysis
Analyze logs for insights:
```bash
# Most active users
grep "authenticated" logs/*.log | cut -d"'" -f2 | sort | uniq -c | sort -rn
# Failed authentications by IP
grep "Authentication failed" logs/*.log | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn
# Upload activity
grep "Upload:" logs/*.log | wc -l
# Average files per vault
grep "Sync complete" logs/*.log | grep -oP '\d+ files' | cut -d' ' -f1 | awk '{sum+=$1; count++} END {print sum/count}'
```
### Alerting
Simple alerting with cron:
```bash
#!/bin/bash
# alert-errors.sh
ERROR_THRESHOLD=10
ERROR_COUNT=$(grep -c "ERROR" logs/latest.log)
if [ "$ERROR_COUNT" -gt "$ERROR_THRESHOLD" ]; then
echo "VaultLink has $ERROR_COUNT errors in the last hour" | \
mail -s "VaultLink Alert" admin@example.com
fi
```
## Security Hardening
### Network Isolation
Run VaultLink in isolated network:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
networks:
- vaultlink-internal
- proxy-external
networks:
vaultlink-internal:
internal: true
proxy-external:
driver: bridge
```
### Read-Only Root Filesystem
Run with read-only root (mount writable volumes for data):
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
read_only: true
volumes:
- ./data:/data
- /tmp
```
### Drop Capabilities
Run with minimal privileges:
```yaml
services:
vaultlink-server:
image: ghcr.io/schmelczer/vault-link-server:latest
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
```
## Migration
### Moving to New Server
1. **Backup on old server**:
```bash
./backup-vaultlink.sh
```
2. **Transfer backup**:
```bash
scp vaultlink-backup.tar.gz new-server:/tmp/
```
3. **Restore on new server**:
```bash
./restore-vaultlink.sh /tmp/vaultlink-backup.tar.gz
```
4. **Update DNS/clients** to point to new server
5. **Verify sync** on all clients
### Version Upgrades
```bash
# Pull latest image
docker pull ghcr.io/schmelczer/vault-link-server:latest
# Backup first
./backup-vaultlink.sh
# Stop old container
docker stop vaultlink-server
docker rm vaultlink-server
# Start with new image
docker run -d \
--name vaultlink-server \
--restart unless-stopped \
-p 3000:3000 \
-v ./data:/data \
ghcr.io/schmelczer/vault-link-server:latest \
/app/sync_server /data/config.yml
# Check logs
docker logs -f vaultlink-server
```
## Next Steps
- [Understand the architecture →](/architecture/)
- [Deploy the server →](/guide/server-setup)
- [Configure clients →](/guide/obsidian-plugin)

View file

@ -0,0 +1,530 @@
# Authentication Configuration
VaultLink uses token-based authentication with per-user vault access control. This guide covers all authentication and authorization options.
## Overview
Authentication in VaultLink:
- **Token-based**: Users authenticate with secure tokens
- **Configured in YAML**: All users defined in `config.yml`
- **Vault-level access**: Control which vaults each user can access
- **No password hashing**: Tokens are treated as secrets
## Basic Configuration
```yaml
users:
user_configs:
- name: alice
token: alice-secure-token-here
vault_access:
type: allow_access_to_all
```
## User Configuration Fields
### `name`
**Type**: String
**Required**: Yes
Human-readable identifier for the user. Used in logs and auditing.
```yaml
- name: alice
```
**Notes**:
- Must be unique across all users
- Used for identification only, not authentication
- Appears in server logs
- Can be any string (e.g., email, username)
### `token`
**Type**: String
**Required**: Yes
Authentication token for the user. Must be kept secret.
```yaml
- token: 1a2b3c4d5e6f7g8h9i0j...
```
**Best practices**:
- Generate with: `openssl rand -hex 32`
- Minimum length: 32 characters
- Use different token per user
- Never commit to version control
- Rotate periodically
**Example token generation**:
```bash
# Generate a secure token
openssl rand -hex 32
# Output: a7f3c9d1e8b2f4a6c3d9e1f7b8a4c2d6e9f1a3b7c5d8e2f4a6b9c3d1e8f7a4b2
```
### `vault_access`
**Type**: Object
**Required**: Yes
Defines which vaults the user can access.
**Three modes**:
1. `allow_access_to_all`: Access to all vaults
2. `allow_list`: Access to specific vaults only
3. `deny_list`: Access to all vaults except specific ones
## Access Control Modes
### Allow Access to All
Grant access to every vault:
```yaml
users:
user_configs:
- name: admin
token: admin-token
vault_access:
type: allow_access_to_all
```
**Use cases**:
- Administrator accounts
- Personal single-user deployments
- Development/testing
### Allow List
Grant access only to specific vaults:
```yaml
users:
user_configs:
- name: alice
token: alice-token
vault_access:
type: allow_list
allowed:
- personal
- shared-team
- project-alpha
```
**Use cases**:
- Multi-user deployments
- Restricted access scenarios
- Separation of concerns
**Notes**:
- User can only access listed vaults
- Attempting to access other vaults returns authentication error
- Empty list = no access to any vault
### Deny List
Grant access to all vaults except specific ones:
```yaml
users:
user_configs:
- name: bob
token: bob-token
vault_access:
type: deny_list
denied:
- restricted
- admin-only
```
**Use cases**:
- Users with broad access except sensitive vaults
- Simplify configuration when most vaults are accessible
**Notes**:
- User can access any vault not in the deny list
- Attempting to access denied vaults returns authentication error
## Multi-User Scenarios
### Personal Use (Single User)
```yaml
users:
user_configs:
- name: me
token: my-super-secret-token
vault_access:
type: allow_access_to_all
```
### Small Team (Shared Vaults)
```yaml
users:
user_configs:
- name: alice
token: alice-token
vault_access:
type: allow_list
allowed:
- personal-alice
- team-shared
- name: bob
token: bob-token
vault_access:
type: allow_list
allowed:
- personal-bob
- team-shared
- name: charlie
token: charlie-token
vault_access:
type: allow_list
allowed:
- personal-charlie
- team-shared
```
### Organization (Mixed Access)
```yaml
users:
user_configs:
- name: admin
token: admin-token
vault_access:
type: allow_access_to_all
- name: developer
token: dev-token
vault_access:
type: allow_list
allowed:
- engineering-docs
- api-specs
- shared
- name: designer
token: design-token
vault_access:
type: allow_list
allowed:
- design-docs
- brand-assets
- shared
- name: readonly
token: readonly-token
vault_access:
type: allow_list
allowed:
- public-wiki
```
## Authentication Flow
### Connection
1. Client connects via WebSocket
2. Client sends authentication message:
```json
{
"type": "auth",
"token": "user-token",
"vault": "vault-name"
}
```
3. Server validates:
- Token exists in config
- User has access to requested vault
4. Server responds:
- Success: Connection established
- Failure: Connection closed with error
### Validation
Server checks:
1. **Token match**: Token exists in `user_configs`
2. **Vault access**: User has permission for vault
3. **Connection limits**: Not exceeding `max_clients_per_vault`
### Errors
**Invalid token**:
```
Authentication failed: Invalid token
```
**No vault access**:
```
Authentication failed: User does not have access to vault 'restricted'
```
**Connection limit**:
```
Connection rejected: Maximum clients reached for vault
```
## Security Best Practices
### Token Generation
Generate strong tokens:
```bash
# 64 character hex token (256 bits)
openssl rand -hex 32
# Base64 encoded (256 bits)
openssl rand -base64 32
# UUID v4
uuidgen
```
### Token Storage
**In config file**:
```yaml
users:
user_configs:
- name: alice
token: !ENV ALICE_TOKEN # Read from environment variable
```
**Load from environment**:
```bash
export ALICE_TOKEN="$(openssl rand -hex 32)"
./sync_server config.yml
```
### Token Rotation
Periodically change tokens:
1. Generate new token
2. Update `config.yml`
3. Restart server
4. Update clients with new token
### Token Revocation
To revoke access:
1. Remove user from `config.yml`
2. Restart server
3. User's connections will be rejected
For immediate revocation:
- Remove user from config
- Restart server
- Existing connections are terminated
## Access Patterns
### Read-Only Users
VaultLink doesn't distinguish read-only vs read-write. Implement via client:
```yaml
# Server: Grant access
users:
user_configs:
- name: readonly
token: readonly-token
vault_access:
type: allow_list
allowed:
- public
# Client: Use CLI in read-only mode (mount vault read-only)
docker run -v /vault:/vault:ro ...
```
### Temporary Access
Grant temporary access:
1. Add user to config
2. Set reminder to remove later
3. Remove user when no longer needed
4. Restart server
For automation:
```bash
# Add user with expiry comment
echo " - name: temp-user # EXPIRES: 2024-12-31" >> config.yml
echo " token: temp-token" >> config.yml
```
### Shared Tokens (Not Recommended)
Multiple users sharing a token:
- All appear as same user in logs
- Can't revoke individual access
- Security risk if one person leaves
**Instead**: Create separate users with same vault access.
## Monitoring
### Server Logs
Authentication events are logged:
```
2024-01-01 12:00:00 INFO User 'alice' authenticated for vault 'personal'
2024-01-01 12:00:05 WARN Authentication failed: Invalid token from 192.168.1.100
2024-01-01 12:00:10 WARN User 'bob' denied access to vault 'restricted'
```
### Audit Trail
Monitor authentication:
```bash
# View authentication logs
grep "authenticated" logs/*.log
# View failed authentications
grep "Authentication failed" logs/*.log
# View access denials
grep "denied access" logs/*.log
```
## Advanced Scenarios
### Multiple Servers
Same user across multiple server instances:
```yaml
# Server 1 config.yml
users:
user_configs:
- name: alice
token: alice-global-token
vault_access:
type: allow_list
allowed:
- vault-1
- vault-2
# Server 2 config.yml
users:
user_configs:
- name: alice
token: alice-global-token # Same token
vault_access:
type: allow_list
allowed:
- vault-3
- vault-4
```
### Service Accounts
Tokens for automated systems:
```yaml
users:
user_configs:
- name: backup-service
token: backup-service-token
vault_access:
type: allow_access_to_all
- name: ci-pipeline
token: ci-token
vault_access:
type: allow_list
allowed:
- documentation
- name: monitoring
token: monitoring-token
vault_access:
type: allow_list
allowed:
- metrics
```
### Dynamic Vault Access
VaultLink doesn't support runtime user management. To change access:
1. Update `config.yml`
2. Restart server
3. Users reconnect automatically
For frequent changes, consider:
- Over-provision access (deny list)
- Use external authentication proxy
- Script config updates + reload
## Troubleshooting
### Can't connect
**Check token**:
```bash
# Verify token in config matches client
grep "token:" config.yml
```
**Check vault name**:
```bash
# Ensure vault is in allowed list
grep -A 5 "name: alice" config.yml
```
**Check server logs**:
```bash
tail -f logs/*.log | grep -i auth
```
### Access denied
**Verify vault access**:
```yaml
# Check user's vault_access configuration
users:
user_configs:
- name: alice
vault_access:
type: allow_list
allowed:
- vault-name # Must match exactly
```
**Case sensitivity**:
- Vault names are case-sensitive
- `Vault``vault`
- Ensure exact match in config and client
### Token not working
**Check for typos**:
- Extra spaces
- Hidden characters
- Wrong quotes in YAML
**Regenerate token**:
```bash
# Generate new token
openssl rand -hex 32
# Update config
# Restart server
# Update client
```
## Next Steps
- [Server configuration reference →](/config/server)
- [Advanced configuration →](/config/advanced)
- [Deploy the server →](/guide/server-setup)

470
docs/config/server.md Normal file
View file

@ -0,0 +1,470 @@
# Server Configuration
Complete reference for configuring the VaultLink sync server via `config.yml`.
## Configuration File Format
The server is configured using a YAML file passed as a command-line argument:
```bash
/app/sync_server /path/to/config.yml
```
## Complete Example
```yaml
database:
databases_directory_path: databases
max_connections_per_vault: 12
cursor_timeout_seconds: 60
server:
host: 0.0.0.0
port: 3000
max_body_size_mb: 512
max_clients_per_vault: 256
response_timeout_seconds: 60
users:
user_configs:
- name: admin
token: your-secure-random-token
vault_access:
type: allow_access_to_all
- name: alice
token: alice-token
vault_access:
type: allow_list
allowed:
- personal
- shared
- name: bob
token: bob-token
vault_access:
type: deny_list
denied:
- restricted
logging:
log_directory: logs
log_rotation: 7days
```
## Database Section
### `databases_directory_path`
**Type**: String
**Required**: Yes
**Default**: None
Directory where SQLite database files are stored. One database file per vault.
```yaml
database:
databases_directory_path: /data/databases
```
The directory structure:
```
databases/
├── vault-1.db
├── vault-2.db
└── personal.db
```
**Notes**:
- Path is relative to working directory or absolute
- Directory must be writable by the server process
- Ensure adequate disk space for vault data
- Back up this directory regularly
### `max_connections_per_vault`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 12
Maximum concurrent database connections per vault.
```yaml
database:
max_connections_per_vault: 12
```
**Tuning**:
- Higher values: Better performance under load
- Lower values: Less memory usage
- Typical range: 8-20
- Consider: Number of concurrent users × average operations per user
### `cursor_timeout_seconds`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 60
How long to keep database cursors alive for inactive clients.
```yaml
database:
cursor_timeout_seconds: 60
```
**Notes**:
- Cursors track client sync state
- Timeout too short: Clients may need to re-sync frequently
- Timeout too long: More memory usage
- Typical range: 30-300 seconds
## Server Section
### `host`
**Type**: String
**Required**: Yes
**Default**: None
Network interface to bind the server to.
```yaml
server:
host: 0.0.0.0 # All interfaces
# OR
host: 127.0.0.1 # Localhost only
# OR
host: 192.168.1.100 # Specific interface
```
**Common values**:
- `0.0.0.0`: Listen on all network interfaces (production)
- `127.0.0.1`: Listen on localhost only (development/testing)
- Specific IP: Listen on specific interface
### `port`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 3000
TCP port to listen on.
```yaml
server:
port: 3000
```
**Notes**:
- Must be available (not in use)
- Privileged ports (< 1024) require root
- Common ports: 3000, 8080, 8888
- Configure firewall to allow this port
### `max_body_size_mb`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 512
Maximum size of HTTP request body in megabytes.
```yaml
server:
max_body_size_mb: 512
```
**Usage**:
- Limits file upload size
- Prevents memory exhaustion attacks
- Must be larger than largest expected file
- Consider client `max_file_size_mb` settings
**Tuning**:
- Small vaults (mostly text): 100 MB
- Medium vaults (some images): 512 MB
- Large vaults (many images/PDFs): 1024+ MB
### `max_clients_per_vault`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 256
Maximum concurrent clients per vault.
```yaml
server:
max_clients_per_vault: 256
```
**Notes**:
- Limits concurrent WebSocket connections
- Prevents resource exhaustion
- Consider expected number of users
- Each client uses memory and file descriptors
**Scaling**:
- Personal use: 10-50
- Small team: 50-100
- Large team: 100-500
### `response_timeout_seconds`
**Type**: Integer
**Required**: Yes
**Default**: None
**Recommended**: 60
Maximum time to wait for client responses.
```yaml
server:
response_timeout_seconds: 60
```
**Usage**:
- Timeout for HTTP requests
- Timeout for WebSocket operations
- Clients disconnected if unresponsive
**Tuning**:
- Fast networks: 30 seconds
- Slow networks: 90-120 seconds
- Large file uploads: Increase proportionally
## Users Section
See [Authentication Configuration →](/config/authentication) for detailed user configuration.
## Logging Section
### `log_directory`
**Type**: String
**Required**: Yes
**Default**: None
Directory where log files are written.
```yaml
logging:
log_directory: /data/logs
# OR
log_directory: logs # Relative to working directory
```
**Notes**:
- Path is relative to working directory or absolute
- Directory must be writable
- Logs are rotated based on `log_rotation`
- Monitor disk usage
### `log_rotation`
**Type**: String
**Required**: Yes
**Default**: None
How often to rotate log files.
```yaml
logging:
log_rotation: 7days
# OR
log_rotation: 24hours
# OR
log_rotation: 30days
```
**Format**: `<number><unit>`
**Units**:
- `hours`: Hours (e.g., `12hours`, `24hours`)
- `days`: Days (e.g., `7days`, `30days`)
**Recommendations**:
- Development: `24hours` or `7days`
- Production: `7days` or `30days`
- High traffic: `24hours` (logs can be large)
## Environment-Specific Configurations
### Development
```yaml
database:
databases_directory_path: ./databases
max_connections_per_vault: 8
cursor_timeout_seconds: 30
server:
host: 127.0.0.1
port: 3000
max_body_size_mb: 100
max_clients_per_vault: 10
response_timeout_seconds: 30
users:
user_configs:
- name: dev
token: dev-token
vault_access:
type: allow_access_to_all
logging:
log_directory: logs
log_rotation: 24hours
```
### Production
```yaml
database:
databases_directory_path: /data/databases
max_connections_per_vault: 16
cursor_timeout_seconds: 120
server:
host: 0.0.0.0
port: 3000
max_body_size_mb: 512
max_clients_per_vault: 256
response_timeout_seconds: 90
users:
user_configs:
- name: admin
token: <strong-random-token>
vault_access:
type: allow_access_to_all
# Additional users...
logging:
log_directory: /data/logs
log_rotation: 7days
```
## Validation
The server validates configuration on startup:
```bash
# Start server
./sync_server config.yml
# Check for errors in logs
tail -f logs/latest.log
```
**Common errors**:
- Missing required fields
- Invalid YAML syntax
- Invalid values (negative numbers, etc.)
- Directory not writable
## Performance Tuning
### High Concurrency
For many concurrent users:
```yaml
database:
max_connections_per_vault: 20 # Increase
server:
max_clients_per_vault: 500 # Increase
response_timeout_seconds: 120 # Increase for slow clients
```
### Large Files
For vaults with large files:
```yaml
server:
max_body_size_mb: 1024 # Allow larger uploads
response_timeout_seconds: 180 # More time for uploads
```
### Resource-Constrained Systems
For limited CPU/memory:
```yaml
database:
max_connections_per_vault: 6 # Reduce
server:
max_clients_per_vault: 50 # Reduce
max_body_size_mb: 256 # Reduce
```
## Security Considerations
### Token Security
- Use strong random tokens: `openssl rand -hex 32`
- Never commit tokens to version control
- Rotate tokens periodically
- Use different tokens per user
### Network Security
- Bind to `127.0.0.1` if using reverse proxy on same host
- Use firewall to restrict access
- Enable SSL/TLS via reverse proxy
### Resource Limits
- Set `max_clients_per_vault` to prevent DoS
- Set `max_body_size_mb` to prevent memory exhaustion
- Configure `response_timeout_seconds` to prevent hanging connections
## Troubleshooting
### Server won't start
**Check YAML syntax**:
```bash
# Use a YAML validator
python -c 'import yaml, sys; yaml.safe_load(open("config.yml"))'
```
**Check file paths**:
```bash
# Ensure directories exist and are writable
mkdir -p databases logs
chmod 755 databases logs
```
**Check port availability**:
```bash
# Verify port is not in use
lsof -i :3000
```
### High memory usage
- Reduce `max_connections_per_vault`
- Reduce `max_clients_per_vault`
- Reduce `max_body_size_mb`
- Check for large vaults or many concurrent users
### Slow performance
- Increase `max_connections_per_vault`
- Increase database connection pool
- Use SSD for database storage
- Monitor database size (vacuum if needed)
## Next Steps
- [Configure authentication →](/config/authentication)
- [Advanced configuration options →](/config/advanced)
- [Deploy the server →](/guide/server-setup)