-
-
Notifications
You must be signed in to change notification settings - Fork 0
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.
- 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)
Download the compose file and start the container:
curl -sO https://raw.githubusercontent.com/marcpope/borgbackupserver/main/docker-compose.yml
docker compose up -dThe pre-built image (marcpope/borgbackupserver) is pulled automatically from Docker Hub.
Get admin credentials from the container logs:
docker compose logs bbsLook for the credentials block:
========================================
ADMIN CREDENTIALS (SAVE THESE!)
========================================
URL: http://localhost:8080
Username: admin
Password: <random password>
========================================
Open http://localhost:8080 and log in.
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) |
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-hereThis 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.
For a production server with a real hostname and HTTPS (via a reverse proxy):
environment:
- APP_URL=https://backups.example.com
- SSH_PORT=2222You 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.
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 connectionsThe 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=22All 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.
To store data on a specific disk or partition instead of a Docker volume:
volumes:
- /path/to/your/storage:/var/bbsThis is useful when you want repositories on a large dedicated disk. Ensure the directory exists and has appropriate permissions before starting the container.
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.
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:
- Starts SSH server — for agent borg connections
- Starts MariaDB — initializes the data directory on first run
-
Creates
.envconfiguration — auto-generated on first run - Imports database schema — on fresh installs only
- Runs migrations — applies any pending database migrations
- Recreates SSH users — restores client SSH users from the persistent volume
- Starts cron scheduler — runs the backup job queue every minute
- Starts Apache — serves the web UI
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.
Pull the latest image and recreate the container:
docker compose pull
docker compose up -dThe 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.
To pin to a specific release instead of always getting the latest:
image: marcpope/borgbackupserver:v1.2.2For production deployments with HTTPS, place a reverse proxy in front of the BBS container.
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;
}
}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.
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 startdocker 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 startTo 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 --buildOr uncomment the build line in docker-compose.yml and comment out the image line:
# image: marcpope/borgbackupserver:latest
build: .Check logs:
docker compose logs bbsCommon causes:
- Port conflict — another service is using port 8080 or 2222
- Insufficient disk space for the Docker volume
Verify the SSH port is accessible:
ssh -p 2222 bbs-1@localhostCommon causes:
-
SSH_PORTdoesn't match the host-side port mapping - Firewall blocking the SSH port
- Agent configured with wrong server hostname or port
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; doneTo completely reset BBS and start over:
docker compose down -v # removes container AND volume
docker compose up -d # fresh startWarning: This deletes all data including backups, configuration, and client registrations.
Next: Getting Started | Agent Setup | Remote Storage | Settings
📖 User Manual
Getting Started
Using BBS
- Dashboard
- Managing Clients
- Linux Agent Setup
- macOS Agent Setup
- Windows Agent Setup
- Repositories
- Backup Plans
- Restoring Files
- Database Backups
- Plugins
- Remote Storage
- S3 Offsite Sync
Monitoring
Administration
Reference