Created
October 5, 2025 13:14
-
-
Save olange/ba458c1ab7e8a993b0d435b9eacfd72c to your computer and use it in GitHub Desktop.
GitHub to Synology DSM7 scheduled mirror backup script (aka scheduled sync)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# GitHub repo + wiki mirror backup for Synology NAS | |
set -euo pipefail | |
# --- CONFIG --- | |
GITHUB_USER="${1:-${GITHUB_USER:-}}" | |
if [ -z "${GITHUB_USER}" ]; then | |
echo "Usage: $0 <github-user-or-org>" | |
echo " or: GITHUB_USER=‹github-user-or-org› $0" | |
echo | |
echo "Example:" | |
echo " $0 ‹your-orgname›" | |
echo " GITHUB_USER=‹your-username› $0" | |
exit 1 | |
fi | |
BACKUP_ROOT="/volume1/synced/GitHub" | |
BACKUP_DIR="$BACKUP_ROOT/$GITHUB_USER" | |
TIMESTAMP=$(date "+%Y%m%d-%H%M%S") | |
LOG_FILE="$BACKUP_ROOT/gh-backup-${GITHUB_USER}-${TIMESTAMP}.log" | |
mkdir -p "$BACKUP_DIR" | |
log() { | |
local msg="$1" | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $msg" | tee -a "$LOG_FILE" | |
} | |
log "Starting GitHub backup for user/org: $GITHUB_USER" | |
# --- BACKUP LOOP --- | |
gh repo list "$GITHUB_USER" --limit 500 --json name,sshUrl -q '.[] | [.name, .sshUrl] | @tsv' | | |
while IFS=$'\t' read -r NAME SSHURL; do | |
REPO_DIR="$BACKUP_DIR/$NAME.git" | |
# --- main repository --- | |
if [ -d "$REPO_DIR" ]; then | |
log "Updating $NAME..." | |
git -C "$REPO_DIR" remote update --prune >>"$LOG_FILE" 2>&1 || log "⚠️ Failed to update $NAME" | |
else | |
log "Cloning new repo $NAME..." | |
git clone --mirror "$SSHURL" "$REPO_DIR" >>"$LOG_FILE" 2>&1 || log "⚠️ Failed to clone $NAME" | |
fi | |
# --- wiki repository --- | |
WIKI_SSHURL="${SSHURL%.git}.wiki.git" | |
WIKI_REPO_DIR="$BACKUP_DIR/${NAME}.wiki.git" | |
if git ls-remote "$WIKI_SSHURL" &>/dev/null; then | |
if [ -d "$WIKI_REPO_DIR" ]; then | |
log "Updating wiki for $NAME..." | |
git -C "$WIKI_REPO_DIR" remote update --prune >>"$LOG_FILE" 2>&1 || log "⚠️ Failed to update wiki for $NAME" | |
else | |
log "Cloning wiki for $NAME..." | |
git clone --mirror "$WIKI_SSHURL" "$WIKI_REPO_DIR" >>"$LOG_FILE" 2>&1 || log "⚠️ Failed to clone wiki for $NAME" | |
fi | |
else | |
log "No wiki found for $NAME" | |
fi | |
done | |
log "GitHub backup finished successfully." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Setup instructions
/var/services/homes/‹username›
)ssh-keygen -t ed25519 -C "synology-backup"
(creates files~/.ssh/id_ed25519[.pub]
)ssh -T [email protected]
and verify that the public key presented is among GitHub's SSH key fingerprints (will create the~/.ssh/known_hosts
file)wget gh_2.81.0_linux_amd64.tar.gz
installed to/var/packages/gh_2.81.0_linux_amd64
and symlinked to/usr/local/bin
(pick the correct architecture for your NAS, mine is x86_64/amd64)gh auth login
synced
volume for all things synced with the Cloud: Control Panel → Shared folders/volume1/synced/GitHub
parent folder for syncing GitHub repos/volume1/synced/GitHub/gh-backup.sh
andchmod ug+x gh-backup.sh
gh-backup.sh ‹org1›
every day at 04h04, send e-mail notification if script failsgh-backup.sh ‹org2›
every day at 04h08, idemgh-backup.sh ‹user›
every day at 04h12, idem