# ============================================================================== # Telegram Archive — Environment Variables # ============================================================================== # Copy this file to .env and fill in your values: # cp .env.example .env # # For the full reference table, see the README: # https://github.com/GeiserX/Telegram-Archive#environment-variables # ============================================================================== # ============================================================================== # TELEGRAM CREDENTIALS (required for backup) # ============================================================================== # Get these from https://my.telegram.org/apps TELEGRAM_API_ID=your_api_id_here TELEGRAM_API_HASH=your_api_hash_here TELEGRAM_PHONE=+1234567890 # Optional SOCKS5 proxy for all TelegramClient connections # Requires python-socks[asyncio] in the runtime image/environment # TELEGRAM_PROXY_TYPE=socks5 # TELEGRAM_PROXY_ADDR=127.0.0.1 # TELEGRAM_PROXY_PORT=1080 # TELEGRAM_PROXY_USERNAME= # TELEGRAM_PROXY_PASSWORD= # TELEGRAM_PROXY_RDNS=false # ============================================================================== # BACKUP SCHEDULE & STORAGE # ============================================================================== # Cron schedule (minute hour day month weekday) # Examples: 0 */6 * * * (every 6h), 0 0 * * * (daily), 0 */1 * * * (hourly) SCHEDULE=0 */6 * * * # Backup destination path (inside container) BACKUP_PATH=/data/backups # Download media files (photos, videos, documents) # Set to false to save space and only backup text messages DOWNLOAD_MEDIA=true # Maximum media file size to download (in MB) # Files larger than this will be skipped MAX_MEDIA_SIZE_MB=100 # Maximum usable filename byte budget for downloaded media (the file_id prefix # and extension are always preserved; only the decorative part is shortened). # Default 143 keeps names writable on Synology/eCryptfs encrypted shares, whose # filename encryption overhead caps components below the usual 255 bytes. # Raise to 255 on plain ext4/xfs/btrfs if you prefer longer decorative names. # MEDIA_MAX_FILENAME_BYTES=143 # Stop retrying a media file's download after this many failed attempts, so a # permanently-unwritable file can't tax every backup run forever. Re-requesting # the download (e.g. via VERIFY_MEDIA or the admin panel) resets the counter. # MEDIA_MAX_DOWNLOAD_ATTEMPTS=5 # Timeout for media downloads (in seconds). 0 disables the timeout. # Default is 3600 (60 minutes). # DOWNLOAD_TIMEOUT_SECONDS=3600 # --- Parallel chunked downloads (advanced, default OFF) --- # Splits one large file into chunks fetched concurrently over several MTProto # connections to a single datacenter, lifting the ~10 MB/s single-stream cap. # Small files and photos always use a single stream regardless of this setting. # Disabled by default; enable only if your download throughput is the bottleneck. # PARALLEL_DOWNLOAD_ENABLED=false # # Only files at least this large (in MB) use the parallel path. Smaller files # stay single-stream (chunking overhead isn't worth it). Minimum 1. # PARALLEL_DOWNLOAD_MIN_SIZE_MB=20 # # Number of concurrent connections per file. Clamped to 2..8. Telegram throttles # hard past ~20 total connections, so this stays conservative. Default 4. # PARALLEL_DOWNLOAD_CONNECTIONS=4 # # Chunk size per request in KB. Must be one of: 4, 8, 16, 32, 64, 128, 256, 512 # (a 4 KiB multiple that divides 1 MiB, per Telegram's getFile constraints). # Invalid values snap down to the nearest valid size. Default 512. # Peak extra memory while downloading is roughly CONNECTIONS x PART_SIZE_KB # (e.g. 4 x 512 KB = 2 MB), since each connection buffers one chunk in flight. # PARALLEL_DOWNLOAD_PART_SIZE_KB=512 # Messages processed per database batch # Higher values = faster but more memory usage BATCH_SIZE=100 # Detect and fetch missing messages in sequence gaps # FILL_GAPS=false # Number of messages missing in a sequence to consider it a gap # GAP_THRESHOLD=50 # How often to save backup progress (every N batch inserts) # 1 = checkpoint every batch (safest, best crash recovery) # Higher = fewer DB writes but more re-work on crash/restart CHECKPOINT_INTERVAL=1 # Use symlinks to deduplicate identical media files across chats # DEDUPLICATE_MEDIA=true # Comma-separated chat IDs to process FIRST in all operations # PRIORITY_CHAT_IDS= # Skip media downloads for specific chats (comma-separated IDs) # Messages are still backed up with text, but media files are not downloaded # Useful for high-volume media chats where you only need text content # Example: SKIP_MEDIA_CHAT_IDS=-1001234567890,-1009876543210 # SKIP_MEDIA_CHAT_IDS= # Delete existing media files and DB records for chats in SKIP_MEDIA_CHAT_IDS # When enabled (default), reclaims storage by removing already-downloaded media # Set to false to keep existing media but skip future downloads SKIP_MEDIA_DELETE_EXISTING=true # Skip specific topics in forum supergroups (format: chat_id:topic_id,...) # Messages in matching topics are completely excluded from backup # Example: SKIP_TOPIC_IDS=-1001234567890:42,-1001234567890:1337 # SKIP_TOPIC_IDS= # Hour (0-23) to recalculate backup statistics daily # STATS_CALCULATION_HOUR=3 # Logging level: DEBUG, INFO, WARNING, ERROR LOG_LEVEL=INFO # Suppress FloodWait log messages below this threshold (seconds) # Waits shorter than this are routine and logged at DEBUG instead of WARNING # Set to 0 to log every flood-wait # FLOOD_WAIT_LOG_THRESHOLD=10 # Maximum retries for FloodWait limits # MAX_FLOOD_RETRIES=5 # Maximum seconds to wait during a FloodWait before aborting # MAX_FLOOD_WAIT_SECONDS=3600 # Exponential backoff for transient connection errors # BACKOFF_MIN_SECONDS=2.0 # BACKOFF_MAX_SECONDS=300.0 # Session name (use different names for multiple accounts) SESSION_NAME=telegram_backup # Session directory (defaults to /data/session) # SESSION_DIR=/data/session # ============================================================================== # CHAT FILTERING — Choose ONE mode # ============================================================================== # MODE 1: WHITELIST (Simple) — Set CHAT_IDS to backup ONLY specific chats # When set, ONLY these chats are backed up. All other filtering is ignored. # Example: CHAT_IDS=-1001234567890,-1009876543210 CHAT_IDS= # MODE 2: TYPE-BASED (Default) — Use CHAT_TYPES to backup by type # Options: private, groups, channels, bots (comma-separated) CHAT_TYPES=private,groups,channels # EXCLUDE specific chats (blacklist — takes priority) GLOBAL_EXCLUDE_CHAT_IDS= PRIVATE_EXCLUDE_CHAT_IDS= GROUPS_EXCLUDE_CHAT_IDS= CHANNELS_EXCLUDE_CHAT_IDS= # INCLUDE specific chats in type-based mode. # GLOBAL_INCLUDE_CHAT_IDS acts as an allow-list across all selected types. # Type-specific include lists limit that chat type. For simplest exclusive # selection, use CHAT_IDS mode instead. GLOBAL_INCLUDE_CHAT_IDS= PRIVATE_INCLUDE_CHAT_IDS= GROUPS_INCLUDE_CHAT_IDS= CHANNELS_INCLUDE_CHAT_IDS= # ============================================================================== # REAL-TIME LISTENER # ============================================================================== # ENABLE_LISTENER is the master switch. When false (default), all LISTEN_* # and MASS_OPERATION_* variables below have no effect. ENABLE_LISTENER=false # Granular listener controls (only apply when ENABLE_LISTENER=true): # LISTEN_EDITS=true # LISTEN_DELETIONS=false # DELETION_MODE=hard # hard=legacy delete from archive, soft=mark deleted and keep message # LISTEN_NEW_MESSAGES=true # LISTEN_NEW_MESSAGES_MEDIA=false # LISTEN_CHAT_ACTIONS=true # Mass operation protection (only applies when ENABLE_LISTENER=true) # MASS_OPERATION_THRESHOLD=10 # MASS_OPERATION_WINDOW_SECONDS=30 # MASS_OPERATION_BUFFER_DELAY=2.0 # Batch sync alternative (expensive — prefer ENABLE_LISTENER instead) SYNC_DELETIONS_EDITS=false # Re-download missing or corrupted media files VERIFY_MEDIA=false # ============================================================================== # DATABASE CONFIGURATION (v3.0+) # ============================================================================== # Supports SQLite (default) and PostgreSQL. # Both backup and viewer containers MUST use the same database settings. # Option 1: Full DATABASE_URL (takes priority over all below) # SQLite: DATABASE_URL=sqlite:///data/telegram_backup.db # PostgreSQL: DATABASE_URL=postgresql://user:password@localhost:5432/telegram_backup # Option 2: Individual settings DB_TYPE=sqlite DB_PATH=/data/backups/telegram_backup.db # Timeout for SQLite operations (seconds) # Increase if you see "database is locked" errors on slow disks # DATABASE_TIMEOUT=60.0 # Print all SQL queries to console (for debugging) # DB_ECHO=false # PostgreSQL settings (when DB_TYPE=postgresql) # POSTGRES_HOST=localhost # POSTGRES_PORT=5432 # POSTGRES_USER=telegram # POSTGRES_PASSWORD=your_secure_password # POSTGRES_DB=telegram_backup # ============================================================================== # VIEWER & AUTHENTICATION # ============================================================================== # These apply to the telegram-archive-viewer container. # Basic auth — set BOTH to enable the master account. The viewer fails closed # unless credentials are configured or ALLOW_ANONYMOUS_VIEWER=true is explicit. # VIEWER_USERNAME=admin # VIEWER_PASSWORD=your_secure_password # AUTH_SESSION_DAYS=30 # # ALLOW_ANONYMOUS_VIEWER grants READ-ONLY access with no login: browsing and # search work, but nothing that writes (settings, viewer/token management, # deletions, etc.) is reachable without authenticating as the master account. # ALLOW_ANONYMOUS_VIEWER=false # --- Multi-User Access Control (v7.0.0) --- # Viewer accounts are managed via the admin panel (gear icon in sidebar). # The VIEWER_USERNAME/VIEWER_PASSWORD above becomes the "master" account. # Create additional viewer accounts with per-chat access via the admin UI. # Viewer account data is stored in the database (viewer_accounts table). # --- Trusted Proxy Authentication (v7.9.0) --- # For use behind auth proxies like Authelia, Authentik, or Keycloak. # The proxy authenticates the user and forwards their identity in a header. # Set AUTH_PROXY_HEADER to enable (e.g., "Remote-User" or "X-Forwarded-User"). # # !!! WARNING !!! # Your reverse proxy MUST strip or overwrite this header on EVERY inbound # request before it reaches this app. If a client can set the header itself # (because the proxy passes it through untouched), anyone can impersonate any # user — including an admin — with a single request header. This is a full # authentication bypass, not a hardening nicety. # AUTH_PROXY_HEADER=Remote-User # Comma-separated list of usernames that get admin (master) role. # Users not in this list are auto-created as viewers with restricted access. # AUTH_PROXY_ADMIN_USERS=admin@example.com # Default chat access for auto-created proxy users: "none" or "all". # "none" = no chats visible until admin grants access via the admin panel. # "all" = full access to all chats (suitable for single-user setups). # AUTH_PROXY_DEFAULT_ACCESS=none # Timezone for displayed timestamps (tz database name) # VIEWER_TIMEZONE=Europe/Madrid # Show backup statistics dropdown in viewer header # SHOW_STATS=true # Restrict viewer to specific chats (comma-separated IDs) # Useful for sharing public channel viewers without exposing other chats # DISPLAY_CHAT_IDS= # ============================================================================== # SECURITY # ============================================================================== # Allowed CORS origins (comma-separated) # Default: * (allow all origins, credentials auto-disabled) # Example: CORS_ORIGINS=https://my.domain.com,https://other.domain.com # CORS_ORIGINS=* # Set Secure flag on auth cookies # Default: auto-detect from request protocol (HTTPS reverse proxy or direct HTTPS = Secure) # Override: true = always Secure, false = never Secure # SECURE_COOKIES= # Only trust X-Forwarded-For / X-Real-IP when your reverse proxy overwrites # those headers. Leave false for direct/LAN deployments. # TRUST_PROXY_HEADERS=false # Shared secret for backup -> viewer realtime pushes when using SQLite split # containers. Required for non-loopback /internal/push calls. # INTERNAL_PUSH_SECRET=change_me_to_a_long_random_value # Backup container target for SQLite realtime pushes. # VIEWER_HOST=telegram-viewer # VIEWER_PORT=8000 # ============================================================================== # NOTIFICATIONS # ============================================================================== # Master switch to enable push notifications # ENABLE_NOTIFICATIONS=false # Push notification mode: off, basic (in-browser only), full (Web Push) # PUSH_NOTIFICATIONS=basic # Custom VAPID keys for Web Push (auto-generated if empty) # Generate with: npx web-push generate-vapid-keys # VAPID_PRIVATE_KEY= # VAPID_PUBLIC_KEY= # VAPID_CONTACT=mailto:admin@example.com