Skip to content

Docker Installation

Marc Pope edited this page Feb 21, 2026 · 6 revisions

Docker Installation

Run BBS in a Docker container — no OS dependencies to install. This is the fastest way to get BBS running and is ideal for testing, home labs, and production environments where you prefer containerized deployments.

Prerequisites

  • Docker Engine 20.10+ and Docker Compose v2
  • 2 GB RAM minimum (4 GB+ recommended)
  • Two available ports: one for the web UI (default 8080) and one for SSH/borg connections (default 2222)

Quick Start

Download the compose file and start the container:

curl -sO https://raw.githubusercontent.com/marcpope/borgbackupserver/main/docker-compose.yml
docker compose up -d

The pre-built image (marcpope/borgbackupserver) is pulled automatically from Docker Hub.

Get admin credentials from the container logs:

docker compose logs bbs

Look for the credentials block:

========================================
  ADMIN CREDENTIALS (SAVE THESE!)
========================================
  URL:      http://localhost:8080
  Username: admin
  Password: <random password>
========================================

Open http://localhost:8080 and log in.

Configuration

All configuration is done through environment variables in docker-compose.yml:

Variable Default Description
APP_URL http://localhost:8080 Public URL used by browsers and agents to reach BBS
SSH_PORT 2222 SSH port for borg connections — must match the host-side port mapping
ADMIN_PASS (auto-generated) Admin password — only used on first run. Omit to auto-generate (shown in logs)

Setting a Custom Admin Password

To set a specific admin password instead of an auto-generated one, uncomment the ADMIN_PASS line in docker-compose.yml:

environment:
  - APP_URL=http://localhost:8080
  - SSH_PORT=2222
  - ADMIN_PASS=your-strong-password-here

This is only applied on first run when the database is initialized. Changing it later has no effect — use the web UI to change passwords after initial setup.

Production Configuration

For a production server with a real hostname and HTTPS (via a reverse proxy):

environment:
  - APP_URL=https://backups.example.com
  - SSH_PORT=2222

You would place an HTTPS reverse proxy (nginx, Caddy, Traefik) in front of the container to handle SSL termination. The container itself serves HTTP on port 80.

Ports

BBS needs two ports: HTTP for the web UI and API, and SSH for borg backup data transfer.

ports:
  - "8080:80"    # Web UI (HTTP)
  - "2222:22"    # SSH for borg agent connections

The SSH_PORT environment variable tells agents which port to connect to for backups — it must match the host-side port in your SSH port mapping (the left side of 2222:22).

To change the ports:

ports:
  - "443:80"      # Web UI on port 443
  - "22:22"       # SSH on standard port
environment:
  - APP_URL=https://backups.example.com
  - SSH_PORT=22

Data & Storage

Docker Volume (Default)

All persistent data lives in a single Docker volume (bbs-data) mounted at /var/bbs inside the container:

Path Contents
/var/bbs/home/ Borg repositories — one directory per client
/var/bbs/mysql/ MariaDB database files
/var/bbs/clickhouse/ ClickHouse catalog database (file-level search index)
/var/bbs/backups/ Server self-backup archives
/var/bbs/cache/ Borg cache (speeds up backup operations)

Each registered client gets its own SSH user and home directory under /var/bbs/home/. Borg repositories are created inside each client's home directory. This is all handled automatically when you add a client through the web UI.

Bind Mount (Specific Disk)

To store data on a specific disk or partition instead of a Docker volume:

volumes:
  - /path/to/your/storage:/var/bbs

This is useful when you want repositories on a large dedicated disk. Ensure the directory exists and has appropriate permissions before starting the container.

Remote SSH Storage

You don't have to store all repositories locally. BBS supports creating borg repositories on remote SSH hosts like rsync.net, BorgBase, and Hetzner Storage Box. With remote storage, backup data flows directly from agents to the remote host — no local disk is used for repository data, only catalog metadata is stored in the BBS database.

This is especially useful with Docker deployments where local storage may be limited. See Remote Storage for setup details.

What Happens on Startup

The application code and all dependencies are baked into the Docker image at build time — no downloads occur at runtime. The container's entrypoint script handles runtime setup on each start:

  1. Starts SSH server — for agent borg connections
  2. Starts MariaDB — initializes the data directory on first run
  3. Creates .env configuration — auto-generated on first run
  4. Imports database schema — on fresh installs only
  5. Runs migrations — applies any pending database migrations
  6. Recreates SSH users — restores client SSH users from the persistent volume
  7. Starts cron scheduler — runs the backup job queue every minute
  8. Starts Apache — serves the web UI

SSH Host Key Persistence

SSH host keys are stored on the persistent volume (/var/bbs/.ssh-host-keys/). This ensures agents don't see "host key changed" errors after a container rebuild or update. The keys are created on first run and restored on subsequent starts.

Updates

Pull the latest image and recreate the container:

docker compose pull
docker compose up -d

The new image includes the updated application code. On startup, any pending database migrations are applied automatically. Your data is stored on the Docker volume and is preserved across updates.

You can check for available updates from the web UI at Settings > Updates.

Pinning a Version

To pin to a specific release instead of always getting the latest:

image: marcpope/borgbackupserver:v1.2.2

Reverse Proxy Setup

For production deployments with HTTPS, place a reverse proxy in front of the BBS container.

Nginx Example

server {
    listen 443 ssl;
    server_name backups.example.com;

    ssl_certificate /etc/letsencrypt/live/backups.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/backups.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        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;
    }
}

Caddy Example

backups.example.com {
    reverse_proxy localhost:8080
}

Set APP_URL=https://backups.example.com in your docker-compose.yml so agents and the web UI use the correct URL.

Backup & Restore of BBS Itself

Backing Up

The Docker volume contains everything — database, repositories, SSH keys, and configuration. To back up:

docker compose stop
docker run --rm -v bbs-data:/data -v $(pwd):/backup alpine tar czf /backup/bbs-backup.tar.gz -C /data .
docker compose start

Restoring

docker compose stop
docker run --rm -v bbs-data:/data -v $(pwd):/backup alpine sh -c "rm -rf /data/* && tar xzf /backup/bbs-backup.tar.gz -C /data"
docker compose start

Building from Source

To build the Docker image locally instead of pulling from Docker Hub:

git clone https://github.com/marcpope/borgbackupserver.git
cd borgbackupserver
docker compose up -d --build

Or uncomment the build line in docker-compose.yml and comment out the image line:

# image: marcpope/borgbackupserver:latest
build: .

Troubleshooting

Container Won't Start

Check logs:

docker compose logs bbs

Common causes:

  • Port conflict — another service is using port 8080 or 2222
  • Insufficient disk space for the Docker volume

Agent Can't Connect via SSH

Verify the SSH port is accessible:

ssh -p 2222 bbs-1@localhost

Common causes:

  • SSH_PORT doesn't match the host-side port mapping
  • Firewall blocking the SSH port
  • Agent configured with wrong server hostname or port

Database Issues After Update

Migrations run automatically on container start. If you encounter errors:

docker compose exec bbs bash
cd /var/www/bbs
for f in migrations/*.sql; do mysql -u bbs -pbbs bbs < "$f" 2>/dev/null; done

Starting Fresh

To completely reset BBS and start over:

docker compose down -v    # removes container AND volume
docker compose up -d      # fresh start

Warning: This deletes all data including backups, configuration, and client registrations.


Next: Getting Started | Agent Setup | Remote Storage | Settings

Clone this wiki locally