Config (bmus.conf)

Updated on 28.01.2026

The configuration file bmus.conf contains all important parameters and settings. Read the following instructions carefully and thoroughly.

Let’s get started.

PATHS & NAMES

HOME_PI (Native version)

The path to the home directory on the master/source you want to backup.

HOME_PI="/home/user"  # Home directory in which BmuS is located.

HOME_PI (Docker version)

Because the working directory is defined in the Dockerfile and assigned to /app you should not change the path.

HOME_PI="/app"  # do not change!

DISK SPACE CHECK

Minimum free space required on the backup destination (in GB) before starting.

If the available space (or user quota) is below this value, the backup will abort to prevent filling up the storage completely.

0 = Disabled (Default)
10 = Abort if less than 10 GB are available
MIN_FREE_SPACE_GB="0"

MYSQL CONFIGURATION

BmuS can create MySQL database dumps from any number of databases. Here you activate the function and specify the database names. The login credentials for the database is stored in the .bmus_credentials file.

BACKUP_SQL

If a database needs to be backed up, this can be activated here.

BACKUP_SQL="1"      # 1 = activated, 0 = disabled

MYSQL_DBS

Databases to be backed up in array (separated by spaces).

MYSQL_DBS=("database_1" "database_2")

BACKUP SOURCES (Native version)

This array contains all paths or files that should be backed up. You can also work with wildcards (*).

BACKUP_SOURCES=(
"/usr/local/bin/*.sh"
"/var/www/html/"
"/home/pi/Desktop/"
"/home/pi/.msmtp-pass.sh"
"/home/pi/.msmtprc"
"/home/pi/.bash_history"
)

BACKUP SOURCES (Docker version)

We’ve mapped / to /host_root/ in docker-compose.yml

This is why all paths must start with: /host_root/

For example: /var/www/ -> /host_root/var/www/

BACKUP_SOURCES=(
"/host_root/usr/local/bin/*.sh"
"/host_root/var/www/html/"
"/host_root/home/pi/Desktop/"
"/host_root/home/pi/.msmtp-pass.sh"
"/host_root/home/pi/.msmtprc"
"/host_root/home/pi/.bash_history"
)

BACKUP EXCLUSIONS

It’s a good idea to exclude files and file types from backup. Be it because they are irrelevant or because they change during a backup run and then produce errors when verification is activated (BACKUP_VERIFICATION=1).

EXCLUDE_ITEMS=(
    ".git"
    "*.tmp"
    "*.cache"
    ".DS_Store"       # Mac Metadata (Disallowed by Dropbox)
    ".~lock.*"        # Office Lock Files (Disallowed by Dropbox)
    "Thumbs.db"       # Windows Thumbnails
    "@eaDir/"         # Synology Indexing
)

LOGFILE (Native version)

BmuS writes a log file that can be sent by email, but is also integrated into the dashboard. Here you can specify the path and name of the log. This file is created automatically.

LOGFILE="/home/user/bmus.log"    # Log file

LOGFILE (Docker version)

While the BmuS program files (e.g., bmus.sh, bmus_encryption.sh, etc.) are stored permanently in the Docker image, the configuration files are stored in the /config folder on the host system after unzipping the Docker zip file. The log file is also written there. Therefore, the path /config should be left unchanged here.

LOGFILE="/config/bmus.log"    # Log file

Example log:

-----------------------------------------------------------------------------------
[01.12.2025 23:30:01] - Starting backup from (192.168.0.xxx) to NAS (192.168.0.xxx)
-----------------------------------------------------------------------------------

[01.12.2025 23:30:01] - Credentials successfully loaded from: /home/pi/.bmus_credentials
[01.12.2025 23:30:01] - Checking NAS reachability: 192.168.0.166
[01.12.2025 23:30:01] - Ping attempt 1 of 3...
[01.12.2025 23:30:02] - ✓ NAS successfully reached: 192.168.0.166
[01.12.2025 23:30:02] - Mountpoint /mnt/workstation exists
[01.12.2025 23:30:02] - Attempt [1/3] Mounting Share
[01.12.2025 23:30:03] - Share /mnt/workstation successfully mounted
[01.12.2025 23:30:03] - Deduplication is enabled
[01.12.2025 23:30:03] - [ENABLED] Deduplication strategy: incremental
[01.12.2025 23:30:03] - Testing hardlink support...
[01.12.2025 23:30:12] - [✓] Hardlink support: Available
[01.12.2025 23:30:12] - Searching reference backup in: /mnt/workstation
[01.12.2025 23:30:12] - Max. age for reference: 14 days
[01.12.2025 23:30:12] - Searching reference backup in nested date folders...
[01.12.2025 23:30:12] - Reference backup found: /mnt/workstation/2025-11-30/2025-11-30_23-30-13
[01.12.2025 23:30:12] - Reference backup found: 2025-11-30_23-30-13
[01.12.2025 23:30:12] - Nested folder structure created: /mnt/workstation/2025-12-01/2025-12-01_23-30-12
[01.12.2025 23:30:12] - Backup directory: 2025-12-01_23-30-12
[01.12.2025 23:30:12] - Target path for backup: /mnt/workstation/2025-12-01/2025-12-01_23-30-12
[01.12.2025 23:30:12] - Searching for unencrypted backups older than 7 days...
[01.12.2025 23:30:12] - Folder mode: Delete timestamped folders
[01.12.2025 23:30:12] - Nested folder mode: Delete old folders within date folders
[01.12.2025 23:30:14] - Total 0 unencrypted backup files deleted
[01.12.2025 23:30:14] - Starting Backup
[01.12.2025 23:30:14] - Backing up MySQL database: stromzaehler
[01.12.2025 23:30:17] - mysqldump /mnt/workstation/2025-12-01/2025-12-01_23-30-12/2025-12-01-stromzaehler.sql successfully created
[01.12.2025 23:30:17] - SQL dump size (4774452 Bytes) added to total size.
[01.12.2025 23:30:17] - Backing up MySQL database: phpmyadmin
[01.12.2025 23:30:18] - mysqldump /mnt/workstation/2025-12-01/2025-12-01_23-30-12/2025-12-01-phpmyadmin.sql successfully created
[01.12.2025 23:30:18] - SQL dump size (19818 Bytes) added to total size.

═══════════════════════════════════════════════════════════════
✅ BATCH PROCESSING STARTED                   
   Total sources: 5
   Batch size: 2 sources
   Pause between batches: 5s
   RAM threshold: 200 MB
═══════════════════════════════════════════════════════════════

[01.12.2025 23:30:18] - Creating detailed deduplication log...
[01.12.2025 23:30:18] - Detailed deduplication log created: /tmp/bmus_dedup.log
[01.12.2025 23:30:18] - 📦 Backup 1 of 5 (Batch #1)
[01.12.2025 23:30:18] - Bandwidth limit active: 5000 KB/s
[01.12.2025 23:30:18] - Deduplication active: Link-Dest = html
[01.12.2025 23:30:18] - Compression disabled
[01.12.2025 23:30:18] - Starting rsync with nice=19, ionice=3
[01.12.2025 23:30:23] - Copying of /var/www/html/ finished: 0 new, 0 new directories
[01.12.2025 23:30:23] - 📦 Backup 2 of 5 (Batch #1)
[01.12.2025 23:30:23] - Bandwidth limit active: 5000 KB/s
[01.12.2025 23:30:23] - Deduplication active: Link-Dest = Desktop
[01.12.2025 23:30:23] - Compression disabled
[01.12.2025 23:30:23] - Starting rsync with nice=19, ionice=3
[01.12.2025 23:31:31] - Copying of /home/pi/Desktop/ finished: 0 new, 0 new directories

──────────────────────────────────────────────────────────────────
  ✅ Batch #1 completed
  ⏸️ BATCH PAUSE: Waiting 5s before Batch #2...
──────────────────────────────────────────────────────────────────
[01.12.2025 23:31:31] - RAM before sync: 630 MB
[01.12.2025 23:31:31] - Syncing data before pause...
[01.12.2025 23:31:31] - RAM after sync: 630 MB (Difference: 0 MB)
[01.12.2025 23:31:37] - RAM OK: 630 MB available

[01.12.2025 23:31:37] - 📦 Backup 3 of 5 (Batch #2)
[01.12.2025 23:31:37] - Bandwidth limit active: 5000 KB/s
[01.12.2025 23:31:37] - Deduplication active: Link-Dest = 2025-11-30_23-30-13
[01.12.2025 23:31:37] - Compression disabled
[01.12.2025 23:31:37] - Starting rsync with nice=19, ionice=3
[01.12.2025 23:31:37] - Copying of /home/pi/.msmtp-pass.sh finished: 0 new, 0 new directories
[01.12.2025 23:31:37] - 📦 Backup 4 of 5 (Batch #2)
[01.12.2025 23:31:37] - Bandwidth limit active: 5000 KB/s
[01.12.2025 23:31:37] - Deduplication active: Link-Dest = 2025-11-30_23-30-13
[01.12.2025 23:31:37] - Compression disabled
[01.12.2025 23:31:37] - Starting rsync with nice=19, ionice=3
[01.12.2025 23:31:38] - Copying of /home/pi/.msmtprc finished: 0 new, 0 new directories

──────────────────────────────────────────────────────────────────
  ✅ Batch #2 completed
  ⏸️ BATCH PAUSE: Waiting 5s before Batch #3...
──────────────────────────────────────────────────────────────────
[01.12.2025 23:31:38] - RAM before sync: 629 MB
[01.12.2025 23:31:38] - Syncing data before pause...
[01.12.2025 23:31:38] - RAM after sync: 629 MB (Difference: 0 MB)
[01.12.2025 23:31:43] - RAM OK: 629 MB available

[01.12.2025 23:31:43] - 📦 Backup 5 of 5 (Batch #3)
[01.12.2025 23:31:43] - Bandwidth limit active: 5000 KB/s
[01.12.2025 23:31:43] - Deduplication active: Link-Dest = 2025-11-30_23-30-13
[01.12.2025 23:31:43] - Compression disabled
[01.12.2025 23:31:43] - Starting rsync with nice=19, ionice=3
[01.12.2025 23:31:43] - Copying of /home/pi/.bash_history finished: 0 new, 0 new directories

═══════════════════════════════════════════════════════════════
✅ BATCH PROCESSING FINISHED                     
✅ All 5 sources backed up in 3 batches
═══════════════════════════════════════════════════════════════

[01.12.2025 23:31:43] - Calculating deduplication statistics...
[01.12.2025 23:31:43] - Verifying hardlink creation...
[01.12.2025 23:31:45] - Deduplication statistics:
[01.12.2025 23:31:45] - Hardlinks created: 0 files
[01.12.2025 23:31:45] - Deduplication rate: 0.0%
[01.12.2025 23:31:45] - Total number of files: 91
[01.12.2025 23:31:45] - Deduplication rate calculated: 0.0%
[01.12.2025 23:31:45] - No hardlinks created (0.0% deduplication)
[01.12.2025 23:31:45] - Possible causes: Files were changed since last backup
[01.12.2025 23:31:45] - Reference backup contains: 97 files
[01.12.2025 23:31:45] - Deduplication performance: 0 hardlinks in 2 seconds
[01.12.2025 23:31:45] - New backup files: 0 items
[01.12.2025 23:31:45] - Copy errors: 0
[01.12.2025 23:31:45] - New directories: 0 items
[01.12.2025 23:31:45] - Total size of today's backup: 83MB
[01.12.2025 23:31:45] - Backup duration: 104 seconds (1.73 minutes)

[01.12.2025 23:31:45] - Writing Detailed File Log...
[01.12.2025 23:31:46] - Detailed File Log successfully written: /mnt/workstation/bmus_file.log (1,3KB)

═══════════════════════════════════════════════════════════
📋 DIFFERENTIAL BACKUP INFO (Changed files)
═══════════════════════════════════════════════════════════
↻ MOD: smartmeter.log (79MB)

═══════════════════════════════════════════════════════════
📂 NEW DIRECTORIES
═══════════════════════════════════════════════════════════
No new directories in this backup.
═══════════════════════════════════════════════════════════
[01.12.2025 23:31:46] - Backing up BmuS system files...
[01.12.2025 23:31:46] - System file backed up: bmus.sh
[01.12.2025 23:31:46] - System file backed up: bmus.conf
[01.12.2025 23:31:46] - System file backed up: .bmus_credentials
[01.12.2025 23:31:46] - System file backed up: bmus_dashboard.sh
[01.12.2025 23:31:46] - System file backed up: bmus_encryption.sh
[01.12.2025 23:31:46] - System file backed up: english.lang
[01.12.2025 23:31:46] - BmuS system files backed up: 6 successful, 0 errors
[01.12.2025 23:31:46] - Checking history rotation (Max. 365 days)
[01.12.2025 23:31:46] - History entry added
[01.12.2025 23:31:46] - Deduplication rate saved to history: 0.0%
[01.12.2025 23:31:46] - Generating dashboard /tmp/backup_dashboard_2025-12-01_23-31-46.html
[01.12.2025 23:31:47] - Dashboard generated: /tmp/backup_dashboard_2025-12-01_23-31-46.html
[01.12.2025 23:31:47] - Dashboard saved to NAS: /mnt/workstation/bmus_dashboard.html
[01.12.2025 23:31:47] - Access via: http://192.168.0.166:5001/BackupGasPi/bmus_dashboard.html
[01.12.2025 23:31:47] - Detailed deduplication log created: /mnt/workstation/bmus_dedup.log
[01.12.2025 23:31:47] - Deduplicated files logged: 0
[01.12.2025 23:31:47] - Syncing NAS data before unmount...
[01.12.2025 23:31:49] - Checking prerequisites zip for mail sending
[01.12.2025 23:31:50] - zip found
[01.12.2025 23:31:50] - Checking prerequisites msmtp for mail sending
[01.12.2025 23:31:50] - msmtp found
[01.12.2025 23:31:50] - Sending mail to user@fancyprovider.com...
[01.12.2025 23:31:51] - Mail successfully sent to user@fancyprovider.com
[01.12.2025 23:31:51] - Temporary ZIP deleted: /tmp/bmus_01.12.2025_23-31-50.zip
[01.12.2025 23:31:51] - Temporary dashboard copy deleted: /tmp/backup_dashboard_2025-12-01_23-31-46.html
[01.12.2025 23:31:51] - Temporary deduplication log deleted: /tmp/bmus_dedup.log
[01.12.2025 23:31:51] - umount /mnt/workstation successful
[01.12.2025 23:31:51] - Backup finished

BACKUP_PATH

The mount path is the path on the master to which the shared directory of the NAS is mounted. This directory is created automatically.

BACKUP_PATH="/mnt/workstation"    # Mount point for NAS

HISTORY_PATH

The history is the database that logs the history of backups. It is created automatically.

HISTORY_PATH="$BACKUP_PATH/bmus_history.csv" # Path to the history file.

Content:

Date,Time,Duration_Sec,Size_Bytes,New_Files,New_Dirs,Copy_Errors,Verification_Errors,Deleted_Backups,Dedup_Rate,Status
2025-11-19,23:34:12,251,4136512,0,0,0,0,0,0.6,Success
2025-11-20,09:34:23,262,4133422,0,0,0,0,0,0.6,Success

DASHBOARD_FILENAME

The name of the HTML dashboard to be generated must be specified here. The dashboard is automatically written to the NAS, i.e. under the path defined in BACKUP_PATH. So actually only the name of the file can be configured here. The path is hardcoded to make sure the dashboard ends up on the NAS so it can be accessed from the report-email via WebDAV.

DASHBOARD_FILENAME="bmus_dashboard.html" # Dashboard file name

HISTORY_MAX_AGE_DAYS

The .csv, i.e. the database into which the history of the backups is written, is rotated after the days specified in HISTORY_MAX_AGE_DAYS have expired. This means that the .csv is renamed, archived and a new file is created.

HISTORY_MAX_AGE_DAYS=365     # Rotate old history entries (0 = disabled)

Example: After 365 days, old entries will be outsourced to:
backup-history_rotated_date_time.csv

BACKUP_HISTORY_ENABLE

If you do not want to generate a history file, you can specify this here. However, this means that there will no longer be any graphs or statistics in the dashboard. And who would want that? That’s the whole fun. Isn’t it?

BACKUP_HISTORY_ENABLE=1  # Write history? If 0, no graphs & stats

DASHBOARD_LINE_LOGS

Here you can specify how many lines of the log (scrollable) should be integrated into the dashboard. Since the dashboard is also sent by email (if you wish), you may want to ensure that the file does not become too large.

DASHBOARD_LINE_LOGS=500 # Number of log lines in the dashboard

DASHBOARD_LINE_NEW_DIRS

This variable controls the maximum number of lines in the log or dashboard that are displayed when new directories are backed up and logged. This can be a lot, especially during the initial backup.

DASHBOARD_LINE_NEW_DIRS=300 # Number of log lines of new dirs in dashboard

CREDENTIALS_FILE (Native version)

This file contains the access data for the NAS and any MySQL databases.

CREDENTIALS_FILE="/home/user/.bmus_credentials" # Password file

CREDENTIALS_FILE (Docker version)

The configuration files are stored in the /config folder on the host system after unzipping the Docker zip file. The credentials file is also stored here. Therefore, the path /config should be left unchanged here.

CREDENTIALS_FILE="/config/bmus_credentials" # Password file

First Check & Dry Run

FIRST_CHECK

During the first run, BmuS checks whether all the necessary packages are installed and settings have been made so BmuS can run. If this is the case, the FIRST_CHECK value automatically changes from 1 to 0 (provided the write permissions are sufficient). From the next start, the system check will be skipped. If you want to trigger it again, you can manually set the variable to 1 again. This makes sense if you install BmuS on another system.

FIRST_CHECK=1 # 1 = At first start, 0 = After successful test

DRY_RUN

Dry run mode simulates script execution and does not make any changes. This is useful if you want to change something in the code or configuration and test whether BmuS is executable.

DRY_RUN=0  # 0 = Normal, 1 = Simulation without changes

Recommendation: Leave DRY_RUN=0 and call this mode from bash using the --dry-run or -n parameter.

Example:

sudo bash ./bmus.sh -n

PRIVACY & STATISTICS

For a developer, it’s naturally important to know how often and in which version their program is used. Therefore, there’s a harmless tracking function in the dashboard that sends the following information to this server:

Date, Native or Docker version, Core version, and anonymized IP address.

This is what it looks like: 2026-01-19 20:54:09 native 26.7 97.4.112.xxx

This function can, of course, be disabled, but I would appreciate it if you would leave it enabled. It’s very helpful and completely harmless.

ALLOW_USAGE_STATS="1" # 0 = Disabled, # 1 = Enabled (Default)

You can see for yourself what the code looks like:

In bmus.sh:

This block tries to determine whether bmus is running as a native or docker variant.

# Detect Execution Mode for Statistics
if [ -f "/.dockerenv" ]; then
    EXEC_MODE="docker"
else
    EXEC_MODE="native"
fi

This block extract the version number from the header of bmus.sh.

BMUS_VERSION=$(head -n 5 "$0" | grep "v\.[0-9]" | sed 's/.*v\.\([0-9.]*\).*/\1/')

bmus_dashboard.sh & bmus_dashboard_pro.sh:

This block receives the version number and type (native or docker) from bmus.sh

exec_mode="${30:-native}"
script_version="${31:-unknown}"

This block constructs the URL that calls a PHP script on the server, which then writes the statistics.


if [ "${ALLOW_USAGE_STATS:-1}" -eq 1 ]; then
        TRACKING_URL="https://www.back-me-up-scotty.com/usage/spacer.php?mode=$exec_mode\&v=$script_version"
        TRACKING_HTML="<img src='$TRACKING_URL' style='width:1px;height:1px;opacity:0.01;' alt=''>"
    else
        TRACKING_HTML=""
    fi

This is a placeholder for the URL.

 </script>
</body>
TRACKING_PIXEL_PLACEHOLDER
</html>

Here, sed replaces the placeholder with the URL

sed -i "s|TRACKING_PIXEL_PLACEHOLDER|$TRACKING_HTML|g" "$out"

NAS_MOUNT_MODE

nas_mount_mode determines how BmuS connects to the NAS or network storage. You can choose between cifs_optimized, cifs_simple, and nfs.

NAS_MOUNT_MODE="nfs"

cifs_optimized (SMB)

Adding mfsymlinks also copies symlinks (or simulates the behavior). This prevents copy errors. cifs_optimized does two more things that are important for databases and deduplication:

nobrl (No Byte Range Locking):

What it does: It prevents your system from asking the NAS, “Can I lock this file while I’m reading it?”

Example: You are backing up SQLite databases (e.g., /etc/pihole/gravity.db, /var/lib/grafana/grafana.db). Without nobrl, the copy process may be interrupted with SMB because the database is currently “locked” or the NAS does not implement locking cleanly. nobrl ignores this and simply copies the bytes “brutally.” This is usually better and faster for backups.

noserverino (client-side inodes):

What it does: Your OS generates its own identification numbers (inodes) for the files instead of using those from the NAS.

When you need it: Some NAS systems change the inode numbers of files after a restart or update. When this happens, rsync thinks the next time it runs: “Whoa, all the inodes are different? These are all new files!” -> Deduplication is broken, everything is copied again. noserverino reliably prevents this.

Important note: The deduplication logs no longer work in the dashboard. This only works with cifs_simple and nfs. It is recommended to use one of these two modes if you want to keep the deduplication logs. cifs_simple is the default.

cifs_optimized (SMB)

cifs_simple is the compatibility mode. It is robust, supports Linux system files (thanks to mfsymlinks), and works with almost any NAS. It is slightly slower than NFS but offers accurate statistics for deduplication on most modern NAS systems.

cifs_simple respects the NAS server’s file locking (brl) and Inode numbering (serverino).

cifs_optimized disables these checks (nobrlnoserverino) to gain speed and prevent database locks, but usually reports “0% Deduplication” because the file IDs (Inodes) are simulated by the client.

nfs

NFS is the native file sharing protocol for Linux/Unix systems. Unlike SMB/CIFS (which emulates Windows behavior), NFS speaks the same language as your Linux or Raspberry Pi. It creates a seamless connection between the client and the server (NAS) with very little processing overhead.

nfs is the High-Performance Mode. It strips away all compatibility layers and safety checks (like file locking) to achieve raw transfer speed. It relies on IP-address authorization rather than passwords. It is the best choice if you want your backups to finish as quickly as possible.

Important

Ensure that NFS is enabled on the NAS. If BmuS still does not connect after activation and spits out errors, or if it runs but does not create folders, this may be because the NAS does not trust the client.

Why NFS “acts up” and CIFS works?

The difference lies in the type of “doorman”.

SMB/CIFS (the friendly bouncer):

  1. It asks: “Do you have a username and password?”
  2. Linux/Pi says: “Yes, here: NAS_USER / NAS_PASS.”
  3. NAS: “All right, come in, you can write.”

Result: It works immediately.

NFS (the strict bouncer):

  1. It doesn’t ask for a password. It looks at the ID (the IP address).
  2. Your NAS has the following stored in the NFS rules: “The IP 192.168.0.62 (your Linux/Pi) is allowed to come in and write.”

The tricky part: Many NAS devices allow unknown IPs from the same subnet to enter (mount works -> script thinks “Everything is okay”), but by default they only give them read-only rights or treat them as guests.

Consequence: The script mounts successfully (exit code 0), then tries to create directories (mkdir), which fails silently or is not caught hard enough by error handling because the file system is “there,” just read-only.

Solution

You must introduce the (new) IP address to the NAS.

  1. Find out the IP of the Linux/Pi hostname -I
  2. Log in to your NAS (Synology/UGREEN etc).
  3. Go to the settings of the backup folder (e.g. Backup).
  4. Go to NFS Permissions.
  5. Add a new rule (or copy the one from the old Linux/Pi).
  6. IP: The IP of the new Linux/Pi.
  7. Privilege: Read/Write.
  8. Squash: “All to Admin.” (Important so that it can write!).
  9. Asynchronous: Enable (for performance).

Once you have saved this, BmuS will with NAS_MOUNT_MODE="nfs" and the usual performance.

Mode Comparison

ModeProsConsBest For
cifs_simple• Maximum Compatibility: 
Works with almost any NAS out of the box.
• Easy Setup: Standard SMB/CIFS protocol (vers=3.0).
• Slowest Performance: High protocol overhead for metadata checks.
• Timeout Prone: Can cause timeouts/freezes with many small files (as seen in your logs).
• Strict Permissions: Often requires ignoring ownership/groups to work without errors.
Simple setups where NFS is not available and file count is low.
cifs_optimized• Better Stability: Uses mfsymlinksnobrl, and noserverino to prevent timeouts and locking errors.
• Symlink Support: Better handling of system files and symlinks.
• Faster than Simple: Reduces some overhead.
• No Dedup Logs: The script explicitly states “No deduplication logs are created!” in this mode because inode numbers are client-generated.
• Still SMB: Still suffers from some protocol overhead compared to NFS.
Users who must use SMB(e.g., Windows-focused NAS) but need better stability than “simple”.
nfs
(Recommended)
• Fastest Performance: Native Linux protocol with minimal overhead.
• Correct Stats: Accurate file attributes and hardlink handling (perfect for deduplication stats).
• Reliable: Optimized in your script with asyncnoatime, and actimeo=600for maximum rsync speed.
• Setup Required: Requires enabling NFS on the NAS and configuring IP permissions (exports).
• Security: Usually relies on IP-based authentication rather than user/password.
Linux-to-Linux backups (like Raspberry Pi to Synology/QNAP) where speed and reliability are the priority.

LANGUAGE

Here you can specify which language file should be loaded. BmuS is available in German, English, French, Spanish, Italian, and Hebrew.

LANGUAGE="english"

The parameters are: german, english, french, spanish, italian, hebrew

You can take any of the language files at any time, have them automatically translated into any language, and add new languages. The file format must be as follows:

language.lang # Example: greek.lang

Attention: When changing or adding a language file, make sure to to escape characters that could break the dashboard’s JavaScript (pro version). For example:

CHART_TITLE_ERROR_RATE_TREND="Tendance du Taux d'Erreur" # incorrect
CHART_TITLE_ERROR_RATE_TREND="Tendance du Taux d\'Erreur" # correct

Docker version

The language files are not included in the download (ZIP file) of the Docker version. They are located in the image itself and are automatically copied from the Docker container to the /config directory on the host when BmuS is run for the first time.

NETWORK CONFIGURATION

The IP addresses of the master (whose data you want to back up) and the NAS (on which you want to perform the backup) are specified here. The name of the share or folder that has been shared on the NAS for backup is also noted here. You can also specify how often BmuS attempts to mount the NAS and at what intervals the mount attempt is made before it is aborted.

MASTER_IP="192.168.0.xxx"    # IP of master
NAS_IP="192.168.0.xxx"       # IP of NAS
NAS_SHARE="Backup"           # Name of the cifs/samba NAS share
NAS_SHARE_NFS="/volume1/Backup" # NFS Absolute Path. 
MOUNT_RETRIES=2              # How many mount attempts before abort
MOUNT_RETRY_DELAY_SECONDS=5  # Interval between mount attempts

MAIL CONFIGURATION

The email address to which the report should be sent is specified here. If you don’t want to receive an email report, you can deactivate this using the SEND_MAIL variable. The subject line can be freely customized.

EMAIL="your@email.com"        # Recipient address for report
SEND_MAIL=1                  # 1 = activated, 0 = deactivated
EMAIL_SUBJECT="Backup Logfile $(date '+%d.%m.%Y %H:%M:%S')"

DASHBOARD CONFIGURATION (SIMPLE)

In this section you set whether the dashboard is created or not. The standard version of the dashboard creates a rudimentary dashboard. The path to the dashboard generator must be specified.

DASHBOARD_ENABLE=1           # 1 = activated, 0 = deactivated
DASHBOARD_MODE="simple"      #  "simple"
DASHBOARD_GENERATOR="/home/user/bmus_dashboard.sh"

DASHBOARD CONFIGURATION (ADVANCED/Pro)

If you have bought the pro version of the dashboard, DASHBOARD_MODE and DASHBOARD_GENERATOR must be adjusted.

DASHBOARD_ENABLE=1           # 1 = activated, 0 = deactivated
DASHBOARD_MODE="simple"      # or "advanced"
DASHBOARD_GENERATOR="/home/user/bmus_dashboard_pro.sh"

Dashboard modes:

simple:

advanced:

  • With interactive charts
  • Trend analysis
  • Charts for size, duration, errors, retention, backup efficiency, speed, error trend, day of week analysis, backup types by time, deduplication efficiency, cpu load, ram load, I/O write.
  • List of changed files
  • List of de-duplicated files

Example: https://www.back-me-up-scotty.com/docs/what-is-bmus/buy-pro-dashboard/

Docker version

If you are using the Docker version and have purchased Dashboard Pro, place it in the /config folder. Change the path to this folder.

DASHBOARD_ENABLE=1           # 1 = activated, 0 = deactivated
DASHBOARD_MODE="simple"      # or "advanced"
DASHBOARD_GENERATOR="/config/bmus_dashboard_pro.sh"

BACKUP SCRIPT FILES

Since errors can occur when BmuS saves itself during operation, a routine has been implemented that allows BmuS and all its files to be saved without disrupting the backup run.

BACKUP_SCRIPT_ENABLE=1 # 1 = activated, 0 = deactivated

Which files should be backed up by BmuS can be determined in the following array.

Native version:

BACKUP_SCRIPT_FILES=(
"$HOME_PI/bmus.sh"
"$HOME_PI/bmus.conf"
"$HOME_PI/.bmus_credentials"
"$HOME_PI/bmus_dashboard.sh"
"$HOME_PI/bmus_dashboard_pro.sh" # If pro version is available
"$HOME_PI/bmus_encryption.sh"
"$HOME_PI/${LANGUAGE}.lang"
)

Docker version:

BACKUP_SCRIPT_FILES=(
"$HOME_PI/bmus.sh"
"/config/bmus.conf"
"/config/bmus_credentials"
"$HOME_PI/bmus_dashboard.sh"
"$HOME_PI/bmus_dashboard_pro.sh" # If pro version is available
"$HOME_PI/bmus_encryption.sh"
"$HOME_PI/${LANGUAGE}.lang"
)

DETAILED FILE LOG CONFIGURATION

The „detailed log“ actually logs all files that were backed up during a run, as the log built into the dashboard only shows the top files. This gives more control over what BmuS does (or doesn’t). The log file is created automatically. The path can be used to control where it should be written.

WRITE_DETAILED_FILELOG

The function can be activated and deactivated here.

WRITE_DETAILED_FILELOG=1 # 1 = activated, 0 = deactivated

DETAILED_FILELOG_PATH

Path to the log and name of the log.

DETAILED_FILELOG_PATH="$BACKUP_PATH/bmus_file.log" # Path and name of log

ENCRYPTION CONFIGURATION

The encryption is controlled in this area. It requires gocryptfs and must be installed if you set BACKUP_ENCRYPTION to 1. You should definitely test the encryption, but especially the decryption, before testing it on important data.

BACKUP_ENCRYPTION

Enable or disable encryption.

BACKUP_ENCRYPTION=0           # 1 = activated, 0 = deactivated

Important note: gocryptfs (BACKUP_ENCRYPTION=1) does NOT work with deduplication (DEDUP_ENABLE=1) (see chapter “Deduplication”). gocryptfs does not support hardlinks in this mode. This combination results in ZERO storage savings but still creates the deduplication structure. You have to decide between BACKUP_ENCRYPTION=1 and DEDUP_ENABLE=1. BmuS detects this configuration error and stops executing the backup in order to prevent you from wasting space.

ENCRYPTION_METHOD

The encryption method used can be specified here. Standard is gocryptfs for regular backups.

ENCRYPTION_METHOD="gocryptfs"   # or gpg for MySQL backups

ENCRYPTION_PASSWORD_FILE (Native version)

The path to the password file, which is used to encrypt and decrypt the data.

ENCRYPTION_PASSWORD_FILE="/home/user/.bmus_encryption_pass"

This file must be created.

ENCRYPTION_PASSWORD_FILE (Docker version)

In the Docker version, the file bmus_geocryptfs is located in the zip file (/config). Simply enter the password here.

ENCRYPTION_PLAINTEXT_MOUNT

Specifying the path and temporary mount directory for unencrypted backups. It will be created.

ENCRYPTION_PLAINTEXT_MOUNT="/mnt/backup_decrypted"

ENCRYPTION_CIPHERTEXT_DIR

The path and folder in which the encrypted files should be saved on the NAS is specified here. Will be created.

ENCRYPTION_CIPHERTEXT_DIR="$BACKUP_PATH/encrypted"

BACKUP_ENCRYPTION_SCRIPT

Name of the encryption module.

BACKUP_ENCRYPTION_SCRIPT="bmus_encryption.sh"

ENCRYPTED BACKUP RETENTION

ENCRYPTED_BACKUP_AGE_DAYS

Deletes old encrypted backups after X days (regardless of normal retention period). This applies to the ENCRYPTION_CIPHERTEXT_DIR directory to prevent memory overflow. Set the value to 0 to disable retention of encrypted backups. Recommendation: Set a higher value than BACKUP_AGE_DAYS.

ENCRYPTED_BACKUP_AGE_DAYS=10

Warning: If READABLE_NAMES=0, the file and folder names will be encrypted.

The problem is that BmuS deletes the files based on the folder name, which is composed of the backup date. BmuS does not delete based on the age of the file or the last modification date, as these timestamps may be younger than the original backup date.

If the folder names are encrypted, BmuS can no longer recognize the creation date of the folder. BmuS then falls back on checking the timestamp of the folder or file.

However, if this timestamp has been changed in the meantime by a third-party system (NAS), BmuS may not delete the file because the timestamp is not (yet) outside the interval defined in ENCRYPTED_BACKUP_AGE_DAYS.

Solution: (1) Either you wait until this is the case (which might be the day after) and hope that your NAS (or wherever these files are stored) no longer changes the timestamps, or (2) you have to manually delete the skipped folders and files.

In any case, the routine works reliably for encrypted and unencrypted folders and files that were created with READABLE_NAMES=1.

A flow chart for a better understanding of the logic:

Encrypted Backup Retention
flowchart TD
    %% Styling Definitionen (Schwarzschrift erzwungen)
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px,color:black;
    classDef process fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:black;
    classDef decision fill:#fff9c4,stroke:#fbc02d,stroke-width:2px,color:black;
    classDef terminator fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:black;
    classDef delete fill:#ffebee,stroke:#c62828,stroke-width:2px,color:black;
    classDef warning fill:#ffccbc,stroke:#bf360c,stroke-width:2px,color:black;

    Start([START BMUS SCRIPT]) --> LoadConfig[Load bmus.conf]
    LoadConfig --> DecisionMode{DECISION:<br>Which Backup Mode?}

    %% --- DEDUPLICATION BRANCH ---
    DecisionMode -- "DEDUP_ENABLE = 1" --> ModeDedup[MODE: DEDUPLICATION<br>Rsync Link-Dest]
    ModeDedup --> StructDedup[Structure:<br>/YYYY-MM-DD/YYYY-MM-DD_HH-MM-SS/]
    StructDedup --> RetUnencInfo[RETENTION Cleanup unencrypted:<br>Name-based Deletion - Very Safe]

    %% --- ENCRYPTION BRANCH ---
    DecisionMode -- "BACKUP_ENCRYPTION = 1" --> ModeEnc[MODE: ENCRYPTION<br>Gocryptfs]
    ModeEnc --> DecisionNames{READABLE_NAMES?}
    
    DecisionNames -- "1 (Yes)" --> NamePlain[Folders named<br>'2025-12-03'<br>Plaintext]
    DecisionNames -- "0 (No)" --> NameCrypt[Folders named<br>'A1s8d7...'<br>Cryptic]
    
    NamePlain --> RetEncInfo[RETENTION:<br>Handled below in Cleanup phase]
    NameCrypt --> RetEncInfo

    %% --- COMMON EXECUTION ---
    RetUnencInfo --> BackupRun[BACKUP PROCESS RUNNING...<br>Files are being copied]
    RetEncInfo --> BackupRun

    %% --- CLEANUP PHASE ---
    BackupRun --> CleanupStart((CLEANUP PHASE<br>Retention System))

    %% 1. Unencrypted Cleanup
    CleanupStart --> CleanUnenc[1. UNENCRYPTED CLEANUP<br>Applies if DEDUP=1 or Standard]
    CleanUnenc --> CheckAgeUnenc{Check<br>BACKUP_AGE_DAYS}
    CheckAgeUnenc -- "Older than X" --> DelFolderUnenc[DELETE FOLDER<br>where NAME is older than X days]:::delete

    %% 2. Encrypted Cleanup
    CleanupStart --> CleanEnc[2. ENCRYPTED CLEANUP<br>Runs if folders exist]
    CleanEnc --> CheckEncExist{Encrypted folder exists<br>& Days > 0?}
    
    CheckEncExist -- Yes --> CaseFolderStruct{BACKUP_USE_DATE_FOLDERS?}
    
    %% Case A: Folder Mode
    CaseFolderStruct -- "1 (Folder Mode)" --> CheckReadNamesCleanup{READABLE_NAMES?}
    
    %% Strategy: Trust Name
    CheckReadNamesCleanup -- "1 (Plaintext)" --> StratTrustName[STRATEGY: TRUST THE NAME<br>Parse '2025-11-28'<br>Compare with Cutoff-Date]:::process
    StratTrustName --> ResPrecise[Result:<br>PRECISE DELETION]:::delete
    
    %% Strategy: Fallback Timestamp
    CheckReadNamesCleanup -- "0 (Encrypted)" --> StratFallbackTimeFolder[STRATEGY: FALLBACK TO TIMESTAMP<br>Cannot read name 'A1b2...'<br>Uses 'stat -c %Y']:::warning
    StratFallbackTimeFolder --> RiskTouch[RISK: If folder was touched recently,<br>it will NOT be deleted!]:::warning

    %% Case B: Flat Mode
    CaseFolderStruct -- "0 (Flat Structure)" --> StratFallbackTimeFile[STRATEGY: FALLBACK TO TIMESTAMP<br>Check mtime of every single file]:::warning

    %% End connections
    DelFolderUnenc --> End([END])
    ResPrecise --> End
    RiskTouch --> End
    StratFallbackTimeFile --> End
    CheckEncExist -- No --> End

    %% Styling
    style Start fill:#e0e0e0,stroke:#333,stroke-width:2px
    style End fill:#e0e0e0,stroke:#333,stroke-width:2px
    style CleanupStart fill:#d1c4e9,stroke:#512da8,stroke-width:2px




ENCRYPTED_BACKUP_MAXDEPTH

How deep should you search for old backups? 1 = Main folder, 2= Main folder/subfolders etc.

ENCRYPTED_BACKUP_MAXDEPTH=10 # Don't go below 5

Note: For a deduplication structure, the path looks like this: 
Backup-Root/YYYY-MM-DD/YYYY-MM-DD_HH-MM-SS/Subfolders/file.txt
That’s depth 4 or more. With -maxdepth 2, BmuS will never find the file if it is in subfolders. The depth restriction is therefore automatically lifted by BmuS if a setting of less than 5 is made here, so that BmuS is able to recursively searches through all subfolders (and deduplication levels).

BACKUP_USE_DATE_FOLDERS

Organizes backups into folders with date names (e.g. /backup/2025-11-12/ or /encrypted/2025-11-12/). This applies to both encrypted and unencrypted backups when this option is enabled.

BACKUP_USE_DATE_FOLDERS=1

0 = disabled (flat structure, files directly in the backup root directory)
1 = Enabled (creates date-based folders for organization)

IMPORTANT: If DEDUP_ENABLE=1 folders are ALWAYS created with a date AND time (e.g. 2025-11-13_10-30-00/) – regardless of this setting. This setting is especially important if you use this folder structure with encryption BACKUP_ENCRYPTION=1 and DEDUP_ENABLE=0.

Advantages when activated:
◦ Easy identification of backup data
◦ Simplified recovery process
◦ Cleaner storage (deleting the entire folder instead of individual files)
◦ Works for both encrypted(/encrypted/YYYY-MM-DD/) as well as for unencrypted (/backup/YYYY-MM-DD/) files

READABLE_NAMES

When encryption is enabled, folder names and file names are also encrypted. If you want to prevent this and have both in plain text, you can activate this option. Of course, the file contents are still encrypted.

This setting only affects encrypted backups.

READABLE_NAMES=1

Example:
READABLE_NAMES=1 leads to /encrypted/folder_name
READABLE_NAMES=0 leads to /encrypted/fkajsdundasnIdnnjdasiinLOjda

GOCRYPTFS OPTIONS

Here you can make some fine adjustments to the GOCRYPTFS encryption. However, all settings can be ignored for now, as they will be taken into account in future versions.

GOCRYPTFS_REVERSE=0   # 0 = Standard

How it works:

GOCRYPTFS_REVERSE=0 (Normal / Forward Mode)   # Don't change.

• This is the setting that BmuS needs. A folder on the NAS (ciphertext) that holds the encrypted data. gocryptfs creates a virtual mount point (plaintext).
• The data flow: The script copies the unencrypted files into the mount point -> gocryptfs encrypts them immediately -> the encrypted data ends up physically on the NAS.

GOCRYPTFS_REVERSE=1  (Reverse Mode)   # For cloud backup. Currently not supported

• This will be used for cloud backups (e.g. Dropbox) in the future, but is not what the script can do at the moment.
• Initial situation: There is a folder full of unencrypted data on the hard drive. 1 creates a virtual mount point that displays an encrypted mirror of this data.
• The data flow: Nothing is changed in the original files. The mount point is “Read-Only” and shows the encrypted version. Backup tools copy from this mount point to the cloud.
• This is a feature that may be used in the future. At the moment it must be at 0.

GOCRYPTFS_LONGNAMEMAX

If you have long file names, you can specify the maximum number of characters here. Default: 255. This option is checked by BmuS for feasibility and is automatically disabled if the version of GOCRYPTFS is too old.

GOCRYPTFS_LONGNAMEMAX=255  # Standard.

GPG ENCRYPTION FOR SQL DUMPS (Optional)

GPG_RECIPIENT

If set, SQL dumps will also be encrypted with GPG. Leave blank to disable GPG encryption.

GPG_RECIPIENT=""

Requires:

apt-get install gnupg

You must generate a GPG recipient (email address of the GPG key) and key:

gpg –gen-key

The output of this operation looks something like this:

pub rsa3072 2025-11-13 [SC] [expires: 2027-11-13]
F8626AA18142691857268C7B054EA4D8EF62315B
uid John Doe <John.Doe@provider.com>
sub rsa3072 2025-11-13 [E] [expires: 2027-11-13]

If you use BmuS within a docker container, run:

docker exec -it bmus_backup gpg --homedir /config/gnupg --full-generate-key

GPG_HOMEDIR (Native version)

F8626AA18142691857268C7B054EA4D8EF62315B is entered into the variable.

GPG_RECIPIENT="F8626AA18142691857268C7B054EA4D8EF62315B"

Home directory of the key.

GPG_HOMEDIR="/home/user/encrypted/.gnupg"

GPG_HOMEDIR (Docker version)

Home directory of the key for docker version.

GPG_HOMEDIR="/config/gnupg"

BACKUP SIZE CALCULATION

If you want the dashboard to show how much data (including updates and databases) was written in this run, CALC_ALL should be set to 1.

CALC_ALL=1      # 1 = Total size including changed files
                # 0 = Only new files count

CALC_ALL=0 (Standard-Logic)

  • Calculation: Only completely new files are added to the total size.
  • Ignored: Files that already exist but have been updated (changed files) and SQL dumps are not included in the total size calculation.
  • Why: Shows how much additional space was used on the NAS by this run.

CALC_ALL=1 (Advanced calculation)

  • Calculation: All data sizes will be added.
  • New files: Files that weren’t there before.
  • Changed files: Files that have been updated (seen in the script at *f.st* in the rsync part).
  • SQL dumps: The size of the database backups created is also added up (explicitly queried in the script).
  • Why: Shows the actual transfer amount or “activity” of this backup run. This is usually the more interesting number for the dashboard because it shows how much data the script touched and wrote in total.

DEDUPLICATION

Deduplication is a data-reduction technique that identifies and removes duplicate copies of information. Instead of storing the same data multiple times, the system keeps only one unique instance and replaces duplicates with references, saving storage space and improving efficiency.

DEDUP_ENABLE

If this function is activated, BmuS tries to detect duplicate data and save it only once. This significantly reduces storage requirements for unchanged files by creating hard links to previous backup versions instead of copying identical files again.

DEDUP_ENABLE=1 #0 = disabled (classic rsync), 1 = activated (with hardlinks).

How it works:

  • First backup: Full copy (no deduplication)
  • Further backups: Only changed files are copied, unchanged ones are linked
  • Storage savings: 20-50% depending on data and rate of change. It can also be significantly lower.

Important note: gocryptfs (BACKUP_ENCRYPTION=1) does NOT work with deduplication (DEDUP_ENABLE=1) (see chapter “ENCRYPTION CONFIGURATION”). gocryptfs does not support hardlinks in GOCRYPTFS_REVERSE=0 mode. This combination results in ZERO storage savings but still creates the deduplication structure. You have to decide between BACKUP_ENCRYPTION=1 and DEDUP_ENABLE=1.

BmuS denies the run if BACKUP_ENCRYPTION=1 and DEDUP_ENABLE=1. GOCRYPTFS_REVERSE=1 is not possible at the moment, as this only makes sense if BmuS supports cloud backups – which it does not currently.

Storage structure with deduplication:

/backup/
├── 2025-11-13_10-30-00/ (Full backup)
├── 2025-11-13_14-00-00/ (hard links + changes)
└── 2025-11-13_18-00-00/ (hard links + changes)

Requirements:

  • File system must support hardlinks (ext4, btrfs, xfs – standard on Linux)
  • NAS share must support hardlinks (SMB/CIFS does, check documentation)

Performance influence:

  • Minimal CPU overhead
  • First rsync slightly slower (file comparison)
  • Additional backups significantly faster

If enabled, folders like 2025-11-13_18-00-00 will be created.

If a flat structure without encryption is desired in BACKUP_PATH (e.g. /mnt/backup), set DEDUP_ENABLE=0.

Cases:

  1. DEDUP_ENABLE=0, BACKUP_USE_DATE_FOLDERS=0:
    Flat structure, file-based storage
  2. DEDUP_ENABLE=0, BACKUP_USE_DATE_FOLDERS=1:
    Date folder (YYYY-MM-DD), folder-based retention
  3. DEDUP_ENABLE=1, BACKUP_USE_DATE_FOLDERS=0:
    Timestamp folder (YYYY-MM-DD_HH-MM-SS), folder-based retention
  4. DEDUP_ENABLE=1, BACKUP_USE_DATE_FOLDERS=1:
    Like #3 (DEDUP overwrites)
  5. DEDUP_ENABLE=0, BACKUP_ENCRYPTION=1, BACKUP_USE_DATE_FOLDERS=1:
    Like #3

Scenarios:

-------------------------------------------------------------------------
Flat (historical, no folders. BACKUP_USE_DATE_FOLDERS=0, DEDUP_ENABLE=0)
-------------------------------------------------------------------------
/mnt/workstation/
├── backup.sh.bak
├── 2025-11-10-database.sql
└── config_2025-11-10.tar.gz
-------------------------------------------------------------------------
Date based (BACKUP_USE_DATE_FOLDERS=1, DEDUP_ENABLE=1)
-------------------------------------------------------------------------
/mnt/workstation/
├── 2025-11-15/
│ ├── backup.sh.bak
│ └── database.sql
└── 2025-11-16/
└── config.tar.gz
-------------------------------------------------------------------------
Nested with deduplication (BACKUP_USE_DATE_FOLDERS=1, DEDUP_ENABLE=1)
-------------------------------------------------------------------------
/mnt/workstation/
├── 2025-11-15/
│ ├── 2025-11-15_10-30-00/
│ │ └── [Files]
│ └── 2025-11-15_18-00-00/
│ └── [Files]
└── 2025-11-16/
└── 2025-11-16_14-30-00/
└── [Files]

DEDUP_REFERENCE_DAYS

Determines how many backup generations are retained as hardlink references.

DEDUP_REFERENCE_DAYS=14

Higher value = more deduplication capabilities, but more storage required
Lower value = less storage required, but potentially less deduplication

DEDUP_STRATEGY

This is where you determine which strategy the backup should use.

DEDUP_STRATEGY="incremental"

DEDUP_MAX_DEPTH

Maximum hardlink depth for finding reference backups.

DEDUP_MAX_DEPTH=6

Higher value = searches more previous backups for deduplication
Lower value = faster, but may miss deduplication opportunities

DEDUP_DETAILED_LOG

In order to be able to see which files were de-deployed after a backup, you can activate the log. The data is logged in the dashboard (Pro version only) and in an external file.

DEDUP_DETAILED_LOG=1   0 = disabled (default), 1 = activated

NAME_DEDUP_LOGFILE

Here you can specify what name the log file should have.

NAME_DEDUP_LOGFILE="bmus_dedup.log"

The log file is automatically saved in BACKUP_PATH (e.g. /mnt/backup) so that it is available in the root of the NAS share.

DEDUP_LOG_DISPLAY_LINES

This setting determines how many log lines should be displayed in the dashboard. Regardless of what is stated here, everything is basically logged in the log file.

DEDUP_LOG_DISPLAY_LINES=600


RESOURCE MONITORING

BmuS is able to log system utilization and display it graphically. RAM utilization, CPU load, and I/O write are logged and displayed. This function is useful if you want to estimate whether the computer is a bottleneck and perhaps reaching its limits.

RESOURCE_MONITOR_ENABLE

Turns the function on (1) or off (0). When turned off, no graph is built into the dashboard and logging is disabled. When enabled, the graph is displayed. This function is part of the pro dashboards.

RESOURCE_MONITOR_ENABLE="1" # 1 = enabled, 0 = disabled


RESOURCE_MONITOR_INTERVAL

Interval in seconds for capturing stats (default: 10s).

RESOURCE_MONITOR_INTERVAL="10"

RESOURCE_LOGFILE

Path to the temporary log file for resource stats (will be deleted after run).

RESOURCE_LOGFILE="/tmp/bmus_resource_stats.log"

RESOURCE_MONITOR_SHOW_MAX_RAM

Show a horizontal line indicating Total RAM in the resource chart? Useful for context, but can make small usage look tiny on high-RAM systems.

RESOURCE_MONITOR_SHOW_MAX_RAM="1"

1 = show line, 0 = hide line (but still show Total in tooltip).


BATCH PROCESSING

Let you take control of how the sources are processed in batches. The goal is to keep performance and system stability in balance. After each batch, BmuS pauses to allow the RAM to recover before continuing.

These settings are particularly important for computers with little RAM and are intended to avoid system freezes.

BATCH_SIZE

Number of sources per batch (then pause for RAM recovery).

BATCH_SIZE=2

BATCH_PAUSE

Pause between batches (seconds).

BATCH_PAUSE=3

MEMORY_TRESHOLD

Minimum free RAM before the next batch starts (MB).

MEMORY_THRESHOLD=200

RSYNC PERFORMANCE OPTIMIZATION

This section adjusts the behavior of rsync to reduce CPU and I/O load.

Adjusting these settings ensures smooth performance on systems with limited resources (e.g. Raspberry Pi).

RSYNC_NICE

Nice-Level (CPU priority): 0–19, higher = lower priority

RSYNC_NICE=0

Recommended: 0 (unless your system needs CPU for other tasks during SMB backup)

RSYNC_IONICE

Ionic class (I/O priority): 0=Disabled (Fastest), 1=Realtime, 2=Best-effort

RSYNC_IONICE=0

CRITICAL: Keep at “0” for NAS backups. Enabling this on network drives causes massive slowdowns.

RSYNC_COMPRESSION

Enable compression (0=off, 1=on) – Disabling it saves CPU time on the computer.

RSYNC_COMPRESSION=0

Recommended: 0 for LAN (Gigabit is faster than Pi CPU compression). Only set to 1 for very slow WiFi or WAN connections.

NOTE: In NFS mode, NICE and IONICE are automatically ignored/disabled by BmuS to prevent kernel scheduling timeouts (Performance Fix). They are only applied in SMB/CIFS modes.

RSYNC_BANDWIDTH_LIMIT

Useful for slow networks or to avoid affecting other services.

RSYNC_BANDWIDTH_LIMIT=0

Bandwidth limit for rsync in KB/s (kilobytes per second)
0 = unlimited (Standard)

Examples:
1000 = 1 MB/s
5000 = 5 MB/s
10000 = 10 MB/s

BACKUP-VERIFICATION

This variable determines whether the script performs a checksum-based check on the files immediately after the backup is complete.

BACKUP_VERIFICATION=0 

If set to 0 (Disabled): The script skips the verification step. This is the default and recommended setting if you experience connection issues or “freezes” during backup as this step is very resource intensive.

If set to 1 (Enabled): The script runs rsync in checksum mode (-c) with --dry-run flag. This causes rsync to calculate and compare a cryptographic checksum for each file on both the source (Raspberry Pi/Linux) and destination (NAS).

Enabling verification (1) significantly increases system load and network I/O. The entire backup set must be read twice (once for the backup itself and once for verification) over the network. On a Raspberry Pi or when the network connection is unstable (which can cause BmuS to freeze), setting it to 1 can cause timeouts or system instability – especially on systems with little RAM or slow storage memory. Errors in the summary report are possible because files can change during the backup (e.g. databases, temporary files…).

VERIFICATION_TIMEOUT

If BmuS or the host (e.g. Raspberry Pi) freezes or stops responding, BmuS tries to detect this condition and briefly resets the network interface (off/on). The timeout defines the duration in seconds after which this action is triggered.

VERIFICATION_TIMEOUT=120

BACKUP RETENTION

These functions can be used to control after how many days old backups are deleted and how deep in the folder structure the search should be. With flat structures, you can also specify which file types should be deleted or limit the deletion to these.

BACKUP_AGE_DAYS

After how many days should be deleted?
Note: This setting will be ignored, if you use Smart Retention (GFS).

BACKUP_AGE_DAYS=7

SMART RETENTION STRATEGY (GFS – Grandfather-Father-Son)

GFS stands for Grandfather-Father-Son. It is a standard backup rotation scheme that allows you to save storage space while maintaining a long history of your data. Instead of keeping every backup or deleting everything after a few days, BmuS now intelligently selects which backups to keep:

  • Son (Daily): Keeps every backup for the last few days (e.g., 7 days) for immediate recovery.
  • Father (Weekly): Keeps one backup per week (Sundays) for a few weeks (e.g., 4 weeks).
  • Grandfather (Monthly): Keeps one backup per month (1st of the month) for a long period (e.g., 12 months).

BmuS marks folders to keep with marker files such as _RETENTION_WEEKLY_KEEP.txt and _RETENTION_MONTHLY_KEEP.txt

1 = Enabled / 0 = Disabled (Standard BACKUP_AGE_DAYS applies)

RETENTION_ENABLE="1"

DAILY: How many days to keep ALL backups? (Standard rotation).
Example: “7” means you can restore any day from the last week.

RETENTION_KEEP_DAILY="7"

WEEKLY: How many weeks to keep the Sunday backups?
Example: “4” means you have a history of the last month, week by week.

RETENTION_KEEP_WEEKLY="4"

MONTHLY: How many months to keep the 1st-of-month backups?
Example: “12” allows you to go back one year, month by month.

RETENTION_KEEP_MONTHLY="12"

Important: 
How does this affect BACKUP_AGE_DAYS or ENCRYPTED_BACKUP_AGE_DAYS?

When you set RETENTION_ENABLE="1", the Smart Retention logic takes full control over the deletion process.

  • Override Behavior: The legacy setting BACKUP_AGE_DAYS="14" (which meant “hard delete everything older than 14 days”) is effectively ignored and replaced by the GFS rules.
  • Safety: You do not need to set BACKUP_AGE_DAYS to “0” or change it. BmuS automatically detects that GFS is active and switches logic.
  • Example:
    • If you have BACKUP_AGE_DAYS="14" but RETENTION_KEEP_MONTHLY="12".
    • Old Behavior: A backup from last month would be deleted because it is older than 14 days.
    • New GFS Behavior: BmuS sees that this backup is a “Monthly” backup. It ignores the 14-day limit and keeps the file because your GFS rule says “keep monthlies for 12 months.”

Summary: As long as RETENTION_ENABLE="1", you don’t have to worry about your old BACKUP_AGE_DAYS settings cutting off your long-term history. The Smart Strategy protects your weekly and monthly archives automatically.

Flowchart of how GFS is working:

GFS Flow
flowchart TD
    %% Style Definitions - JETZT MIT SCHWARZER SCHRIFT
    classDef process fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:black;
    classDef decision fill:#fff9c4,stroke:#fbc02d,stroke-width:2px,color:black;
    classDef terminator fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:black;
    classDef delete fill:#ffebee,stroke:#c62828,stroke-width:2px,color:black;
    classDef storage fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,stroke-dasharray: 5 5,color:black;

    Start([Backup Complete]) --> TaggingPhase
    style Start color:black,fill:#e0e0e0,stroke:#333,stroke-width:2px

    subgraph TaggingPhase [Phase 1: Tagging Logic]
        direction TB
        style TaggingPhase fill:#fafafa,stroke:#666,color:black
        
        T1{Is today the<br>1st of Month?}:::decision
        T1 -- Yes --> T2[Create Marker File:<br><b>.monthly</b>]:::process
        T1 -- No --> T3{Is today<br>Sunday?}:::decision
        
        T2 --> T3
        T3 -- Yes --> T4[Create Marker File:<br><b>.weekly</b>]:::process
        T3 -- No --> T5[Standard:<br>Daily Backup]:::process
    end

    TaggingPhase --> LoopStart
    
    subgraph PruningPhase [Phase 2: Retention & Pruning]
        direction TB
        style PruningPhase fill:#fafafa,stroke:#666,color:black

        LoopStart(Iterate through<br>all old backup folders):::process --> CheckMonthly
        
        CheckMonthly{Has folder<br>.monthly marker?}:::decision
        CheckMonthly -- Yes --> AgeMonthly{Older than<br>RETENTION_KEEP_MONTHLY?}:::decision
        
        CheckMonthly -- No --> CheckWeekly{Has folder<br>.weekly marker?}:::decision
        
        AgeMonthly -- Yes --> DELETE:::delete
        AgeMonthly -- No --> KEEP:::terminator
        
        CheckWeekly -- Yes --> AgeWeekly{Older than<br>RETENTION_KEEP_WEEKLY?}:::decision
        CheckWeekly -- No --> AgeDaily{Older than<br>RETENTION_KEEP_DAILY?}:::decision
        
        AgeWeekly -- Yes --> DELETE:::delete
        AgeWeekly -- No --> KEEP:::terminator
        
        AgeDaily -- Yes --> DELETE:::delete
        AgeDaily -- No --> KEEP:::terminator
        
        DELETE[DELETE BACKUP]:::delete
        KEEP[KEEP BACKUP]:::terminator
    end

    %% Logic Connections
    T4 --> LoopStart
    T5 --> LoopStart

BACKUP_MAXDEPTH

Search depth for old backups (1 = main directory only, 2 = one level deeper, etc.)

BACKUP_MAXDEPTH=5

BACKUP_FILETYPES

File types that should be taken into account when deleting old backups can be specified explicitly.

BACKUP_FILETYPES=("*.sql" "*.db" "*.baksh")  # delete only the specified files

or

BACKUP_FILETYPES=("*") # delete all files

The .backsh file type is automatically created for backups of all BmuS-owned files. The idea is that in flat structure mode (BACKUP_USE_DATE_FOLDERS=0 & DEDUP_ENABLE=0) BmuS (and its associated files) is prevented from deleting itself.

Hint: It makes sense to put the program files in a folder and put a .backupignore file in this folder.

In order for BmuS to secure itself, BACKUP_SCRIPT_ENABLE=1 and BACKUP_SCRIPT_FILES must be set.

Note: This routine is ignored if BACKUP_USE_DATE_FOLDERS=1 & DEDUP_ENABLE=1. It only works in flat structure mode. Only those specified here are the file types used for deletetion. Folders will not be deleted.

Docker Container Settings

This section is ONLY evaluated by the Docker container (entrypoint.sh). BmuS ignores these lines, if it’s a native installation.

Schedule for automatic backups (cron format): Minute Hour Day Month Weekday.

Examples:

“0 3 * * *” = Daily at 3:00 a.m.
“30 2 * * 0” = Every Sunday at 2:30 a.m.
“30 15 * * 1” = Every Monday at 4 p.m.
“30 2,14 * * 0” = Every Sunday at 2:30 a.m. and 2:30 p.m.
“” = Leave blank for manual mode (no automation)

CRON_SCHEDULE="0 3 * * *"

IMPORTANT: Make sure, that there are no blanks behind commas. This would throw an error:

CRON_SCHEDULE="0 3, 16 * * *"

CLOUD BACKUP (via rclone)

Since version 26.3, BmuS can also make backups to the cloud. Since BmuS uses rclone, all cloud providers (or protocols) supported by rclone are accessible. As of January 2026, these are:

  1. 1Fichier
  2. Akamai NetStorage
  3. Alias for an existing remote
  4. Amazon Drive
  5. Amazon S3 Compliant Storage Providers including AWS, Alibaba, Ceph, China Mobile, Cloudflare, ArvanCloud, Digital Ocean, Dreamhost, Huawei OBS, IBM COS, IDrive e2, IONOS Cloud, Lyve Cloud, Minio, Netease, RackCorp, Scaleway, SeaweedFS, StackPath, Storj, Tencent COS, Qiniu and Wasabi
  6. Backblaze B2
  7. Better checksums for other remotes
  8. Box
  9. Cache a remote
  10. Citrix Sharefile
  11. Combine several remotes into one
  12. Compress a remote
  13. Dropbox
  14. Encrypt/Decrypt a remote
  15. Enterprise File Fabric
  16. FTP
  17. Google Cloud Storage (this is not Google Drive)
  18. Google Drive
  19. Google Photos
  20. Hadoop distributed file system
  21. HiDrive
  22. HTTP
  23. In memory object storage system
  24. Internet Archive
  25. Jottacloud
  26. Koofr, Digi Storage and other Koofr-compatible storage providers
  27. Local Disk
  28. Mail.ru Cloud
  29. Microsoft Azure Blob Storage
  30. Microsoft OneDrive
  31. OpenDrive
  32. OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
  33. Pcloud
  34. premiumize.me
  35. Put.io
  36. seafile
  37. Sia Decentralized Cloud
  38. SMB / CIFS
  39. SSH / SFTP
  40. Sugarsync
  41. Transparently chunk/split large files
  42. Union merges the contents of several upstream fs
  43. Uptobox
  44. WebDAV
  45. Yandex Disk
  46. Zoho

For a native installation of BmuS, rclone must be installed. If you use the installer install_dependencies.sh (included in the zip file bmus.zip), this happens automatically. The Docker version already includes rclone. In this case, the installer does not need to be used.

The most important parameters for cloud backup are defined in bmus.conf.

IMPORTANT: Please read this chapter to learn how to configure your cloud provider.

CLOUD_BACKUP

This switch enables or disables the cloud backup functionality.

# 1 = Enabled / 0 = Disabled
CLOUD_BACKUP="0"

CLOUD_LOG_FILE

Here, the path to rclone-log is specified so that errors can be detected. The path between native installation and Docker installation differs. The path of the Docker version should not be changed.

Native Install

CLOUD_LOG_FILE="$HOME_PI/rclone_last_run.log"

Docker Install

CLOUD_LOG_FILE="/config/rclone_last_run.log"

RCLONE_CFG_PATH

This is the file where your rclone configuration will be stored. If set, BMUS will use this specific configuration file.

Native version

Leave empty “” to use standard rclone behavior (default locations, native installation).

RCLONE_CFG_PATH=""

Docker version

For DOCKER version path would be /config/rclone.conf

RCLONE_CFG_PATH="/config/rclone.conf"

Note: If this file does not exist, BMUS tries to copy the internal from the docker container to /config on the host. In detail: The script now checks three scenarios at startup.

Rclone Check
flowchart TD
    %% Styling Definitionen (Schwarzschrift erzwungen)
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px,color:black;
    classDef process fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:black;
    classDef decision fill:#fff9c4,stroke:#fbc02d,stroke-width:2px,color:black;
    classDef terminator fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:black;
    classDef warning fill:#ffccbc,stroke:#bf360c,stroke-width:2px,color:black;

    Start([START SCRIPT]) --> CheckCloud{"CLOUD_BACKUP = '1' ?"}:::decision

    %% DISABLED PATH
    CheckCloud -- "No / Not Set" --> Ignore[IGNORE RCLONE SETTINGS<br>• No file checks<br>• No import attempts<br>• No warnings]:::process
    Ignore --> End([END])

    %% ENABLED PATH
    CheckCloud -- "Yes" --> CheckCustom{"Custom Config<br>Exists & Valid?"}:::decision

    %% Scenario: FOUND
    CheckCustom -- Yes --> UseCustom[SCENARIO: FOUND<br>Use Custom Config<br>Immediately]:::terminator
    UseCustom --> End

    %% Checking for Import vs Missing
    CheckCustom -- "No (Missing/Empty)" --> CheckInternal{"Internal Config<br>Exists?"}:::decision

    %% Scenario: IMPORT
    CheckInternal -- Yes --> ImportConfig[SCENARIO: IMPORT<br>Copy Internal Config<br>to Persistent Location]:::process
    ImportConfig --> End

    %% Scenario: MISSING
    CheckInternal -- No --> MissingConfig[SCENARIO: MISSING<br>Warn User:<br>No Configuration Found]:::warning
    MissingConfig --> End

    %% Styling
    style Start fill:#e0e0e0,stroke:#333,stroke-width:2px
    style End fill:#e0e0e0,stroke:#333,stroke-width:2px

The logic only becomes active if you actually want to use cloud backup. This keeps the script clean and prevents errors for users who do not use the cloud (and therefore do not have a config).

CLOUD_REMOTE

During the installation or configuration of rclone, you gave the connection a name. This must be entered here exactly as it was given. Example: If you named your connection “dropbox“, enter “dropbox” here.

CLOUD_REMOTE=""

CLOUD_TARGET_PATH

Destination path inside the cloud storage. This folder will be created automatically. Change this, if you like.

CLOUD_TARGET_PATH="/Backups"

CLOUD_DRY_RUN_CHECK

This variable only takes effect when Bmus is called with the dry run parameter (sudo bash.sh -n). Otherwise, it is ignored. The idea is that the cloud connection and cloud backup are also simulated.

# 1 = Yes (shows what would happen)
# 0 = No
CLOUD_DRY_RUN_CHECK="1"

Next