104 lines
4.3 KiB
Org Mode
104 lines
4.3 KiB
Org Mode
#+TITLE: Mastodon Backup
|
|
#+DATE: 2023-07-26
|
|
* Prologue
|
|
People on the Fediverse like to point out how you have to backup your
|
|
data regularly in case of a catastrophic failure effecting your
|
|
instance, the host of your instance, the data centre of your instance
|
|
or maybe your admin. Heck, even a catastrophic failure effecting an
|
|
admin of /another/ instance might make you wish you had a backup of
|
|
your follows list[fn::If a remote admin decides to de-federate your
|
|
instance it will sever all your connections with people on that
|
|
instance.].
|
|
|
|
Remembering to make a backup manually is already difficult
|
|
enough[fn::My last manual backup was over a year old.], but then you
|
|
also need to remember *how* to make that backup...
|
|
* Manual Backups
|
|
Got to "App Settings". You do not know where "App Settings" are? I
|
|
know the feeling... They are behind the three cogs on the top
|
|
left. Navigate to "Import and export". Click "Data export". Click the
|
|
"CSV" link. Click the other "CSV" link. Click the other other "CSV"
|
|
link. You have now downloaded your "follows", "muted" and "blocked"
|
|
accounts lists.
|
|
* Automatic Backups
|
|
I have recently discovered [[https://toot.bezdomni.net/introduction.html][toot - Mastodon CLI client]] which can output
|
|
a list of your follows and people following you. I have [[https://github.com/ihabunek/toot/pull/390][contributed
|
|
code for "muted" and "blocked" commands]] which got accepted and
|
|
released in version 0.38.
|
|
|
|
We first need to authenticate to our instance by running ~toot
|
|
login~. This is only needed once. For more information [[https://toot.bezdomni.net/usage.html][see the
|
|
official documentation]].
|
|
|
|
I am running the following script from cron once a day:
|
|
#+begin_src shell
|
|
#! /bin/ksh
|
|
ACCOUNT=@florian@bsd.network
|
|
INSTANCE=bsd.network
|
|
BACKUPDIR=/home/mastodonbackup/backup
|
|
|
|
set -e
|
|
set -o pipefail
|
|
|
|
exit_if_nonzero_or_stderr() {
|
|
(
|
|
set -o pipefail
|
|
{ "$@" 1>&3 ;} 2>&1 | {
|
|
if IFS= read -r line; then
|
|
printf "%s\n" "$line"
|
|
cat
|
|
exit 1
|
|
fi
|
|
} >&2
|
|
) 3>&1
|
|
}
|
|
|
|
exit_if_nonzero_or_stderr /usr/local/bin/toot muted | \
|
|
awk '$2 !~ /^@.*@/ {print $2 "@'${INSTANCE}'"; next} {print $2}' \
|
|
> ${BACKUPDIR}/muted.new
|
|
|
|
mv ${BACKUPDIR}/muted{.new,}
|
|
|
|
exit_if_nonzero_or_stderr /usr/local/bin/toot blocked | \
|
|
awk '$2 !~ /^@.*@/ {print $2 "@'${INSTANCE}'"; next} {print $2}' \
|
|
> ${BACKUPDIR}/blocked.new
|
|
mv ${BACKUPDIR}/blocked{.new,}
|
|
|
|
exit_if_nonzero_or_stderr /usr/local/bin/toot following ${ACCOUNT} | \
|
|
awk '$2 !~ /^@.*@/ {print $2 "@'${INSTANCE}'"; next} {print $2}' \
|
|
> ${BACKUPDIR}/following.new
|
|
mv ${BACKUPDIR}/following{.new,}
|
|
|
|
exit_if_nonzero_or_stderr /usr/local/bin/toot followers ${ACCOUNT} | \
|
|
awk '$2 !~ /^@.*@/ {print $2 "@'${INSTANCE}'"; next} {print $2}' \
|
|
> ${BACKUPDIR}/followers.new
|
|
mv ${BACKUPDIR}/followers{.new,}
|
|
#+end_src
|
|
~toot~ outputs accounts from the local instance without
|
|
/@instance/. ~awk(1)~ checks for the existence of two /@/ characters
|
|
and if they are not present outputs /@instance@/ after the account
|
|
name.
|
|
|
|
Unfortunately ~toot~ always exits with 0, even if there is an error so
|
|
we need to check if there is some output on =stderr= so that we do not
|
|
replace our backup with empty files. For that I copy-pasted
|
|
=exit_if_nonzero_or_stderr= from [[https://stackoverflow.com/a/61468182][stackoverflow]] like a pro.
|
|
|
|
My crontab entry looks like this:
|
|
#+begin_src crontab
|
|
~ 9 * * * -sn su -s /bin/sh mastodonbackup -c /home/mastodonbackup/backup.sh
|
|
#+end_src
|
|
=-sn= ensures that the script is only run once and that no mail is
|
|
sent after a successful run. See [[https://man.openbsd.org/crontab.5][crontab(5)]] for details.
|
|
|
|
* Epilogue
|
|
I have automated backing up the most important lists from my mastodon
|
|
account. My mastodon account is running on somebody else's
|
|
computer. The backup data is written as text files on a system that I
|
|
control. That system is hooked up to my standard backup solution to
|
|
have daily, multiple-redundant backups.
|
|
|
|
I expire my toots after 90 days using [[https://ephemetoot.hugh.run/][ephemetoot]]. I have configured it
|
|
to save the toots and media before deleting them from my account.
|