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.
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
/localmount for single directory - Use
/local/subdirpattern for multiple directories - Use
:ro(read-only) when you only need to backup, not restore - Mount backup destinations as
:rwif 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
Nginx example:
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;
}
}
Traefik example:
services:
borg-ui:
image: ainullcode/borg-ui:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.borg-ui.rule=Host(`backups.example.com`)"
- "traefik.http.routers.borg-ui.entrypoints=websecure"
- "traefik.http.routers.borg-ui.tls.certresolver=letsencrypt"
- "traefik.http.services.borg-ui.loadbalancer.server.port=8081"
Custom Network
networks:
borg-network:
driver: bridge
services:
borg-ui:
networks:
- borg-network
Performance Tuning
For Large Repositories
Increase Borg cache size by mounting to fast storage:
volumes:
- /path/to/ssd/borg-cache:/home/borg/.cache/borg
For Raspberry Pi / Low Memory
environment:
- WORKERS=1 # Reduce concurrent workers
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
- Notifications Setup - Configure alerts
- SSH Keys Guide - Set up remote backups
- Usage Guide - Create your first backup