ZimaOS Automated Backup

ZimaOS Automated Backup Solution

I have seen quite a few posts regarding data backup on ZimaOS lately. It looks like the devs are working on a more robust GUI backup solution, but in the meantime I figured I would share my backup method in case it can help others.

I am a Network Admin that specializes in Linux administration, so I tend to live in the CLI. In general, I find it quicker and easier to make my servers do what I want them to do by modifying configuration files instead of dealing with a Web UI. Because of that, I have been using the rclone utility that ships with ZimaOS combined with Bash scripts and Systemd for automation. I have connected my Backblaze B2 account with rclone for remote backup to maintain the “3-2-1 backup strategy.”

Backup Schedule

Contents Directory Sechedule
Docker app data /media/nvme0n1p1/AppData Weekly (Sundays @ 00:00)
Network client backups /media/Quick-Storage/Backup Weekdays (Mon-Fri @ 00:00)
Immich gallery /media/Quick-Storage/Gallery/immich Daily (Mon-Sun @ 01:00)

Note: I am working on finding the most important ZimaOS configuration files located in the /etc & /media/ZimaOS-HD directories so I can set up a script that backs up those directories too.

Restore a Backup

With this setup you can easily restore backed up data by reversing the source and destination in the scripts. I actually needed to do this recently. I was removing the Immich service that I had installed via the store, and replacing it with a manual install via the CLI with the compose files provided by the Immich project. My main reason for doing this is the Immich updates. With the version from the store I had to manually change the image tag for every new version. Now that I have it installed with the official compose files, the service is much easier to update.

Anyway, when I selected “Uninstall” on the store version it deleted my entire gallery AND the AppData directory! Thankfully, since I back up all of that data it was easy to restore it to my server and get back up and running within a couple hours. Instead of modifying my existing backup scripts, I just wrote a couple simple restore scripts that target the specific Immich directories and ran them with the root user.

Just a quick note to @777-Spider:

It would be nice if the ZimaOS Web-UI had a toggle when uninstalling a service that allows you to remove the service while leaving its data intact, or at the very least a warning that lets the user know their data is going to be erased. It does not affect me anymore since I have migrated all of my Docker services to manual installs with custom compose.yaml files that I manage in the CLI and sometimes Dockge. However, for an average user who doesn’t know it may cause data loss. If I had not been practicing good data hygiene I would have been screwed too.

Also, after the ZimaOS v1.7.0 update I noticed all my services disappear from the dashboard. I don’t know if this is a bug or intentional, but PLEASE keep it this way! I much prefer creating links for my services on the dashboard because it keeps my compose files clean. Before the change ZimaOS added a bunch of metadata to my compose files under x-casaos:. This change allows advanced users like myself manage their Docker services the same way we do on all our other servers while keeping the easy method available to less advanced users.

Example Restore Scripts:

#!/bin/bash
# Define your variables
RESTORE_SOURCE="B2-Crypt:ZimaOS-NAS-Backup/Quick-Storage/Gallery/immich"
RESTORE_DEST="/media/Quick-Storage/Gallery/immich"

# Execute the restore
rclone copy $RESTORE_SOURCE $RESTORE_DEST \
  --config /DATA/.config/rclone/rclone.conf \
  --fast-list \
  --transfers 16 \
  --log-level INFO
#!/bin/bash
# Define your variables
RESTORE_SOURCE="B2:ZimaOS-NAS-Backup/nvme0n1p1/AppData/immich"
RESTORE_DEST="/media/nvme0n1p1/AppData/immich"

# Execute the restore
rclone copy $RESTORE_SOURCE $RESTORE_DEST \
  --config /DATA/.config/rclone/rclone.conf \
  --fast-list \
  --transfers 16 \
  --log-level INFO

GitHub Repo

I have created a GitHub repo that contains my backup scripts and the Systemd unit files for automation. The README.md contains step-by-step instructions for how to set it up. My scripts are obviously geared toward my setup, including parsing the log file and sending a push notification to my Gotify server. However, they can be used as a template for anyone else by commenting out the Gotify code and changing the variables for the source and destination.


GitHub — README.md:

ZimaOS Backup Scripts

The ZimaOS NAS is the main backup server for clients and other servers on the local network. To maintain the 3-2-1 Backup Strategy the important data stored on the NAS is backed up to Backblaze B2 cloud storage. To automate the backup process we utilize Bash scripts that use the rclone command and Systemd unit files to trigger the scripts on a set schedule. Reference the Backblaze docs for help with rclone integration.

Clone the Repo

git clone https://github.com/benhaube/zimaos-backup-scripts.git
cd zimaos-backup-scripts/

Activate Scripts

  1. Put the backup scripts b2-appdata-bkp.sh, b2-backup-bkp.sh, and b2-immich-bkp.sh into the /opt/scripts directory.

    sudo mkdir -p /opt/scripts
    sudo cp b2-*-bkp.sh /opt/scripts
    
  2. Make the scripts executable.

    sudo chmod +x /opt/scripts/b2-*-bkp.sh
    

Automate with Systemd

  1. Move the Systemd timer unit files into the /etc/systemd/system directory.

    sudo cp systemd/b2-*-bkp.timer /etc/systemd/system
    
  2. Move the Systemd service unit files into the /etc/systemd/system directory.

    sudo cp systemd/b2-*-bkp.service /etc/systemd/system
    
  3. Tell Systemd to parse the changes.

    sudo systemctl daemon-reload
    
  4. Test the new services, and check the logs to make sure they completed successfully.

    sudo systemctl start b2-<script>-bkp.service
    sudo journalctl -u b2-<script>-bkp.service -e
    
  5. After confirming the services run successfully, enable the timers so they survive a reboot and begin their schedule.

    sudo systemctl enable --now b2-*-bkp.timer
    
  6. Verify the timers are active with the following command.

    systemctl list-timers --all
    

    Example Output

    NEXT                          LEFT LAST                              PASSED UNIT                          ACTIVATES                      
    Thu 2026-09-10 00:04:10 EDT     8h -                                      - b2-backup-bkp.timer           b2-backup-bkp.service
    Thu 2026-09-10 01:03:06 EDT     9h -                                      - b2-immich-bkp.timer           b2-immich-bkp.service
    Thu 2026-09-10 11:19:42 EDT    19h Wed 2026-09-09 11:19:42 EDT 4h 33min ago systemd-tmpfiles-clean.timer  systemd-tmpfiles-clean.service
    Sun 2026-09-13 00:04:23 EDT 3 days -                                      - b2-appdata-bkp.timer          b2-appdata-bkp.service
    Mon 2026-09-14 00:52:53 EDT 4 days -                                      - fstrim.timer                  fstrim.service
    -                                - Mon 2026-09-07 11:04:41 EDT   2 days ago cron-watchdog.timer           cron-watchdog.service
    -                                - Mon 2026-09-07 11:04:47 EDT   2 days ago zfw-ui-watchdog.timer         zfw-ui-watchdog.service
    -                                - Mon 2026-09-07 11:04:41 EDT   2 days ago zima-vm-extras-watchdog.timer zima-vm-extras-watchdog.service
    
    8 timers listed.
    
3 Likes