---
name: borgwarehouse
description: "Fast, modern web UI for managing a central BorgBackup repository server. AGPL-3.0. Ravinou. Docker Compose. Single container with optional Apprise sidecar. SSH + web management of Borg repos, quotas, alerts, REST API."
---

# BorgWarehouse

**A fast and modern web UI for a BorgBackup central repository server.** Manage BorgBackup repositories, SSH keys, quotas, and backup monitoring from a browser — no more command-line-only administration. Supports REST API for CRUD operations, email/Apprise alerting for missed backups, and per-repository quota management. AGPL-3.0.

Built + maintained by **Ravinou**.

- Upstream repo: <https://github.com/Ravinou/borgwarehouse>
- Docs: <https://borgwarehouse.com/docs/prologue/introduction/>
- Docker Hub: <https://hub.docker.com/r/borgwarehouse/borgwarehouse>
- Latest release: v3.1.3

## Architecture in one minute

- Single Next.js + React container exposing port **3000** (web UI)
- SSH server exposed on a configurable port (default **2222**) — Borg clients connect here to push backups
- Persistent volumes: `config/` (repo metadata), `ssh/` (authorised keys), `ssh_host/` (SSH host keys), `repos/` (actual Borg backup data)
- Optional sidecar: **Apprise** container for webhook/push notifications
- Resource: low — runs comfortably on a Raspberry Pi or small VPS

## Compatible install methods

| Infra        | Runtime                             | Notes                                             |
| ------------ | ----------------------------------- | ------------------------------------------------- |
| **Docker**   | `borgwarehouse/borgwarehouse`        | **Primary** — one-liner install script            |
| **Docker Compose** | `docker compose up -d`         | Manual setup path                                 |

## Inputs to collect

| Input                    | Example                    | Phase    | Notes                                                                 |
| ------------------------ | -------------------------- | -------- | --------------------------------------------------------------------- |
| `WEB_SERVER_PORT`        | `3000`                     | Network  | Host port mapped to the web UI                                        |
| `SSH_SERVER_PORT`        | `2222`                     | Network  | Host port exposed for Borg client SSH connections                     |
| `FQDN`                   | `borgwarehouse.example.com` | Auth/TLS | Public hostname (used for SSH connection strings shown in the UI)    |
| `NEXTAUTH_URL`           | `https://borgwarehouse.example.com` | Auth | Full URL including protocol                                 |
| `NEXTAUTH_SECRET`        | `<random 32+ chars>`       | Auth     | Auto-generated by install script via `openssl rand -base64 32`        |
| `CRONJOB_KEY`            | `<random 32+ chars>`       | Auth     | Used to authenticate the scheduled alert cron endpoint                |
| `PUID` / `PGID`          | `1000` / `1000`            | Storage  | Must match the owner of volume directories on the host; cannot be 0  |
| Data directory           | `/opt/borgwarehouse`       | Storage  | Parent of `config/`, `ssh/`, `ssh_host/`, `repos/` bind-mount dirs   |

## Install via upstream script (recommended)

The official one-liner sets up directories, generates secrets, and writes a ready-to-run `docker-compose.yml` + `.env`:

```bash
curl -fsSL https://raw.githubusercontent.com/Ravinou/borgwarehouse/main/docker/install.sh | bash
```

The script prompts for install directory, FQDN, ports, and the user that will own the data. It auto-generates `NEXTAUTH_SECRET` and `CRONJOB_KEY` via `openssl`.

Once complete:

```bash
cd <install-dir>
docker compose up -d
```

Visit `http://localhost:<WEB_SERVER_PORT>` (or your domain with a reverse proxy).

## Install via Docker Compose (manual)

```yaml
# docker-compose.yml — based on upstream v3.1.3
services:
  borgwarehouse:
    image: borgwarehouse/borgwarehouse
    container_name: borgwarehouse
    restart: unless-stopped
    ports:
      - "${WEB_SERVER_PORT}:3000"
      - "${SSH_SERVER_PORT}:22"
    env_file:
      - .env
    volumes:
      - ./config:/home/borgwarehouse/app/config
      - ./ssh:/home/borgwarehouse/.ssh
      - ./ssh_host:/etc/ssh
      - ./repos:/home/borgwarehouse/repos

  # Optional — Apprise for webhook/push notifications
  apprise:
    image: caronc/apprise
    container_name: apprise
    restart: unless-stopped
    user: "www-data:www-data"
    # Referenced as http://apprise:8000 in BorgWarehouse Settings -> Notifications
```

Minimal `.env`:

```env
# Ports
WEB_SERVER_PORT=3000
SSH_SERVER_PORT=2222

# Hostname and URL
FQDN=borgwarehouse.example.com
NEXTAUTH_URL=https://borgwarehouse.example.com

# Secrets — generate with: openssl rand -base64 32
NEXTAUTH_SECRET=<generated>
CRONJOB_KEY=<generated>

# UID/GID — must match the owner of the volume directories on the host
PUID=1000
PGID=1000

# Volume paths (relative to docker-compose.yml location)
CONFIG_PATH=./config
SSH_PATH=./ssh
SSH_HOST=./ssh_host
BORG_REPOSITORY_PATH=./repos
```

Create directories before first run:

```bash
mkdir -p config ssh ssh_host repos
chown -R ${PUID}:${PGID} config ssh ssh_host repos
```

## First boot

1. Visit `http://<host>:<WEB_SERVER_PORT>` — BorgWarehouse shows the initial setup wizard.
2. Create the first admin account.
3. Add a new repository; the UI generates the correct Borg init + backup command for each client.
4. On each Borg client: paste the client's public SSH key into the BorgWarehouse UI, then run the generated `borg init` command.
5. Configure alert thresholds (hours since last backup) per repository.
6. Optionally connect Apprise: set URL to `http://apprise:8000` in Settings → Notifications.

## Data & config layout

```
<install-dir>/
├── config/       # BorgWarehouse repo metadata (JSON files)
├── ssh/          # Authorised client SSH public keys
├── ssh_host/     # SSH host key files (persist across container recreates)
└── repos/        # Actual BorgBackup repository data (grows with backups)
```

## Upgrade

```bash
cd <install-dir>
docker compose pull
docker compose up -d
```

Check the [releases page](https://github.com/Ravinou/borgwarehouse/releases) before upgrading across major versions.

## Gotchas

- **PUID/PGID cannot be 0 (root).** BorgWarehouse explicitly rejects running as root.
- **SSH host keys must persist.** Mount `./ssh_host` as a volume; if the host key regenerates, clients will see a host-key-changed warning and refuse to connect until `known_hosts` is updated.
- **`NEXTAUTH_SECRET` must not change after first run.** Changing it invalidates all existing sessions.
- **Firewall: open `SSH_SERVER_PORT` to Borg clients.** The web UI port only needs to be reachable by admins.
- **Apprise `http://apprise:8000` is internal.** Resolves only inside the Compose network — configure it in BorgWarehouse Settings, don't open it to the internet.
- **`repos/` can grow very large.** Set per-repository quotas in the UI and mount `repos/` on a volume with sufficient capacity.
