Configuration Guide

Customize Borg Web UI for your environment.


Auto-Configured Settings

These are automatically set up on first run - no configuration needed:

Setting Auto-Configuration
SECRET_KEY Randomly generated (32 bytes), persisted to /data/.secret_key
DATABASE_URL SQLite at /data/borg.db (includes encrypted SSH keys)
JOB_LOGS Stored in /data/logs/ (backup_job_.log, check_job_.log, compact_job_*.log)
SSH_KEYS_DIR /data/ssh_keys (used for temporary files during SSH operations)

Note: Application logs (FastAPI, uvicorn) are sent to Docker logs (stdout/stderr). View with docker logs borg-web-ui.


Environment Variables

Port Configuration

environment:
  - PORT=8082  # Default: 8081

Access at http://localhost:8082

User/Group IDs

Match your host user for proper permissions:

environment:
  - PUID=1000  # Your user ID
  - PGID=1000  # Your group ID

Find your IDs:

id -u  # User ID
id -g  # Group ID

Common IDs:

  • Linux/Raspberry Pi: 1000:1000
  • Unraid: 99:100
  • macOS: 501:20

Note: When PUID=0 (running as root), SSH keys are symlinked from /root/.ssh to /home/borg/.ssh automatically.

Logging

environment:
  - LOG_LEVEL=DEBUG  # Default: INFO
  # Options: DEBUG, INFO, WARNING, ERROR

Initial Admin Password

Set a custom admin password on first run:

environment:
  - INITIAL_ADMIN_PASSWORD=your-secure-password

Note: If not set, defaults to admin123. You’ll be prompted to change it on first login.

Reverse Proxy / BASE_PATH

New in vX.Y.Z: BASE_PATH support for subfolder deployments

Run Borg Web UI in a subfolder behind a reverse proxy:

environment:
  - BASE_PATH=/borg  # Access at example.com/borg/

Important Notes:

  • Requires container rebuild: docker-compose up -d --build
  • Must start with / and have no trailing slash
  • Defaults to / (root path) if not set

Examples:

  • /borg → Access at example.com/borg/
  • /backup-ui → Access at example.com/backup-ui/
  • / → Access at example.com/ (default)

See Reverse Proxy Setup for complete configuration examples with Nginx, Traefik, Caddy, and Apache.

File Browser Mount Points

New in vX.Y.Z: LOCAL_MOUNT_POINTS for improved file browser navigation

Specify which container paths are host filesystem mounts to highlight them in the file browser:

environment:
  - LOCAL_MOUNT_POINTS=/local  # Default

What it does:

  • Highlights host filesystem mounts with a 💾 HardDrive icon and “Host” badge
  • Makes it easy to identify where your actual data lives
  • Similar to how SSH mount points are displayed with “Remote” badge

Custom configurations:

# Single mount (default)
volumes:
  - /:/local:rw
environment:
  - LOCAL_MOUNT_POINTS=/local

# Multiple mounts (comma-separated)
volumes:
  - /home/john:/mylocalserver:rw
  - /mnt/nas:/nas:rw
environment:
  - LOCAL_MOUNT_POINTS=/mylocalserver,/nas

# No highlighting (empty string)
environment:
  - LOCAL_MOUNT_POINTS=

In the file browser:

  • 💾 /local [Host] - Highlighted as host mount
  • 🌐 /mnt/ssh-connection [Remote] - SSH mount point
  • 📦 /backups/repo1 [Borg] - Borg repository
  • 📁 /data - Regular directory

Volume Mounts

Application Data

Required volumes:

volumes:
  - borg_data:/data                       # Application data
  - borg_cache:/home/borg/.cache/borg    # Borg cache

What’s stored in /data:

  • SQLite database (includes encrypted SSH keys)
  • Job logs (backup, check, compact operations) in /data/logs/
  • Auto-generated SECRET_KEY
  • Temporary SSH key files during deployment/testing in /data/ssh_keys/

Filesystem Access

⚠️ Important Security Note

The container needs access to directories you want to backup. For production, mount only specific directories you need:

volumes:
  # ✅ Recommended: Mount specific directories
  - /home/yourusername:/local:rw      # Replace with your path
  - /mnt/data:/local/data:rw          # Additional directories

  # ❌ NOT Recommended: Full filesystem access
  # - /:/local:rw  # Development/testing only - avoid in production

Why limit filesystem access?

  • Reduces security risk (principle of least privilege)
  • Prevents accidental access to sensitive system files
  • Makes it clear which directories are being backed up
  • Easier to troubleshoot permission issues

Mount Pattern Examples

Personal Computer:

volumes:
  - borg_data:/data
  - borg_cache:/home/borg/.cache/borg
  - /home/john:/local:rw              # Mount home directory

Server with Multiple Directories:

volumes:
  - borg_data:/data
  - borg_cache:/home/borg/.cache/borg
  - /var/www:/local/www:ro            # Website files (read-only)
  - /home/appuser:/local/app:rw       # Application data
  - /var/lib/postgresql:/local/db:rw  # Database directory

NAS Backup (Unraid/TrueNAS):

volumes:
  - borg_data:/data
  - borg_cache:/home/borg/.cache/borg
  - /mnt/user/Documents:/local:ro     # Documents (read-only)
  - /mnt/user/Media:/local/media:ro   # Media files
  - /mnt/backup:/local/backup:rw      # Backup destination

Best Practices:

  • Use simple /local mount for single directory
  • Use /local/subdir pattern for multiple directories
  • Use :ro (read-only) when you only need to backup, not restore
  • Mount backup destinations as :rw if storing repositories locally

Custom Volume Locations

Store application data in a specific location:

volumes:
  borg_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/storage/borg-data

  borg_cache:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/storage/borg-cache

Repository Configuration

Important: Repositories are configured through the web UI, not Docker volumes.

Supported repository types:

  • Local paths: /local/backups/my-repo, /backups/my-repo
  • SSH/SFTP: user@host:/path/to/repo
  • Cloud storage: Via rclone (S3, Azure, Google Cloud)

No need for a separate borg_backups volume!


Network Configuration

Using a Reverse Proxy

Borg Web UI supports both root domain and subfolder deployments behind reverse proxies.

Quick Example (Nginx root domain):

server {
    listen 80;
    server_name backups.example.com;

    location / {
        proxy_pass http://localhost:8081;
        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/SSE support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

For complete reverse proxy setup including:

  • Subfolder deployments (e.g., example.com/borg/)
  • Nginx, Traefik, Caddy, Apache configurations
  • SSL/HTTPS setup
  • Docker network integration
  • Troubleshooting

See the Reverse Proxy Setup Guide

Custom Network

networks:
  borg-network:
    driver: bridge

services:
  borg-ui:
    networks:
      - borg-network

Performance Tuning

For Large Repositories

New in vX.Y.Z: Configurable operation timeouts for very large repositories

Increase Borg cache size by mounting to fast storage:

volumes:
  - /path/to/ssd/borg-cache:/home/borg/.cache/borg

Operation Timeouts for Very Large Repositories

For repositories with:

  • Multi-terabyte deduplicated size
  • Hundreds of archives
  • Long cache build times on first access

You can increase operation timeouts via environment variables:

environment:
  # Borg operation timeouts (in seconds)
  - BORG_INFO_TIMEOUT=7200      # 2 hours for borg info (default: 600 = 10 min)
  - BORG_LIST_TIMEOUT=3600      # 1 hour for borg list (default: 600 = 10 min)
  - BORG_INIT_TIMEOUT=900       # 15 min for borg init (default: 300 = 5 min)
  - BORG_EXTRACT_TIMEOUT=7200   # 2 hours for restore (default: 3600 = 1 hour)
  - SCRIPT_TIMEOUT=300          # 5 min for hooks (default: 120 = 2 min)

Timeout Usage:

Operation When Used Default Recommended for Large Repos
BORG_INFO_TIMEOUT Repository verification, stats, import 10 min 1-4 hours (based on cache build time)
BORG_LIST_TIMEOUT Listing archives/files, restore browser 10 min 30-60 min
BORG_INIT_TIMEOUT Creating new repositories 5 min 10-15 min
BORG_EXTRACT_TIMEOUT Restore operations 1 hour 2-4 hours
SCRIPT_TIMEOUT Pre/post backup scripts 2 min 5-10 min

Example for very large repository:

environment:
  - BORG_INFO_TIMEOUT=7200    # 2 hours for initial cache build
  - BORG_LIST_TIMEOUT=3600    # 1 hour for listing operations

Symptoms you need higher timeouts:

  • “Repository verification timed out” during import
  • Operations fail with timeout errors in logs
  • Large operations (info/list) succeed when run manually but fail in UI

For Raspberry Pi / Low Memory

environment:
  - WORKERS=1  # Reduce concurrent workers

Redis Cache Configuration

New in vX.Y.Z: Redis-based archive caching for 600x faster browsing

Borg Web UI includes Redis caching for dramatically faster archive browsing. Without cache, navigating folders in large archives (1M+ files) takes 60-90 seconds. With cache, it takes less than 100ms.

Default Setup (Local Redis)

Redis is included in docker-compose.yml - no configuration needed.

# Already configured in docker-compose.yml
redis:
  image: redis:7-alpine
  command: redis-server --maxmemory 2gb --maxmemory-policy allkeys-lru

Manage via UI:

  • Go to Settings → Cache tab
  • View statistics, configure TTL/size, clear cache
  • Default: 2-hour TTL, 2GB size limit

External Redis (For Large Repositories)

Connect to Redis on a separate machine with more RAM:

# docker-compose.yml
services:
  app:
    environment:
      # External Redis URL (can also configure via Settings → Cache in UI)
      - REDIS_URL=redis://192.168.1.100:6379/0

      # Or with password
      # - REDIS_URL=redis://:password@192.168.1.100:6379/0

      # Cache settings
      - CACHE_TTL_SECONDS=7200    # 2 hours
      - CACHE_MAX_SIZE_MB=2048    # 2GB

When to use external Redis:

  • Repositories with 5M+ files
  • Multiple large archives
  • Limited RAM on Borg Web UI host
  • NAS/workstation with spare RAM available

Full setup guide with examples: Cache Configuration


Security Configuration

Change SECRET_KEY

The SECRET_KEY is auto-generated on first run. To rotate it:

docker exec borg-web-ui rm /data/.secret_key
docker restart borg-web-ui

Note: This invalidates all user sessions.

Enable HTTPS

Use a reverse proxy (Nginx, Traefik, Caddy) with Let’s Encrypt certificates.

Never expose the application directly to the internet without HTTPS.

Restrict Access

Using firewall:

# Allow only from local network
sudo ufw allow from 192.168.1.0/24 to any port 8081

Using Docker:

ports:
  - "127.0.0.1:8081:8081"  # Only accessible from localhost

Then access via reverse proxy or SSH tunnel.


Backup Configuration Data

Backup Application Data

# Backup borg_data volume
docker run --rm \
  -v borg_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/borg-data-backup.tar.gz -C /data .

Restore Application Data

# Restore borg_data volume
docker run --rm \
  -v borg_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/borg-data-backup.tar.gz -C /data

Example Configurations

Basic Home Setup

version: '3.8'

services:
  borg-ui:
    image: ainullcode/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    ports:
      - "8081:8081"
    volumes:
      - borg_data:/data
      - borg_cache:/home/borg/.cache/borg
      - /home/yourusername:/local:rw  # Replace with your home directory
    environment:
      - PUID=1000
      - PGID=1000

volumes:
  borg_data:
  borg_cache:

Production Setup with Restricted Access

version: '3.8'

services:
  borg-ui:
    image: ainullcode/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:8081"  # Only localhost
    volumes:
      # Application data
      - borg_data:/data
      - borg_cache:/home/borg/.cache/borg

      # Backup sources (read-only)
      - /var/www:/local/www:ro
      - /home/appuser:/local/app:ro

      # Backup destination
      - /mnt/backups:/local/backup:rw
    environment:
      - PUID=1000
      - PGID=1000
      - LOG_LEVEL=INFO
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.borg-ui.rule=Host(`backups.example.com`)"
      - "traefik.http.routers.borg-ui.tls=true"

volumes:
  borg_data:
  borg_cache:

NAS Setup (Unraid/TrueNAS)

services:
  borg-ui:
    image: ainullcode/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    ports:
      - "8081:8081"
    volumes:
      - /mnt/user/appdata/borg-ui:/data
      - /mnt/user/appdata/borg-ui/cache:/home/borg/.cache/borg
      - /mnt/user/Documents:/local:ro         # Documents share
      - /mnt/user/Media:/local/media:ro       # Media share
      - /mnt/user/Backups:/local/backup:rw    # Backup destination
    environment:
      - PUID=99
      - PGID=100

Troubleshooting

Database Locked Error

If multiple containers are using the same database:

# Stop all containers
docker stop borg-web-ui

# Check for locks
docker exec borg-web-ui ls -la /data/

# Restart
docker start borg-web-ui

Permission Issues

Verify PUID/PGID match your host user:

# Check file ownership
docker exec borg-web-ui ls -la /data/

# Check container user
docker exec borg-web-ui id

# Fix ownership if needed
docker exec borg-web-ui chown -R borg:borg /data

High Memory Usage

Reduce Borg cache or move to disk-based cache:

volumes:
  - /path/to/slower/storage:/home/borg/.cache/borg

Next Steps


Back to top

Copyright © 2024 Karan Hudia. Distributed under the GPL-3.0 License.

This site uses Just the Docs, a documentation theme for Jekyll.