Automatically remove old HA config backups

Here is my solution:

# delete old backups
# flow: open backup folder & list files sorted by age -> delete first 3 entries (jungest files) from output -> run remove on each left 
sensors
  - platform: command_line
    name: delete old backups
    command: 'cd /config/backups/ && ls -A1t | sed -e "1,4d" | xargs rm'

I use this in my HA docker container. So your path might be different. By default command line sensors are called every minute. Setting scan_interval to some more useful value might be advised.

Hi and thanks for sharing the solution. I’ve used it to create a command_line switch so it can be used by the backup-Automation:

- platform: command_line
  switches:
    purge_backups:
      friendly_name: Purge HA-config Backups
      unique_id: switch.purge_backups
      icon_template: mdi:trash-can
      # go to backup direcotory, list files by date, filter result list to hide the first 7 results (show from nr.8) and remove remaining
      command_on: cd /config/backups/ && ls -A1t | tail -n +8 | xargs rm -v

The switch will stay turned on if you use it in lovelace, but that isn’t my scope. I just use it in the automation to trigger it and then turn it of again:

alias: Backup, daily HA-config backup
description: ""
trigger:
  - platform: time
    at: "00:10:00"
condition: []
action:
  - service: backup.create
    data: {}
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.purge_backups
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.purge_backups
mode: single

maybe there is a solution that will also turn off the switch automatically after the command has been executed, but i’m happy with this solution :slight_smile:

2 Likes

Adds a service which runs your command. No unnecessary toggling. Or

Basically the same thing except stdin is set from message before the command is run, allowing you to pass some value as input from your automation/script.

I just tried to set up a backup purge command using the Shell Command integration.
Correct me if I’m wrong, but the /backup dir is not mounted in the homeassistant container, so we can’t use that integration for this specific case?
From the docs:

If you are using Home Assistant Operating System, the commands are executed in the homeassistant container context. So if you test or debug your script, it might make sense to do this in the context of this container to get the same runtime environment.

1 Like

I tried to set it up and I managed to remove the files. The issue I have now is that HomeAssistant still keeps the references to the files in Settings->System->Backups list. The files don’t exist anymore so when trying to download a file it returns 0B file (so it’s expected) but I’d like also to clean up those references. I don’t see any service (only backup.create). Anyone solved it?

1 Like

I’ve just started using this integration hass auto backup and it adds a lot more capability around backups. I’ll report back once I have more experience with it but it seems to work well so far.

Just adding an update - this looks good but Home Assistant configuration.yaml now separates command_line stuff…

command_line:
  - switch:
      name: Purge Backups
      # go to backup direcotory, list files by date, filter result list to hide the first 7 results (show from nr.8) and remove remaining
      command_on: cd /config/backups/ && ls -A1t | tail -n +8 | xargs rm -v

Edit: removed trailing backslash.

1 Like

Once using this Auto Backup do we disable the built in backup or do they work together?

Shameless plug for my blog post about auto-backups ibizaman's Blog - Backup Home-Assistant with and without Nix

I tried this, but my main homeassistant core container does not have a /config/backups/ folder. Did this change?

Hi,

for those who prefer to do it on Bash I wrote myself a little script which does the handling and is started daily by cron.

  • it creates a lockfile in case the job run more often than only a single process
  • removes all backups older than 7 days (properly for HA, not only removing the files)
  • creates a new backup
    That’s it. Match the files and directories according to your need.
#!/bin/bash
#set -x

LOCKFILE=/var/lock/backup.run

# Einen lock mit FileDescriptor 958 erstellen
exec 958<>$LOCKFILE ||exit 1
flock -n 958 || exit 1 # Non-Blocking. Wenn das nicht geht, steigt er mit Fehlercode aus

# Löscht die Lock-Datei bei Erhalt von "EXIT" Signal
trap 'rm -f $LOCKFILE' EXIT

# Und los geht's
NAME="CRON_Vollbackup_am_`date +%d.%m.%y`"

pushd /usr/share/hassio/backup
find . -ctime "+7" > /tmp/filelist.$$
if [ ! -z /tmp/filelist.$$ ]; then
	for i in $(cat /tmp/filelist.$$) ; do
		FILE = $(basename -s .tar $i)
		ha backups rm $FILE
	done
fi
rm -f /tmp/filelist.$$
popd
ha backup new --name \"$NAME\"

rm -f $LOCKFILE
exit
3 Likes

Can this be used on Home Assistant OS or are you using a self-managed linux?

I can’t get this to work with Home Assistant OS either. The command gets executed in the ‘homeassistant’ docker’s environment. There is no backups there. I have not yet figured it out. :confused:

1 Like

It is on the supervised mode- Debian12 as OS running.

If you have the advanced ssh and web terminal addon installed, you could create a shell_command to run the code inside the ssh addon container, which does have the backup volume mapped:

shell_command:
  backup_purge: "ssh -i {{path to ssh keys}} -p {{port}} {{username}}@{{HAOSip}} ‘{{executable file path}}'"
2 Likes

This actually did help me to find the solution. Thank you very much!

For everyone else, here it is:

shell_command:
  delete_old_backups: "ssh -i /config/private.pem -p 22222 [email protected] 'find /mnt/data/supervisor/backup -type f -mtime +20 -name '*.tar' | xargs rm'"
1 Like

* ha backups remove

1 Like

Steps to Automatically Delete Old Backups in Home Assistant

Follow these steps to set up a system that automatically deletes backups older than 7 days.

Step 1: Generate SSH Keys

Generate a new SSH key pair. Open the terminal and execute:

ssh-keygen -t rsa

When prompted for the file location, change it to:

/config/shell_command_id_rsa

Step 2: Set Up SSH Key Authentication

Append the public key to the authorized keys and test the SSH connection:

cat /config/shell_command_id_rsa.pub >> /root/.ssh/authorized_keys
cd /config
ssh -i shell_command_id_rsa root@localhost

This should open a new SSH session. Type exit to close the session.

Step 3: Create a Directory for Shell Scripts

Create a directory to store your shell scripts:

mkdir /config/shell

Step 4: Create the Backup Removal Script

Create a shell script that deletes backups older than 7 days:

nano /config/shell/remove-old-backups.sh

Add the following content to the script:

#!/bin/bash

# Remove old backup files
# -mtime +7 corresponds to files older than 7 days
find /backup -name '*.tar' -mtime +7 -exec rm -f {} \;

Make the script executable:

chmod +x /config/shell/remove-old-backups.sh

Step 5: Edit the Home Assistant Configuration

Edit the configuration.yaml file to add a shell command that executes your script via SSH:

shell_command:
  delete_old_backups: 'ssh -i /config/shell_command_id_rsa -o StrictHostKeyChecking=no root@localhost bash /config/shell/remove-old-backups.sh'

Step 6: Create an Automation to Run the Script

Add an automation to run the shell command daily. Edit your automations.yaml or use the UI to create a new automation:

automation:
  - alias: Delete Old Backups
    description: Deletes backups older than 7 days every day at 3:30 AM
    trigger:
      - platform: time
        at: "03:30:00"
    action:
      - service: shell_command.delete_old_backups

Step 7: Restart Home Assistant

Restart Home Assistant to apply the changes:

ha core restart

Summary

You’ve now set up an automated system to delete backups older than 7 days using a custom shell script and Home Assistant automations.


Feel free to adapt the SSH setup to suit other types of commands if needed.

2 Likes

Just a quick update on this working on HA Core 2024.8.3 (Home Assistant OS)
Backups folder moved from /config/bakcups/ to backup/

command_line:
  - switch:
      name: Purge Backups
      # go to backup direcotory, list files by date, filter result list to hide the first 7 results (show from nr.8) and remove remaining
      command_on: cd backup/ && ls -A1t | tail -n +8 | xargs rm -v
1 Like

Just wanted to pop in here and show yet another commandline that works. I was getting errors due to using Syncthing on that folder. This will check only for .tar files (I’m on Docker - change the folder name for Core): command_on: "cd /config/backups/ && ls *.tar -A1t | tail -n +8 | xargs rm -f"