# Pinakes Configuration Example # Copy this file to pinakes.toml and adjust values as needed. # Most settings have sensible defaults and can be omitted. ## Storage Backend Configuration [storage] # Storage backend: "sqlite" or "postgres" # SQLite is recommended for single-user or small deployments (< 10k items) # PostgreSQL is recommended for larger libraries or multi-user setups backend = "sqlite" [storage.sqlite] # Path to the SQLite database file (relative to data directory or absolute) # Default: /pinakes.db path = "pinakes.db" # PostgreSQL configuration (uncomment if using PostgreSQL backend) # [storage.postgres] # host = "localhost" # port = 5432 # database = "pinakes" # username = "pinakes" # password = "your_secure_password_here" ## Maximum number of database connections in the pool # max_connections = 10 ## Enable TLS/SSL for database connections # tls = { mode = "require", ca_cert = "/path/to/ca.pem" } ## Directory Configuration [directories] # Root directories to scan for media files # Supports environment variable expansion: ${HOME}, $HOME # Paths can be absolute or relative to the working directory. Add more directories # as needed. roots = [ "${HOME}/Music", "${HOME}/Documents", "${HOME}/Videos", "${HOME}/Pictures", # ... ] ## File Scanning Configuration [scanning] # Watch directories for changes using filesystem events # When enabled, Pinakes will automatically detect new/modified/deleted files # and update the catalog index. # Default: true watch = true # Polling interval in seconds (used as fallback when native fs events unavailable) # Only used on systems without inotify/FSEvents support # Default: 300 (5 minutes) poll_interval_secs = 300 # File patterns to ignore during scanning (glob patterns) # Default: Hidden files and common build/cache directories ignore_patterns = [ ".*", # Hidden files (starting with .) "node_modules", # JavaScript dependencies "target", # Rust build artifacts ".git", # Git repository data "__pycache__", # Python cache "venv", # Python virtual environments "*.tmp", # Temporary files "*.swp", # Vim swap files "Thumbs.db", # Windows thumbnail cache ".DS_Store", # macOS metadata ] ## Server Configuration [server] # Server bind address # Use "0.0.0.0" to listen on all interfaces (required for network access) # Use "127.0.0.1" for localhost-only access (slightly more secure) # Default: "127.0.0.1" host = "127.0.0.1" # Server port # Default: 3000 port = 3000 # Disable authentication (NOT RECOMMENDED for production) # When true, all requests are treated as admin with full access # Default: false # authentication_disabled = false # JWT secret for session tokens (auto-generated if not specified) # IMPORTANT: Set this to a strong random value in production # Generate with: openssl rand -base64 32 # jwt_secret = "your-secret-key-here" # Session timeout in seconds # Default: 86400 (24 hours) # session_timeout_secs = 86400 # Enable CORS (Cross-Origin Resource Sharing) # When enabled with origins, replaces default localhost origins # Default: false # cors_enabled = true # cors_origins = ["http://localhost:5173", "https://app.example.com"] # Enable TLS/HTTPS # tls_enabled = false # tls_cert_path = "/path/to/cert.pem" # tls_key_path = "/path/to/key.pem" ## Photo Management Configuration # These settings control CPU-intensive photo processing features [photos] # Generate perceptual hashes for image duplicate detection. Uses the # DCT (Discrete Cosine Transform) algorithm, which is CPU-intensive, but # enables finding visually similar images (mostly) accurately. # Default: true generate_perceptual_hash = true # Automatically create tags from EXIF keywords # Extracts keywords from photo metadata and creates hierarchical tags # Example: IPTC keyword "Nature/Wildlife/Birds" creates nested tags # Default: false (can create many tags quickly) auto_tag_from_exif = false # Generate multi-resolution thumbnails (tiny, grid, preview) # Creates 3 sizes: 64x64, 320x320, 1024x1024 # Increases storage usage but improves UI performance # Default: false (single thumbnail generated) multi_resolution_thumbnails = false # Enable automatic event/album detection # Groups photos by time and location proximity # Default: false enable_event_detection = false # Minimum number of photos to form an event # Only applies if event detection is enabled # Default: 5 min_event_photos = 5 # Maximum time gap between photos in the same event (in seconds) # Photos taken further apart are considered separate events # Default: 7200 (2 hours) event_time_gap_secs = 7200 # Maximum distance between photos in the same event (in kilometers) # Photos taken further apart geographically are considered separate events # Requires GPS coordinates in photo EXIF data # Default: 1.0 km event_max_distance_km = 1.0 ## Thumbnail Configuration [thumbnails] # Default thumbnail size in pixels (width = height for square thumbnails) # Default: 320 size = 320 # JPEG quality for thumbnails (1-100, higher = better quality but larger files) # Default: 80 quality = 80 # Path to ffmpeg binary for video thumbnails (auto-detected if not specified) # ffmpeg_path = "/usr/bin/ffmpeg" # Video thumbnail seek position in seconds # Extracts frame at this timestamp for video thumbnails # Default: 2 video_seek_secs = 2 ## User Interface Configuration [ui] # UI theme: "dark" or "light" # Default: "dark" theme = "dark" # Default view: "library", "search", "collections", etc. # Default: "library" default_view = "library" # Default number of items per page # Default: 50 default_page_size = 50 # Default view mode: "grid" or "table" # Default: "grid" default_view_mode = "grid" # Auto-play media when selected # Default: false auto_play_media = false # Show thumbnails in views (disable for faster loading with large libraries) # Default: true show_thumbnails = true # Start with sidebar collapsed # Default: false sidebar_collapsed = false ## User Accounts & Authentication [accounts] # Session expiry in hours # Default: 24 # session_expiry_hours = 24 # Require email verification for new accounts # Default: false # require_email_verification = false # Allow user self-registration # Default: true # allow_registration = true # Default role for new users: "viewer", "editor", "admin" # Default: "viewer" # default_role = "viewer" # Password minimum length # Default: 8 # password_min_length = 8 # Maximum failed login attempts before temporary lockout # Default: 5 # max_failed_logins = 5 # Lockout duration in seconds after max failed logins # Default: 900 (15 minutes) # lockout_duration_secs = 900 ## Rate Limiting Configuration ## All rate limits are per-IP. Values control token bucket parameters: ## per_second = interval in seconds between token replenishment ## burst_size = maximum tokens (concurrent requests) allowed # [rate_limits] # global_per_second = 1 # ~100 req/sec with burst_size=100 # global_burst_size = 100 # login_per_second = 12 # ~5 req/min with burst_size=5 # login_burst_size = 5 # search_per_second = 6 # ~10 req/min with burst_size=10 # search_burst_size = 10 # stream_per_second = 60 # 1 per minute, max 5 concurrent # stream_burst_size = 5 # share_per_second = 2 # Share token access rate limit # share_burst_size = 20 ## Background Jobs Configuration [jobs] # Number of concurrent background job workers # Default: 2 worker_count = 2 # Job result cache TTL in seconds # Default: 60 cache_ttl_secs = 60 # Maximum time a job can run before being cancelled (in seconds) # Set to 0 to disable timeout # Default: 3600 (1 hour) # job_timeout_secs = 3600 ## Metadata Enrichment Configuration [enrichment] # Enable automatic metadata enrichment from online sources # Default: false enabled = false # Automatically enrich new books with ISBN lookups # Default: false # auto_enrich_new_books = false # Automatically enrich music with MusicBrainz/Last.fm # Default: false # auto_enrich_new_music = false # [enrichment.sources] # # OpenLibrary (books) - No API key required # [enrichment.sources.openlibrary] # enabled = true # # # Google Books API (books) - Optional API key for higher rate limits # [enrichment.sources.googlebooks] # enabled = true # api_key = "your-google-books-api-key" # # # TMDb (movies/TV) - Requires API key from themoviedb.org # [enrichment.sources.tmdb] # enabled = false # api_key = "${TMDB_API_KEY}" # Or hardcode: "your-tmdb-api-key" # # # Last.fm (music) - Requires API key from last.fm/api # [enrichment.sources.lastfm] # enabled = false # api_key = "${LASTFM_API_KEY}" ## Plugin Configuration [plugins] # Enable plugin system # Default: false # enabled = false # Directories to scan for plugins (each containing a plugin.toml + .wasm binary) # Default: [] # plugin_dirs = ["/etc/pinakes/plugins", "~/.local/share/pinakes/plugins"] # Allow loading unsigned plugins (disable in production to enforce signatures) # Default: false # allow_unsigned = false # Hex-encoded Ed25519 public keys trusted for plugin signature verification. # Plugins must ship a plugin.sig (Ed25519 signature over the BLAKE3 hash of the # WASM binary). If allow_unsigned is false and no trusted keys match, the plugin # is rejected. # Default: [] # trusted_keys = [ # "a1b2c3d4e5f6...64_hex_chars...", # ] # Maximum concurrent plugin operations (e.g., parallel metadata extraction) # Default: 4 # max_concurrent_ops = 4 # Global plugin timeout in seconds (legacy, prefer per-tier timeouts below) # Default: 30 # plugin_timeout_secs = 30 # Circuit breaker: auto-disable a plugin after this many consecutive failures # A successful call resets the counter. Reload or toggle to re-enable. # Default: 5 # max_consecutive_failures = 5 # Per-tier timeout configuration # [plugins.timeouts] # Timeout for capability queries (supported_types, interested_events, can_handle) # Default: 2 # capability_query_secs = 2 # # Timeout for processing calls (extract_metadata, generate_thumbnail) # Default: 30 # processing_secs = 30 # # Timeout for event handler calls (handle_event) # Default: 10 # event_handler_secs = 10 ## Transcoding Configuration [transcoding] # Enable on-the-fly media transcoding for streaming # Default: false # enabled = false # Path to ffmpeg binary # ffmpeg_path = "/usr/bin/ffmpeg" # Default video codec: "h264", "h265", "vp9", "av1" # video_codec = "h264" # Default audio codec: "aac", "opus", "vorbis", "mp3" # audio_codec = "aac" # Video bitrate in kbps # video_bitrate_kbps = 2000 # Audio bitrate in kbps # audio_bitrate_kbps = 128 ## Cloud Sync Configuration [cloud] # Enable cloud storage sync # Default: false enabled = false # Automatic sync interval in minutes # Default: 60 # auto_sync_interval_mins = 60 # Cloud storage accounts # [[cloud.accounts]] # provider = "s3" # "s3", "gcs", "azure", "webdav" # name = "My S3 Bucket" # bucket = "my-media-bucket" # region = "us-east-1" # access_key = "${AWS_ACCESS_KEY_ID}" # secret_key = "${AWS_SECRET_ACCESS_KEY}" ## Analytics Configuration [analytics] # Enable usage analytics and statistics tracking # Default: false enabled = false # Track individual media view/play events # Default: true (if analytics enabled) # track_usage = true # How long to retain analytics data (in days) # Default: 90 # retention_days = 90 ## Webhook Configuration # Send HTTP notifications for events. # Supported events: media.created, media.updated, media.deleted, # scan.completed, import.completed, test # Use "*" to receive all events. # [[webhooks]] # url = "https://example.com/webhook" # events = ["media.created", "media.deleted", "scan.completed"] # secret = "webhook-secret-for-signature" # Optional BLAKE3 HMAC secret ## Scheduled Tasks # Configure periodic background tasks # [[scheduled_tasks]] # id = "nightly_vacuum" # enabled = true # # Cron-style schedule (minute hour day month weekday) # schedule = "0 3 * * *" # Run at 3 AM daily # [[scheduled_tasks]] # id = "weekly_integrity_check" # enabled = false # schedule = "0 4 * * 0" # Run at 4 AM every Sunday