Skip to main content

Docker Compose Configuration

Borg UI uses Docker Compose for easy deployment with zero-configuration setup and smart defaults.

Quick Start

The default docker-compose.yml provides:
  • Auto-generated SECRET_KEY (persisted to /data/.secret_key)
  • Auto-configured SQLite database at /data/borg.db
  • Redis cache for 600x faster archive browsing
  • Smart defaults for all settings

Complete docker-compose.yml

docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
      args:
        - APP_VERSION=${APP_VERSION:-local-dev}
    container_name: borg-web-ui
    restart: unless-stopped

    # Privileged mode for remote-to-remote backups via SSHFS
    # Disable if you only use local or direct SSH backups
    privileged: true

    ports:
      - "${PORT:-8081}:${PORT:-8081}"

    volumes:
      # Application data (database, logs, SSH keys)
      - borg_data:/data

      # Borg repository cache (improves backup performance)
      - borg_cache:/home/borg/.cache/borg

      # System timezone sync
      - /etc/localtime:/etc/localtime:ro

      # Filesystem access for backups
      - ${LOCAL_STORAGE_PATH:-/}:/local:rw

      # Docker socket for container management (optional)
      - /var/run/docker.sock:/var/run/docker.sock:rw

    environment:
      - PORT=${PORT:-8081}
      - ENVIRONMENT=${ENVIRONMENT:-production}
      - PUID=${PUID:-1001}
      - PGID=${PGID:-1001}
      - TZ=${TZ:-}
      - LOCAL_MOUNT_POINTS=${LOCAL_MOUNT_POINTS:-/local}

      # Redis cache settings
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_DB=0
      - CACHE_TTL_SECONDS=7200
      - CACHE_MAX_SIZE_MB=2048

    healthcheck:
      test: ["CMD", "sh", "-c", "curl -f http://localhost:$${PORT:-8081}/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

    networks:
      - borg_network

    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    container_name: borg-redis
    restart: unless-stopped

    command: >
      redis-server
      --maxmemory 2gb
      --maxmemory-policy allkeys-lru
      --save ""
      --appendonly no

    ports:
      - "${REDIS_PORT:-6379}:6379"

    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 10s

    networks:
      - borg_network

networks:
  borg_network:
    driver: bridge

volumes:
  borg_data:
    driver: local
  borg_cache:
    driver: local

Service Configuration

App Service

Build Arguments

APP_VERSION
string
default:"local-dev"
Application version identifier. Auto-populated in CI/CD pipelines.
build:
  args:
    - APP_VERSION=${APP_VERSION:-v1.66.1}

Privileged Mode

Required ONLY for remote-to-remote backups via SSHFSThis allows mounting remote SSH locations as local filesystems. If you only use local or direct SSH backups, you can disable this:
privileged: false  # Disable if not using SSHFS

Ports

ports:
  - "${PORT:-8081}:${PORT:-8081}"
Maps the web UI port to the host. Default: 8081 Change via environment variable:
.env
PORT=8080

Volumes

# All persistent data: database, SSH keys, logs
volumes:
  - borg_data:/data
Custom mount paths: If you use paths other than /local, update LOCAL_MOUNT_POINTS to match:
volumes:
  - /mnt/disk1:/disk1:rw
  - /home/user:/home:rw
environment:
  - LOCAL_MOUNT_POINTS=/disk1,/home

Environment Variables

environment:
  - PORT=${PORT:-8081}
  - ENVIRONMENT=${ENVIRONMENT:-production}
  - PUID=${PUID:-1001}
  - PGID=${PGID:-1001}
  - TZ=${TZ:-}
See Environment Variables for complete reference.

Health Check

healthcheck:
  test: ["CMD", "sh", "-c", "curl -f http://localhost:$${PORT:-8081}/"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s
Ensures the container is healthy and accepting connections.

Redis Service

Redis provides 600x faster archive browsing through intelligent caching.

Redis Configuration

redis:
  image: redis:7-alpine
  container_name: borg-redis
  restart: unless-stopped

  command: >
    redis-server
    --maxmemory 2gb
    --maxmemory-policy allkeys-lru
    --save ""
    --appendonly no
Redis flags explained:
  • --maxmemory 2gb: Maximum memory usage (adjust as needed)
  • --maxmemory-policy allkeys-lru: Evict least recently used keys when full
  • --save "": Disable RDB persistence (cache-only, no disk writes)
  • --appendonly no: Disable AOF persistence
Redis is used purely as a cache - persistence is disabled for better performance. Data loss on restart is acceptable since the cache rebuilds automatically.

Redis Ports

ports:
  - "${REDIS_PORT:-6379}:6379"
Exposes Redis for external connections (optional). Remove this line if you only need internal access.

Redis Health Check

healthcheck:
  test: ["CMD", "redis-cli", "ping"]
  interval: 10s
  timeout: 3s
  retries: 3
  start_period: 10s

Production Examples

Minimal Setup (Local Backups Only)

docker-compose.yml
services:
  app:
    image: ghcr.io/karanhudia/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    privileged: false  # No SSHFS needed
    
    ports:
      - "8081:8081"
    
    volumes:
      - borg_data:/data
      - borg_cache:/home/borg/.cache/borg
      - /home:/local:rw  # Only mount /home
    
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru

volumes:
  borg_data:
  borg_cache:

Behind Reverse Proxy with External Redis

docker-compose.yml
services:
  app:
    image: ghcr.io/karanhudia/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    
    # No ports exposed - accessed via reverse proxy
    expose:
      - "8081"
    
    volumes:
      - borg_data:/data
      - borg_cache:/home/borg/.cache/borg
      - /mnt/storage:/local:rw
    
    environment:
      - PUID=1000
      - PGID=1000
      - BASE_PATH=/borg
      - REDIS_URL=redis://redis.internal.lan:6379/0
      - DISABLE_AUTHENTICATION=true
      - PROXY_AUTH_HEADER=X-Forwarded-User
    
    networks:
      - proxy_network
      - internal

networks:
  proxy_network:
    external: true
  internal:
    driver: bridge

volumes:
  borg_data:
  borg_cache:

High-Performance Setup (Large Repositories)

docker-compose.yml
services:
  app:
    image: ghcr.io/karanhudia/borg-ui:latest
    container_name: borg-web-ui
    restart: unless-stopped
    privileged: true
    
    ports:
      - "8081:8081"
    
    volumes:
      - borg_data:/data
      - borg_cache:/home/borg/.cache/borg
      - /mnt/storage:/local:rw
    
    environment:
      - PUID=1000
      - PGID=1000
      # Increased timeouts for large repos (e.g., 830TB)
      - BORG_INFO_TIMEOUT=7200    # 2 hours for cache build
      - BORG_LIST_TIMEOUT=1800    # 30 minutes
      - BORG_EXTRACT_TIMEOUT=7200 # 2 hours
      # Larger Redis cache
      - CACHE_TTL_SECONDS=14400   # 4 hours
      - CACHE_MAX_SIZE_MB=4096    # 4GB
    
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: >
      redis-server
      --maxmemory 4gb
      --maxmemory-policy allkeys-lru
      --save ""
      --appendonly no

volumes:
  borg_data:
  borg_cache:

Common Customizations

Change Port

ports:
  - "8080:8080"
environment:
  - PORT=8080

Multiple Host Directories

volumes:
  - /home:/home:rw
  - /var/www:/www:ro
  - /mnt/data:/data:rw
environment:
  - LOCAL_MOUNT_POINTS=/home,/www,/data

Disable Redis (In-Memory Cache Only)

services:
  app:
    # ... app config ...
    environment:
      - REDIS_HOST=disabled
    # Remove depends_on

# Remove redis service entirely

Custom Redis Memory Limit

redis:
  command: >
    redis-server
    --maxmemory 512mb
    --maxmemory-policy allkeys-lru

Management Commands

docker-compose up -d

Troubleshooting

Port Already in Use

# Change port in .env
echo "PORT=8082" >> .env
docker-compose up -d

Permission Denied

# Set PUID/PGID to match host user
id -u && id -g
echo "PUID=1000" >> .env
echo "PGID=1000" >> .env
docker-compose down && docker-compose up -d

Redis Connection Failed

# Check Redis is running
docker-compose ps redis

# Check Redis logs
docker-compose logs redis

# Restart Redis
docker-compose restart redis

Reset Everything

This deletes all data including repositories, SSH keys, and settings.
docker-compose down -v
docker-compose up -d

Next Steps

Environment Variables

Complete reference for all configuration options

Cache Configuration

Set up Redis for 600x faster archive browsing

SSH Keys

Configure SSH keys for remote repositories

Deployment

Deploy to production environments

Build docs developers (and LLMs) love