Automatically Backup Home Assistant to Gitea/ Github

Automatically Backup Home Assistant to Gitea/ Github

I recently decided to pave and nuke my old Home Assistant of 2 years and start from scratch again. There is a lot of unnecessary data collected and broken things in general. So why not start again.

I wanted to figure out first how to integrate some backup structure that allowed me to see a changelog over time. Git is built for file system version control. So I started to look into a way to perform a push of files changed on a schedule automated by Home Assistant.

In this example, I use a locally hosted Gitea server which will house my Home Assistant data. However, you could quite quickly adapt this to Github or other online/ self-hosted services.

From here on out, I will be reference specific Gitea configuration, and some of this may not be relevant.

The Setup

Gitea:

As mentioned above, I run a self-hosted Gitea in my environment. It runs via a Docker-Compose configuration. You may need to refresh your memory on how the SSH aspect of Gitea is configured. As I usually push and pull via HTTPS, I had not even touched the SSH process.

Performing a quick test to see if it worked, I quickly released that it did not. To make this process work, you need to be able to utilise SSH push and pull, and you need to use SSH keys to achieve this so that you are not stuck at a username and password prompt. So this needed to get fixed.

Checking out the docker-compose file of Gitea, I quickly realised that I had set up a different SSH port to be used. This was because port 22 was already being used by the docker host. So I needed to incorporate the different port being used into my plan.

Highlight is the alternative port number for port 22.

We next need to create a new (private) repo for our Home Assistant files to go in too. Create a new repo and copy the ssh path somewhere we can get again later.

One thing to note here, notice how Gitea is referenced here. If Home Assistant was to use this as-is, it has no way of translating gitea. This can be quickly fixed by change gitea for the IP address of the Gitea server or just simply add the translation of gitea to the IP address into the HOSTS file. The hosts file can be found in /etc/hosts.

Home Assistant:

So we have already fixed up the HOSTS file inside of Home Assistant; however, we still need to do a couple of things.

First, we need to install the add-in SSH & Web Terminal.

SSH & Web Terminal can be found under Supervisor/Add-On Store

If you dont see this add-in, it is because you have not turned on Advanced Mode. To turn on Advanced Mode click on the user profile at the bottom of the navigation menu in Home Assistant. You should see Advanced Mode in the list of options.

Once installed, from within the SSH & Web Terminal menu, click on Configuration. Here, we need to set a password or apply an SSH Key of a computer that will be authorized to log into Home Assistant in this form.

I grabbed the id_rsa.pub key we generated earlier and put it into the configuration in my setup.

Note: If you are using just a password with no SSH Key, protection mode will block you from starting the container. If you don't care about security in your setup, protection mode can be set to off and should allow you to start the container.

Validate that you can get into Home Assistant via SSH using the Open Web UI button in the Add-in.

Next, I would also install Visual Studio Code if not already. We will be doing the majority of tasks from now on inside Code.

Initialising the GIT repo:

Next, we need to initialise the /config folder to get ready to commit and push to Gitea. From within Code, open a new terminal window, and type the following:

To initialise the repo typ: git init

To add all the contents of /config to the repo, type git add -A

To commit the intial commit, type: git commit -m "Initial commit"

Now we will need to add our repo's SSH directory to the git config so that we have a destination for the push. This is the address we grabbed earlier. git remote add origin git@gitea:kanderson/home-assistant.git

After performing those steps, the git repo is fully initialised and ready to serve a push.

Creating SSH Keys for Gitea:

Before we can push our repo content off to Gitea, we first need to setup our SSH keys to automatically authenticate without the need for using a username or password. This is so that we can later down the track setup an Automation which does not need to store or have any username or password anywhere.

The way I descided to do this was by creating the .ssh directory inside my /config folder. Again these steps are performed inside Code in the /config directory.

Create the .ssh directory by typing: mkdir .ssh

Generate the private and public SSH Keys: ssh-keygen -t rsa -b 4096 -C "HomeAssistant"

When you run the above command, you should get prompted for a path location for the key to be saved. This path will need to be set as .ssh/id_rsa, the path inside the /config directory.

Do not enter a passphrase, as this gives us the ability to push the repo to Gitea automatically.

Once you have successfully created the SSH keys, you should now note that you have two files: id_rsa and id_rsa.pub.

Next we need to get the contents of id_rsa.pub. You can do this by either running cat .ssh/id_rsa.pub or opening it up in Code.

This SSH key then needs to be added to Gitea. Back in Gitea, navigate into the repo, click on Settings, and go to Deploy Keys. Click on Add Deploy Key and paste the contents into the  content space. This should also prefill the Title field.

Ensure that you also enable Enable Write Access by ticking the box at the bottom. Click on Add Deploy Key.

Update Git config - Read the SSH Keys:

Storing the SSH keys inside the /config is not a normal location for the system to see and use. For git to utilise the keys, we need to tell it where they live. This can be handled with one command.

git config core.sshCommand "ssh -i /config/.ssh/id_rsa -F /dev/null"

Perform a manual PUSH to see if everything is working:

First we need to validate that we can perform a push to Gitea without being prompted for a username or password and successfully do it without any additional prompts.

Run the following in Code: git push -u origin master

If it all works as expected we can move onto creating a script that does this for us.

Backup Script:

Inside the /config directory, create a new file called backup-ha.sh.

Copy the following script into this file.

# Change directory to /config
cd /config

# Git add all the files
git add -A 

# Commit a message to the change - also add date and time. 
git commit -m "Config files on `date +'%d-%m-%Y %H:%M:%S'`"

# Push the changes to Gitea
git push -u origin master

We also need to make sure that this .sh script is executable. Run a chmod +x backup-ha.sh

Finally test the script, go back into the SSH & Web Terminal webui and run the script manuall to see if it works succesfully. You may need to say Yes to accept the first initial ssh key write. After this is should be automatic.  

Type, ./backup-ha.sh

You should now see your Home Assistant files pushed over to the repo.

Automating the Backup Script:

We are on the home stretch now. All we need to do is automate the script to run either daily at a particular time or in a time interval. With my setup, I opted to go for an hourly backup.

From the Automation menu in Home Assistant, we need to create the following automation.

alias: Push HA Config to Gitea
description: Pushs any changes made to Home Assistant to Gitea
trigger:
  - platform: time_pattern
    hours: '1'
condition: []
action:
  - data:
      addon: a0d7b954_ssh
      input: /config/ha_gitpush.sh
    service: hassio.addon_stdin
mode: single

And that's it! The automation will run every 1 hour and push any config changes you or the containers make each time. The best part is that you also see the change history over each file, so if there is a breaking update or bug that comes through, you should see what changed.