6da1e6fd81
- Add LOG_FORMAT setting (text/json) for structured JSON log output - Add LOG_SYSLOG_* settings for direct syslog forwarding of app logs - JSON format compatible with Grafana Loki, Splunk, ELK, Datadog - Syslog forwarding uses Python's SysLogHandler (UDP/TCP) - Update .env.demo and ConfigurationGuide.md with all new settings - Add tests for JSON formatter and syslog config fields Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
610 lines
28 KiB
Bash
610 lines
28 KiB
Bash
# **Core Settings**
|
||
WORKDIR=/workdir
|
||
DATABASE_URL=sqlite:///./app/database.db
|
||
REDIS_URL=redis://redis:6379/0
|
||
EXTERNAL_HOSTNAME=docuelevate.example.com
|
||
GOTENBERG_URL=http://gotenberg:3000
|
||
ALLOW_FILE_DELETE=true # Allow deletion of file records
|
||
COMPLIANCE_ENABLED=true # Enable compliance templates dashboard (GDPR, HIPAA, SOC 2)
|
||
|
||
# **Logging**
|
||
# LOG_LEVEL controls the Python root-logger level.
|
||
# Accepted values: DEBUG, INFO, WARNING, ERROR, CRITICAL (default: INFO).
|
||
# When DEBUG=true and LOG_LEVEL is not set, the level is automatically lowered to DEBUG.
|
||
# LOG_LEVEL=INFO
|
||
# DEBUG=false
|
||
|
||
# Log output format: "text" (human-readable, default) or "json" (structured JSON lines).
|
||
# Use "json" when shipping logs to Grafana Loki, Splunk, ELK, Datadog, or any SIEM.
|
||
# LOG_FORMAT=text
|
||
|
||
# Forward application logs to a syslog receiver (in addition to stdout).
|
||
# Useful for traditional (non-container) deployments and centralised SIEM ingestion.
|
||
# LOG_SYSLOG_ENABLED=false
|
||
# LOG_SYSLOG_HOST=localhost
|
||
# LOG_SYSLOG_PORT=514
|
||
# LOG_SYSLOG_PROTOCOL=udp # udp | tcp
|
||
|
||
# **UI / Appearance**
|
||
# Default colour scheme: system (follow OS), light, or dark
|
||
# Individual users can always override with the navbar dark-mode toggle.
|
||
# UI_DEFAULT_COLOR_SCHEME=system
|
||
|
||
# **Batch Processing Settings**
|
||
# Control throttling behavior for the /processall endpoint to prevent overwhelming downstream APIs
|
||
PROCESSALL_THROTTLE_THRESHOLD=20 # Number of files above which throttling is applied (default: 20)
|
||
PROCESSALL_THROTTLE_DELAY=3 # Delay in seconds between each task submission when throttling (default: 3)
|
||
|
||
# **Task Retry Settings**
|
||
# Failed tasks are automatically retried with exponential backoff and jitter.
|
||
# TASK_RETRY_MAX_RETRIES=3 # Max retry attempts per task (default: 3)
|
||
# TASK_RETRY_DELAYS=60,300,900 # Countdown (seconds) before each retry; 1 min, 5 min, 15 min
|
||
# TASK_RETRY_JITTER=true # Add ±20% random jitter to prevent thundering-herd (default: true)
|
||
|
||
# **Client-Side Upload Throttling**
|
||
# Controls pacing when the browser uploads files (especially large directory drops).
|
||
# The browser auto-detects rate-limit (HTTP 429) responses and backs off accordingly.
|
||
UPLOAD_CONCURRENCY=3 # Max simultaneous uploads from the browser (default: 3)
|
||
UPLOAD_QUEUE_DELAY_MS=500 # Delay (ms) between starting each upload slot (default: 500)
|
||
|
||
# **File Upload Size Limits** (Security - see SECURITY_AUDIT.md)
|
||
# Maximum file upload size in bytes. Default: 1GB (1073741824 bytes)
|
||
# Prevents resource exhaustion attacks. Adjust based on your server capacity.
|
||
MAX_UPLOAD_SIZE=1073741824
|
||
|
||
# Maximum size for a single file chunk in bytes (optional)
|
||
# If set and a file exceeds this size, it will be split into smaller chunks for processing
|
||
# Default: None (no splitting). Example: 104857600 for 100MB chunks
|
||
# MAX_SINGLE_FILE_SIZE=104857600
|
||
|
||
# **Request Body Size Limit** (Security - see SECURITY_AUDIT.md)
|
||
# Maximum request body size in bytes for non-file-upload requests (JSON, form data, etc.).
|
||
# Default: 1MB (1048576 bytes). File uploads are governed by MAX_UPLOAD_SIZE above.
|
||
# Prevents memory exhaustion from oversized JSON/form payloads.
|
||
# MAX_REQUEST_BODY_SIZE=1048576
|
||
|
||
# **Security Headers** (see SECURITY_AUDIT.md and docs/DeploymentGuide.md)
|
||
# Disabled by default since most deployments use a reverse proxy (Traefik, Nginx, etc.)
|
||
# that already adds these headers. Set to true only if deploying directly without a reverse proxy.
|
||
# SECURITY_HEADERS_ENABLED=false
|
||
|
||
# If you enable security headers, you can also configure individual headers:
|
||
# Strict-Transport-Security (HSTS) - Forces HTTPS connections
|
||
# Only effective when served over HTTPS. Disable if not using HTTPS or if proxy adds this header
|
||
# SECURITY_HEADER_HSTS_ENABLED=true
|
||
# SECURITY_HEADER_HSTS_VALUE="max-age=31536000; includeSubDomains"
|
||
|
||
# Content-Security-Policy (CSP) - Controls resource loading
|
||
# Customize based on your application's resource loading needs
|
||
# Default allows self-hosted resources, inline scripts/styles, and external images
|
||
# SECURITY_HEADER_CSP_ENABLED=true
|
||
# SECURITY_HEADER_CSP_VALUE="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;"
|
||
|
||
# X-Frame-Options - Prevents clickjacking attacks
|
||
# Options: DENY (no framing), SAMEORIGIN (same origin framing only), ALLOW-FROM uri
|
||
# SECURITY_HEADER_X_FRAME_OPTIONS_ENABLED=true
|
||
# SECURITY_HEADER_X_FRAME_OPTIONS_VALUE="DENY"
|
||
|
||
# X-Content-Type-Options - Prevents MIME sniffing
|
||
# Always set to 'nosniff' when enabled
|
||
# SECURITY_HEADER_X_CONTENT_TYPE_OPTIONS_ENABLED=true
|
||
|
||
# **CORS (Cross-Origin Resource Sharing)** (see SECURITY_AUDIT.md – Infrastructure Security)
|
||
# Disabled by default: most deployments rely on a reverse proxy (Traefik, Nginx, etc.) to inject
|
||
# CORS headers. Set CORS_ENABLED=true only if DocuElevate is exposed directly without a proxy,
|
||
# or if your proxy does not handle CORS. When enabled, only list the exact origins that need access.
|
||
#
|
||
# Rationale for reverse-proxy-first approach:
|
||
# Traefik/Nginx already set Access-Control-Allow-Origin (and related headers) for every response,
|
||
# so adding the middleware here would duplicate headers. When this flag is False the application
|
||
# trusts the proxy layer to enforce CORS policy; set it to True for standalone / direct-access
|
||
# deployments only.
|
||
#
|
||
# CORS_ENABLED=false
|
||
#
|
||
# Comma-separated list of allowed origins (use * to allow all - not recommended with credentials)
|
||
# CORS_ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com
|
||
#
|
||
# Allow cookies / Authorization headers in cross-origin requests
|
||
# Must be False when CORS_ALLOWED_ORIGINS=* (browser security requirement)
|
||
# CORS_ALLOW_CREDENTIALS=false
|
||
#
|
||
# Allowed HTTP methods (comma-separated)
|
||
# CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS,PATCH
|
||
#
|
||
# Allowed request headers (use * to allow all)
|
||
# CORS_ALLOWED_HEADERS=*
|
||
|
||
# **Audit Logging & SIEM Integration** (see docs/ConfigurationGuide.md#audit-logging)
|
||
# Enable HTTP request audit logging middleware
|
||
AUDIT_LOGGING_ENABLED=true
|
||
# Include client IP in audit log entries (disable for GDPR-sensitive deployments)
|
||
AUDIT_LOG_INCLUDE_CLIENT_IP=true
|
||
|
||
# Forward audit events to an external SIEM system (Syslog, Splunk, Logstash, Grafana, etc.)
|
||
# AUDIT_SIEM_ENABLED=false
|
||
# AUDIT_SIEM_TRANSPORT=syslog # syslog | http
|
||
# AUDIT_SIEM_SYSLOG_HOST=localhost
|
||
# AUDIT_SIEM_SYSLOG_PORT=514
|
||
# AUDIT_SIEM_SYSLOG_PROTOCOL=udp # udp | tcp
|
||
# AUDIT_SIEM_HTTP_URL= # e.g. https://splunk:8088/services/collector/event
|
||
# AUDIT_SIEM_HTTP_TOKEN= # Bearer / HEC token
|
||
# AUDIT_SIEM_HTTP_CUSTOM_HEADERS= # Comma-separated Key:Value pairs
|
||
|
||
# **Rate Limiting** (see SECURITY_AUDIT.md and docs/API.md)
|
||
# Protects against DoS attacks and API abuse by limiting request rates per IP/user
|
||
# Enabled by default - highly recommended for production
|
||
RATE_LIMITING_ENABLED=true
|
||
|
||
# Default rate limit for all API endpoints (format: count/period)
|
||
# Periods can be: second, minute, hour, day
|
||
# Default: 100 requests per minute per IP/user
|
||
RATE_LIMIT_DEFAULT=100/minute
|
||
|
||
# Rate limit for file upload endpoints
|
||
# Allows faster uploads while still preventing abuse
|
||
# Default: 600 uploads per minute per IP/user
|
||
RATE_LIMIT_UPLOAD=600/minute
|
||
|
||
# Rate limit for authentication endpoints
|
||
# Strict limit to prevent brute force attacks
|
||
# Default: 10 attempts per minute per IP
|
||
RATE_LIMIT_AUTH=10/minute
|
||
|
||
# Note: Processing endpoints (OCR, metadata extraction) use built-in queue throttling
|
||
# via Celery task queue to control processing rates and prevent upstream API overloads.
|
||
# No additional API-level rate limit is needed for processing endpoints.
|
||
|
||
# **Authentication**
|
||
AUTH_ENABLED=true
|
||
# Generate a secure random string, for example:
|
||
# python -c "import secrets; print(secrets.token_hex(32))"
|
||
SESSION_SECRET=b39fd43f68d0491ca942f28a16e484b1e763fe9accf4445ca2669a5f3b179eb4
|
||
ADMIN_USERNAME=admin
|
||
ADMIN_PASSWORD=your_secure_password
|
||
ADMIN_GROUP_NAME=admin
|
||
|
||
# **Multi-User Mode**
|
||
# When enabled, each user has their own document space with isolated uploads,
|
||
# search, and file management. Requires AUTH_ENABLED=true.
|
||
MULTI_USER_ENABLED=false
|
||
# Allow users to self-register with an email address and password.
|
||
# Set to true to enable the /signup page. Requires MULTI_USER_ENABLED=true.
|
||
# When SMTP is configured, a verification email is sent before the account is activated.
|
||
# Without SMTP, accounts are activated immediately upon registration.
|
||
# ALLOW_LOCAL_SIGNUP=false
|
||
# Default upload limit per user per day (0 = unlimited)
|
||
DEFAULT_DAILY_UPLOAD_LIMIT=0
|
||
# Show unowned documents (owner_id=NULL) to all users (true) or only admins (false)
|
||
UNOWNED_DOCS_VISIBLE_TO_ALL=true
|
||
# Auto-assign this owner ID to documents ingested without a session (e.g. IMAP, API)
|
||
# Leave empty/unset to keep them unowned until claimed.
|
||
# DEFAULT_OWNER_ID=
|
||
|
||
# **Subscription / Quota Settings**
|
||
# Soft-limit overage buffer in percent (0–200). Announced quota is multiplied by (1 + percent/100)
|
||
# for actual enforcement. E.g. 20 means a 150-doc/month plan enforces at 180. 0 = enforce exactly.
|
||
# Per-plan overage_percent set in the Plan Designer overrides this global default.
|
||
# SUBSCRIPTION_OVERAGE_PERCENT=20
|
||
|
||
# **OpenID Connect/Authentik Settings**
|
||
AUTHENTIK_CLIENT_ID=<yourAuthentikAppClientID>
|
||
AUTHENTIK_CLIENT_SECRET=<yourAuthentikClientSecret>
|
||
AUTHENTIK_CONFIG_URL=<ConfigUrlOfYourApp, e.g. https://authentik.example.com/application/o/docuelevate/.well-known/openid-configuration>
|
||
OAUTH_PROVIDER_NAME="Authentik SSO"
|
||
|
||
# **Social Login Providers**
|
||
# Enable one or more social login providers to let users sign in with existing accounts.
|
||
# Each provider requires separate OAuth credentials. See docs/SocialLoginSetup.md for details.
|
||
|
||
# Google Sign-In (https://console.cloud.google.com/apis/credentials)
|
||
# SOCIAL_AUTH_GOOGLE_ENABLED=false
|
||
# SOCIAL_AUTH_GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
|
||
# SOCIAL_AUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret
|
||
|
||
# Microsoft Sign-In / Azure AD (https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps)
|
||
# SOCIAL_AUTH_MICROSOFT_ENABLED=false
|
||
# SOCIAL_AUTH_MICROSOFT_CLIENT_ID=your-microsoft-application-id
|
||
# SOCIAL_AUTH_MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret
|
||
# SOCIAL_AUTH_MICROSOFT_TENANT=common # common | organizations | consumers | <tenant-id>
|
||
|
||
# Apple Sign-In (https://developer.apple.com/account/resources)
|
||
# SOCIAL_AUTH_APPLE_ENABLED=false
|
||
# SOCIAL_AUTH_APPLE_CLIENT_ID=com.example.docuelevate
|
||
# SOCIAL_AUTH_APPLE_TEAM_ID=ABCDE12345
|
||
# SOCIAL_AUTH_APPLE_KEY_ID=FGHIJ67890
|
||
# SOCIAL_AUTH_APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
|
||
|
||
# Dropbox Sign-In (https://www.dropbox.com/developers/apps)
|
||
# SOCIAL_AUTH_DROPBOX_ENABLED=false
|
||
# SOCIAL_AUTH_DROPBOX_CLIENT_ID=your-dropbox-app-key
|
||
# SOCIAL_AUTH_DROPBOX_CLIENT_SECRET=your-dropbox-app-secret
|
||
|
||
# **AI/ML Services**
|
||
# Select your AI provider: openai | azure | anthropic | gemini | ollama | openrouter | portkey | litellm
|
||
AI_PROVIDER=openai
|
||
# Model override (optional – falls back to OPENAI_MODEL when not set)
|
||
# AI_MODEL=gpt-4o-mini
|
||
|
||
# --- OpenAI (AI_PROVIDER=openai) ---
|
||
OPENAI_API_KEY="<OPENAI_API_KEY>"
|
||
OPENAI_BASE_URL=https://api.openai.com/v1
|
||
OPENAI_MODEL=gpt-4o-mini
|
||
|
||
# --- Anthropic Claude (AI_PROVIDER=anthropic) ---
|
||
# ANTHROPIC_API_KEY=sk-ant-...
|
||
# AI_MODEL=claude-3-5-sonnet-20241022
|
||
|
||
# --- Google Gemini (AI_PROVIDER=gemini) ---
|
||
# GEMINI_API_KEY=AIza...
|
||
# AI_MODEL=gemini-1.5-pro
|
||
|
||
# --- Ollama local LLMs (AI_PROVIDER=ollama) ---
|
||
# OLLAMA_BASE_URL=http://localhost:11434
|
||
# AI_MODEL=llama3.2
|
||
|
||
# --- OpenRouter (AI_PROVIDER=openrouter) ---
|
||
# OPENROUTER_API_KEY=sk-or-...
|
||
# AI_MODEL=anthropic/claude-3.5-sonnet
|
||
|
||
# --- Portkey AI Gateway (AI_PROVIDER=portkey) ---
|
||
# PORTKEY_API_KEY=pk-...
|
||
# PORTKEY_VIRTUAL_KEY=vk-... # optional – routes to provider credentials in Portkey vault
|
||
# PORTKEY_CONFIG=pc-... # optional – saved Config ID for fallbacks / load balancing
|
||
|
||
# --- Azure OpenAI (AI_PROVIDER=azure) ---
|
||
# OPENAI_API_KEY=<azure-key>
|
||
# OPENAI_BASE_URL=https://my-resource.openai.azure.com
|
||
# AZURE_OPENAI_API_VERSION=2024-02-01
|
||
# AI_MODEL=gpt-4o # deployment name in Azure
|
||
|
||
# Azure Document Intelligence (OCR – separate from AI provider above)
|
||
# **Email Settings (shared SMTP – password reset, verification, and system notifications)**
|
||
EMAIL_HOST=smtp.example.com
|
||
EMAIL_PORT=587
|
||
EMAIL_USERNAME=docuelevate@example.com
|
||
EMAIL_PASSWORD=your_secure_email_password
|
||
EMAIL_USE_TLS=True
|
||
EMAIL_SENDER=DocuElevate System <docuelevate@example.com>
|
||
# EMAIL_DEFAULT_RECIPIENT is not used for document delivery (see DEST_EMAIL_* below)
|
||
|
||
# **Email Destination Settings (dedicated SMTP for document delivery)**
|
||
# These settings are intentionally separate from the shared EMAIL_* settings above.
|
||
# Configuring EMAIL_HOST for password reset / notifications does NOT automatically
|
||
# enable the email destination – you must set DEST_EMAIL_HOST to activate it.
|
||
# DEST_EMAIL_ENABLED=true # Set to false to disable email delivery without removing credentials
|
||
DEST_EMAIL_HOST=smtp.example.com
|
||
DEST_EMAIL_PORT=587
|
||
DEST_EMAIL_USERNAME=docuelevate@example.com
|
||
DEST_EMAIL_PASSWORD=your_secure_email_password
|
||
DEST_EMAIL_USE_TLS=True
|
||
DEST_EMAIL_SENDER=DocuElevate Delivery <docuelevate@example.com>
|
||
DEST_EMAIL_DEFAULT_RECIPIENT=recipient@example.com
|
||
|
||
# **Watch Folder Ingestion**
|
||
# DocuElevate can automatically monitor directories (local, FTP, SFTP, and cloud providers) for new files.
|
||
#
|
||
# Local watch folders — works with any mounted path (SMB/CIFS, NFS, local disk, etc.)
|
||
# Set WATCH_FOLDERS to a comma-separated list of absolute paths inside the container.
|
||
WATCH_FOLDERS=
|
||
WATCH_FOLDER_POLL_INTERVAL=1
|
||
WATCH_FOLDER_DELETE_AFTER_PROCESS=false
|
||
|
||
# FTP ingest — poll an FTP directory for new files (uses FTP connection settings above)
|
||
FTP_INGEST_ENABLED=false
|
||
FTP_INGEST_FOLDER=
|
||
FTP_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# SFTP ingest — poll an SFTP directory for new files (uses SFTP connection settings above)
|
||
SFTP_INGEST_ENABLED=false
|
||
SFTP_INGEST_FOLDER=
|
||
SFTP_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# Dropbox ingest — poll a Dropbox folder (uses Dropbox OAuth credentials above)
|
||
DROPBOX_INGEST_ENABLED=false
|
||
DROPBOX_INGEST_FOLDER=
|
||
DROPBOX_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# Google Drive ingest — poll a Google Drive folder (uses Google Drive credentials above)
|
||
GOOGLE_DRIVE_INGEST_ENABLED=false
|
||
GOOGLE_DRIVE_INGEST_FOLDER_ID=
|
||
GOOGLE_DRIVE_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# OneDrive ingest — poll a OneDrive folder (uses OneDrive MSAL credentials above)
|
||
ONEDRIVE_INGEST_ENABLED=false
|
||
ONEDRIVE_INGEST_FOLDER_PATH=
|
||
ONEDRIVE_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# Nextcloud ingest — poll a Nextcloud folder (uses Nextcloud WebDAV credentials above)
|
||
NEXTCLOUD_INGEST_ENABLED=false
|
||
NEXTCLOUD_INGEST_FOLDER=
|
||
NEXTCLOUD_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# Amazon S3 ingest — poll an S3 prefix (uses S3/AWS credentials above)
|
||
S3_INGEST_ENABLED=false
|
||
S3_INGEST_PREFIX=
|
||
S3_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# WebDAV ingest — poll a WebDAV folder (uses WebDAV credentials above)
|
||
WEBDAV_INGEST_ENABLED=false
|
||
WEBDAV_INGEST_FOLDER=
|
||
WEBDAV_INGEST_DELETE_AFTER_PROCESS=false
|
||
|
||
# **IMAP Settings**
|
||
# DocuElevate polls these mailboxes for new email attachments and automatically ingests them.
|
||
# No manual forwarding required — DocuElevate acts as an IMAP *client*.
|
||
# For HP Scanners / Scan-to-Email: configure the scanner to send to a dedicated mailbox,
|
||
# then point DocuElevate at that mailbox using the settings below.
|
||
IMAP1_HOST=mail.example.com
|
||
IMAP1_PORT=993
|
||
IMAP1_USERNAME=<IMAP1_USERNAME>
|
||
IMAP1_PASSWORD=<IMAP1_PASSWORD>
|
||
IMAP1_SSL=true
|
||
IMAP1_POLL_INTERVAL_MINUTES=5
|
||
IMAP1_DELETE_AFTER_PROCESS=false
|
||
|
||
IMAP2_HOST=imap.gmail.com
|
||
IMAP2_PORT=993
|
||
IMAP2_USERNAME=<IMAP2_USERNAME>
|
||
IMAP2_PASSWORD=<IMAP2_PASSWORD>
|
||
IMAP2_SSL=true
|
||
IMAP2_POLL_INTERVAL_MINUTES=10
|
||
IMAP2_DELETE_AFTER_PROCESS=false
|
||
|
||
# IMAP Readonly Mode (Feature Flag)
|
||
# When true, IMAP processing will fetch and process attachments but will NOT modify
|
||
# the mailbox state (no starring, labeling, deleting, or flag changes).
|
||
# Use for pre-production instances that share a mailbox with production.
|
||
IMAP_READONLY_MODE=false
|
||
|
||
# Controls which attachment types are ingested from IMAP emails.
|
||
# 'documents_only' (default) – PDFs and office files only; images are skipped.
|
||
# 'all' – all supported file types including images.
|
||
# Per-user IMAP accounts can override this global default.
|
||
IMAP_ATTACHMENT_FILTER=documents_only
|
||
|
||
# **Storage/Document Services**
|
||
# Amazon S3
|
||
# S3_ENABLED=true # Set to false to disable S3 uploads without removing credentials
|
||
AWS_REGION=us-east-1
|
||
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
|
||
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||
S3_BUCKET_NAME=my-document-bucket
|
||
S3_FOLDER_PREFIX=documents/uploads/2023/ # Organizes files in this subfolder
|
||
S3_STORAGE_CLASS=STANDARD
|
||
S3_ACL=private
|
||
|
||
# NextCloud
|
||
# NEXTCLOUD_ENABLED=true # Set to false to disable NextCloud uploads without removing credentials
|
||
NEXTCLOUD_UPLOAD_URL=https://nextcloud.example.com/remote.php/dav/files/<USERNAME>
|
||
NEXTCLOUD_FOLDER="<NEXTCLOUD_FOLDER_PATH>"
|
||
NEXTCLOUD_USERNAME=<NEXTCLOUD_USERNAME>
|
||
NEXTCLOUD_PASSWORD=<NEXTCLOUD_PASSWORD>
|
||
|
||
# Paperless-ngx
|
||
# PAPERLESS_ENABLED=true # Set to false to disable Paperless uploads without removing credentials
|
||
PAPERLESS_HOST=https://paperless.example.com
|
||
PAPERLESS_NGX_API_TOKEN=<PAPERLESS_API_TOKEN>
|
||
# Optional: Name of the custom field in Paperless-ngx to store the "absender" (sender) value
|
||
# If set, the extracted sender information will be automatically set as a custom field in Paperless
|
||
# Example: PAPERLESS_CUSTOM_FIELD_ABSENDER=Absender
|
||
# PAPERLESS_CUSTOM_FIELD_ABSENDER=
|
||
|
||
# Optional: JSON mapping of metadata fields to Paperless custom field names
|
||
# This allows you to map multiple extracted metadata fields to custom fields in Paperless
|
||
# The mapping format is: {"metadata_field_name": "PaperlessCustomFieldName", ...}
|
||
# Available metadata fields: absender, empfaenger, correspondent, document_type, language,
|
||
# kommunikationsart, kommunikationskategorie, reference_number, etc.
|
||
# Example: PAPERLESS_CUSTOM_FIELDS_MAPPING={"absender": "Sender", "empfaenger": "Recipient", "language": "Language", "correspondent": "Correspondent"}
|
||
# PAPERLESS_CUSTOM_FIELDS_MAPPING=
|
||
|
||
# Dropbox
|
||
# DROPBOX_ENABLED=true # Set to false to disable Dropbox uploads without removing credentials
|
||
DROPBOX_APP_KEY=<DROPBOX_APP_KEY>
|
||
DROPBOX_APP_SECRET=<DROPBOX_APP_SECRET>
|
||
DROPBOX_REFRESH_TOKEN=<DROPBOX_REFRESH_TOKEN>
|
||
DROPBOX_FOLDER="/Documents/Uploads"
|
||
|
||
# Google Drive
|
||
# GOOGLE_DRIVE_ENABLED=true # Set to false to disable Google Drive uploads without removing credentials
|
||
# Service Account Method:
|
||
GOOGLE_DRIVE_CREDENTIALS_JSON={"type":"service_account","project_id":"your-project","private_key_id":"key-id","private_key":"-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY\n-----END PRIVATE KEY-----\n","client_email":"service-account@project.iam.gserviceaccount.com","client_id":"client-id","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/service-account%40project.iam.gserviceaccount.com"}
|
||
GOOGLE_DRIVE_FOLDER_ID=<YOUR_FOLDER_ID>
|
||
GOOGLE_DRIVE_DELEGATE_TO=<OPTIONAL_USER_EMAIL>
|
||
|
||
# OAuth Method (Alternative):
|
||
GOOGLE_DRIVE_USE_OAUTH=false # Set to true to use OAuth instead of service account
|
||
GOOGLE_DRIVE_CLIENT_ID=your-oauth-client-id # Required for OAuth method
|
||
GOOGLE_DRIVE_CLIENT_SECRET=your-oauth-client-secret # Required for OAuth method
|
||
GOOGLE_DRIVE_REFRESH_TOKEN=your-oauth-refresh-token # Required for OAuth method
|
||
|
||
# OneDrive
|
||
# ONEDRIVE_ENABLED=true # Set to false to disable OneDrive uploads without removing credentials
|
||
ONEDRIVE_CLIENT_ID=your-client-id
|
||
ONEDRIVE_CLIENT_SECRET=your-client-secret
|
||
ONEDRIVE_TENANT_ID=common
|
||
ONEDRIVE_REFRESH_TOKEN=your-refresh-token
|
||
ONEDRIVE_FOLDER_PATH=Documents/Uploads
|
||
|
||
# WebDAV
|
||
# WEBDAV_ENABLED=true # Set to false to disable WebDAV uploads without removing credentials
|
||
WEBDAV_URL=https://webdav.example.com/path
|
||
WEBDAV_USERNAME=webdav_user
|
||
WEBDAV_PASSWORD=your_secure_webdav_password
|
||
WEBDAV_FOLDER=/Documents/Uploads
|
||
WEBDAV_VERIFY_SSL=True
|
||
|
||
# FTP
|
||
# FTP_ENABLED=true # Set to false to disable FTP uploads without removing credentials
|
||
# Security Note: FTP_USE_TLS=True is strongly recommended for secure connections
|
||
# Set FTP_ALLOW_PLAINTEXT=False in production to prevent unencrypted FTP
|
||
FTP_HOST=ftp.example.com
|
||
FTP_PORT=21
|
||
FTP_USERNAME=ftp_user
|
||
FTP_PASSWORD=your_secure_ftp_password
|
||
FTP_FOLDER=/Documents/Uploads
|
||
FTP_USE_TLS=True
|
||
FTP_ALLOW_PLAINTEXT=True
|
||
|
||
# SFTP
|
||
# SFTP_ENABLED=true # Set to false to disable SFTP uploads without removing credentials
|
||
# Security Note: Host key verification is enabled by default (False)
|
||
# Only set to True in development/testing environments if needed
|
||
# When false, configure SSH known_hosts for proper host key verification
|
||
SFTP_HOST=sftp.example.com
|
||
SFTP_PORT=22
|
||
SFTP_USERNAME=sftp_user
|
||
SFTP_PASSWORD=your_secure_sftp_password
|
||
# SFTP_PRIVATE_KEY=/path/to/private_key.pem
|
||
# SFTP_PRIVATE_KEY_PASSPHRASE=optional_passphrase
|
||
SFTP_FOLDER=/Documents/Uploads
|
||
SFTP_DISABLE_HOST_KEY_VERIFICATION=False # Default is False (secure); set to True only for testing
|
||
|
||
# iCloud Drive
|
||
# ICLOUD_ENABLED=true # Set to false to disable iCloud uploads without removing credentials
|
||
# Requires an Apple ID with iCloud Drive enabled.
|
||
# For accounts with two-factor authentication (most accounts), generate an
|
||
# app-specific password at https://appleid.apple.com/account/manage
|
||
ICLOUD_USERNAME=your_apple_id@example.com
|
||
ICLOUD_PASSWORD=your-app-specific-password
|
||
ICLOUD_FOLDER=Documents/Uploads
|
||
# ICLOUD_COOKIE_DIRECTORY=/path/to/cookie/dir # Optional: defaults to ~/.pyicloud
|
||
|
||
# **HTTP Request Settings**
|
||
# Timeout for HTTP requests - set higher to handle large PDF files (up to 1GB)
|
||
HTTP_REQUEST_TIMEOUT=120 # Timeout in seconds (default: 120 for large file operations)
|
||
|
||
# **Notification Settings**
|
||
# Configure notification services using Apprise URL format
|
||
# See https://github.com/caronc/apprise#supported-notifications
|
||
# Examples:
|
||
# - Discord: discord://webhook_id/webhook_token
|
||
# - Telegram: tgram://bot_token/chat_id
|
||
# - Email: mailto://user:pass@example.com
|
||
# - Pushover: pover://user_key/app_token
|
||
# - Slack: slack://tokenA/tokenB/tokenC
|
||
# - Matrix: matrix://username:password@domain/#room
|
||
|
||
# You can specify multiple notification URLs by separating them with commas
|
||
NOTIFICATION_URLS=discord://webhook_id/webhook_token,mailto://user:pass@gmail.com,tgram://bot_token/chat_id
|
||
|
||
# Control when notifications are sent
|
||
NOTIFY_ON_TASK_FAILURE=True
|
||
NOTIFY_ON_CREDENTIAL_FAILURE=True
|
||
NOTIFY_ON_STARTUP=True
|
||
NOTIFY_ON_SHUTDOWN=False
|
||
NOTIFY_ON_FILE_PROCESSED=True
|
||
|
||
# Webhooks – Notify external systems via HTTP POST on document events.
|
||
# Individual webhooks (URL, events, secret) are managed via /api/webhooks/.
|
||
WEBHOOK_ENABLED=True
|
||
|
||
# Uptime Kuma
|
||
UPTIME_KUMA_URL=https://status.example.com/api/push/abcdef123456?status=up
|
||
UPTIME_KUMA_PING_INTERVAL=5
|
||
|
||
# Backup & Restore
|
||
# Enable automatic scheduled backups (hourly, daily, weekly)
|
||
BACKUP_ENABLED=True
|
||
# Directory for local backup archives (defaults to <WORKDIR>/backups)
|
||
# BACKUP_DIR=/data/backups
|
||
# Optional remote destination: s3, dropbox, google_drive, onedrive, nextcloud, webdav, ftp, sftp, email
|
||
# BACKUP_REMOTE_DESTINATION=s3
|
||
# Sub-folder used when uploading backup archives to the remote destination
|
||
BACKUP_REMOTE_FOLDER=backups
|
||
# Retention: number of snapshots to keep per tier
|
||
BACKUP_RETAIN_HOURLY=96 # 4 days of hourly snapshots
|
||
BACKUP_RETAIN_DAILY=21 # 3 weeks of daily snapshots
|
||
BACKUP_RETAIN_WEEKLY=13 # ~3 months of weekly snapshots
|
||
|
||
# **Full-Text Search (Meilisearch)**
|
||
# URL for the Meilisearch instance.
|
||
# Default is "http://meilisearch:7700" — the Docker Compose / K8s service name —
|
||
# so container-to-container networking works without extra configuration.
|
||
# Override to "http://localhost:7700" only when running the API process outside Docker.
|
||
MEILISEARCH_URL=http://meilisearch:7700
|
||
# Optional master/API key for secured Meilisearch instances
|
||
# MEILISEARCH_API_KEY=your_master_key_here
|
||
MEILISEARCH_INDEX_NAME=documents
|
||
ENABLE_SEARCH=True
|
||
|
||
# **Duplicate Detection**
|
||
# Exact duplicate detection (SHA-256) is always on during document processing.
|
||
# The settings below control near-duplicate detection (same scanned content,
|
||
# different hash) and the visibility of deduplication steps.
|
||
ENABLE_DEDUPLICATION=True
|
||
SHOW_DEDUPLICATION_STEP=True
|
||
# Minimum cosine similarity score (0–1) for two documents to be flagged as
|
||
# near-duplicates. 0.85 means 85 % semantic overlap. Lower = more matches.
|
||
NEAR_DUPLICATE_THRESHOLD=0.85
|
||
|
||
# **PDF/A Archival Conversion**
|
||
# When enabled, PDF/A copies of both the original ingested file and the processed
|
||
# file are created and saved alongside the standard copies. This may double or
|
||
# triple storage but provides better legal coverage with time-stamped archival copies.
|
||
# Uses ocrmypdf with Ghostscript for the conversion.
|
||
ENABLE_PDFA_CONVERSION=false
|
||
# PDF/A format variant: 1 = PDF/A-1b, 2 = PDF/A-2b (default), 3 = PDF/A-3b
|
||
PDFA_FORMAT=2
|
||
# Upload original-file PDF/A variant to all configured storage providers
|
||
PDFA_UPLOAD_ORIGINAL=false
|
||
# Upload processed-file PDF/A variant to all configured storage providers
|
||
PDFA_UPLOAD_PROCESSED=false
|
||
# Subfolder name appended to each provider's folder for PDF/A uploads
|
||
# e.g. if Dropbox folder is '/Documents' this puts PDF/A files into '/Documents/pdfa'
|
||
PDFA_UPLOAD_FOLDER=pdfa
|
||
# Google Drive folder ID for PDF/A uploads (uses folder IDs, not paths)
|
||
# Leave empty to use the same folder as regular uploads
|
||
GOOGLE_DRIVE_PDFA_FOLDER_ID=
|
||
# RFC 3161 timestamping of PDF/A files (creates .tsr proof-of-existence files)
|
||
PDFA_TIMESTAMP_ENABLED=false
|
||
# Timestamp Authority URL (default: FreeTSA, a free RFC 3161 TSA)
|
||
PDFA_TIMESTAMP_URL=https://freetsa.org/tsr
|
||
# Model used to generate text embeddings for document similarity.
|
||
# Must be supported by your OpenAI-compatible API endpoint.
|
||
EMBEDDING_MODEL=text-embedding-3-small
|
||
# Maximum tokens to send to the embedding model. Set below the model's
|
||
# context window (e.g. 8000 for an 8192-token model).
|
||
EMBEDDING_MAX_TOKENS=8000
|
||
|
||
# **Support / Help Center – Zammad Integration**
|
||
# Base URL of your Zammad instance (required for chat and ticket form).
|
||
# ZAMMAD_URL=https://zammad.example.com
|
||
# Show a live-chat widget on the Help Center page (requires an online Zammad agent).
|
||
# ZAMMAD_CHAT_ENABLED=false
|
||
# Zammad chat topic ID (see Zammad → Channels → Chat → Topics).
|
||
# ZAMMAD_CHAT_ID=1
|
||
# Show a "Submit a Ticket" feedback form on the Help Center page.
|
||
# ZAMMAD_FORM_ENABLED=false
|
||
# Support e-mail address displayed on the Help Center page.
|
||
# SUPPORT_EMAIL=support@example.com
|
||
|
||
# **Observability – Sentry Error & Performance Monitoring**
|
||
# Sentry DSN – obtain from https://sentry.io (Project → Settings → Client Keys).
|
||
# Leave commented out (or set to empty) to disable Sentry entirely.
|
||
# SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project>
|
||
#
|
||
# Environment label shown in the Sentry dashboard (e.g. development / staging / production).
|
||
# SENTRY_ENVIRONMENT=production
|
||
#
|
||
# Fraction of requests to capture for performance tracing (0.0–1.0).
|
||
# 0.0 disables tracing; 1.0 captures every request. Default: 0.1 (10 %).
|
||
# SENTRY_TRACES_SAMPLE_RATE=0.1
|
||
#
|
||
# Fraction of profiled transactions to send to Sentry (0.0–1.0).
|
||
# Profiling is only active when SENTRY_TRACES_SAMPLE_RATE > 0. Default: 0.0 (disabled).
|
||
# SENTRY_PROFILES_SAMPLE_RATE=0.0
|
||
#
|
||
# Attach PII (IP addresses, user agents) to Sentry events.
|
||
# Disable (default) to stay GDPR/CCPA compliant.
|
||
# SENTRY_SEND_DEFAULT_PII=false
|
||
|
||
# **Mobile App – Push Notifications**
|
||
# Push notifications are delivered via Expo's push notification service
|
||
# (https://expo.dev/notifications) which routes to APNs (iOS) and FCM (Android).
|
||
# No additional credentials are required on the server side.
|
||
# The mobile app registers its Expo push token via POST /api/mobile/register-device.
|
||
#
|
||
# To use native FCM/APNs directly (without Expo relay), replace the
|
||
# send_expo_push_notification function in app/utils/push_notification.py.
|