Docker deployment

The fastest way to get started is to use the interactive install script. It fetches the latest release, prompts you for your settings, and sets everything up automatically.

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

Manual setup

  • Get the latest BorgWarehouse docker image from the docker hub.
docker pull borgwarehouse/borgwarehouse:latest
services:
  borgwarehouse:
    container_name: borgwarehouse
    image: borgwarehouse/borgwarehouse
    ports:
      - "${WEB_SERVER_PORT:?WEB_SERVER_PORT variable missing}:3000"
      - "${SSH_SERVER_PORT:?SSH_SERVER_PORT variable missing}:22"
    env_file:
      - .env
    volumes:
      - ${CONFIG_PATH:?CONFIG_PATH variable missing}:/home/borgwarehouse/app/config
      - ${SSH_PATH:?SSH_PATH variable missing}:/home/borgwarehouse/.ssh
      - ${SSH_HOST:?SSH_HOST variable missing}:/etc/ssh
      - ${BORG_REPOSITORY_PATH:?BORG_REPOSITORY_PATH variable missing}:/home/borgwarehouse/repos
  # Apprise is used to send notifications, it's optional. http://apprise:8000 is the URL to use in BorgWarehouse.
  apprise:
    container_name: apprise
    image: caronc/apprise
    user: "www-data:www-data"

Pick the .env.sample (rename it to .env) and adapt to your needs :

## Required variables section ##

# Host port mappings
WEB_SERVER_PORT=3000
SSH_SERVER_PORT=2222

# Hostname and URL
FQDN=your.domain.com
BETTER_AUTH_URL=https://your.domain.com

# Secrets
BETTER_AUTH_SECRET=your-secret
CRONJOB_KEY=your-other-secret

# PUID/PGID: the user and group ID the app will run as inside the container.
# Must match the owner of your volume directories on the host.
PUID=1000
PGID=1000

# Config and data folders (volume mounts)
# The host folders must be owned by the user with PUID and PGID specified above
CONFIG_PATH=./config
SSH_PATH=./ssh
SSH_HOST=./ssh_host
BORG_REPOSITORY_PATH=./repos

## Optional variables section ##

# LAN feature
FQDN_LAN=
SSH_SERVER_PORT_LAN=

# SMTP server settings
MAIL_SMTP_FROM=
MAIL_SMTP_HOST=
MAIL_SMTP_PORT=
MAIL_SMTP_LOGIN=
MAIL_SMTP_PWD=
MAIL_REJECT_SELFSIGNED_TLS=

# OAuth providers (optional) โ€” see https://borgwarehouse.com/docs/admin-manual/oauth-oidc/
# GITHUB_CLIENT_ID=
# GITHUB_CLIENT_SECRET=
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
# OIDC_ISSUER_URL=
  • Create the 4 volumes on the host and set the correct permissions.
    • mkdir config ssh ssh_host repos
    • chown -R YOUR_PUID:YOUR_PGID config ssh ssh_host repos
  • Launch the docker-compose file with docker compose up -d.
  • Set your scheduled tasks

Scheduled tasks

As a reminder, 2 important tasks require regular API calls to be triggered :

  • checking repository status, and sending alerts.
  • storage verification.

Since version 2.1.0, the cron service is no longer included with the container. This gives you full control over the schedule.

Since v3.2.0, docker-compose.yml includes a ready-to-use commented cron service using Supercronic, a production-ready cron for containers.

  1. Copy the example crontab file:
cp crontab.example crontab
  1. Edit crontab to adjust the schedule if needed (default: every hour).

  2. Uncomment the cron service in docker-compose.yml and restart:

docker compose up -d

Option 2 โ€” System cron (baremetal / external scheduler)

You can trigger the cron endpoints from any external cron service:

0 * * * * curl --request POST --url 'http://localhost:3000/api/v1/cron/status' --header 'Authorization: Bearer YOUR_CRONJOB_KEY'
0 * * * * curl --request POST --url 'http://localhost:3000/api/v1/cron/storage' --header 'Authorization: Bearer YOUR_CRONJOB_KEY'

Manual refresh

Since v3.2.0, a refresh button (โ†ป) is available in the repository list UI. Clicking it triggers a status and storage update immediately without waiting for the next cron run. This is useful for quick checks but does not replace the scheduled cron โ€” in particular, it does not send alerts.