I want to backup my HA config every night and upload it to S3. I’m surprised this isn’t a supported feature out of the box, and bewildered by how difficult it was to setup.
An automation starts the backup, waits a minute, then calls a shell command which runs a bash script inside the SSH addon to copy the latest backup to /share
. That file copy fires a folder_watcher
event, which triggers an automation to upload this file to S3 using minio
addon.
The SSH workaround is because automations run inside the homeassistant
Docker container, which does not have access to /backup
. The SSH addon has access to both places, so it can copy the tar file to /share
.
There is no way to know the backup filename directly, that’s why I have to use the folder_watcher
event.
To setup SSH access you need to generate a key pair inside the homeassistant
container and store it somewhere outside the home directory so that it persists across software updates. Then add the public key to the SSH addon.
ssh-keygen -t ecdsa -f /config/shell_scripts/id_ecdsa
This is my shell script at /config/shell_scripts/move_backup_to_share.sh
#!/bin/bash
mkdir -p /share/backups
cp /backup/$(ls -t /backup/ | head -1) /share/backups/
In configuration.yaml:
shell_command:
copy_backup_to_share: >
ssh -o UserKnownHostsFile=/config/shell_scripts/known_hosts
[email protected]
-i /config/shell_scripts/id_ecdsa
'/config/shell_scripts/copy_backup_to_share.sh'
folder_watcher:
- folder: '/share/backups'
patterns:
- '*.tar'
And automations.yaml:
- alias: Utility - nightly backup
trigger:
- platform: time
at: 03:00:00
action:
- service: hassio.backup_partial
data:
homeassistant: true
- delay:
minutes: 1
- service: shell_command.copy_backup_to_share
mode: single
- alias: Utility - upload backups to S3
description: 'run when tar is finished copying to /share/backups'
trigger:
- platform: event
event_type: folder_watcher
event_data:
event_type: closed
action:
- service: notify.mobile_app_pro_llama
data:
title: System backup at {{ now().strftime('%H:%M:%S') }}
message: '{{ trigger.event.data.path }}'
- service: minio.put
data:
bucket: my-bucket
file_path: '{{ trigger.event.data.path }}'
key: backups/{{ trigger.event.data.file }}
mode: single
You can vote here to make this easier: