-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
The backup engine keeps its configuration near the beginning of github-backup.sh.
The default configuration is designed for a Linux/NAS environment.
BASE="/volume1/Archivum"
TOKEN_FILE="$HOME/.config/github/token"
LOG_DIR="$BASE/_logs"
LOG_KEEP=30
LOCK_DIR="/tmp/github-backup.lock"
API="https://api.github.com"The root directory where repository mirrors are stored.
Example:
BASE="/volume1/Archivum"The script creates one bare mirror per repository:
/volume1/Archivum/
├── project-a.git/
├── project-b.git/
└── project-c.git/
The directory must be writable by the user running the backup.
Location of the GitHub Personal Access Token.
Default:
TOKEN_FILE="$HOME/.config/github/token"The token should be stored as a single line.
Recommended permissions:
chmod 600 ~/.config/github/tokenDo not commit this file to the repository.
Directory containing backup logs.
Default:
LOG_DIR="$BASE/_logs"A new log is created for every execution:
_logs/
├── github-backup-2026-09-28_08-00-00.log
├── github-backup-2026-09-29_08-00-00.log
└── ...
The directory is created automatically if it does not exist.
Number of recent log files to retain.
Default:
LOG_KEEP=30After each successful script execution, older logs beyond this number are removed.
For example:
LOG_KEEP=90keeps approximately 90 log files.
The script does not rotate or delete repository mirrors as part of log rotation.
Location of the temporary lock used to prevent concurrent executions.
Default:
LOCK_DIR="/tmp/github-backup.lock"If another instance is already running, the second instance exits instead of modifying the same mirrors simultaneously.
A stale lock from a process that no longer exists is automatically removed.
GitHub API endpoint.
Default:
API="https://api.github.com"There normally should be no reason to change this value.
Git operations use SSH.
The script sets:
export GIT_TERMINAL_PROMPT=0
export GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=20"Disables Git's interactive credential prompt.
This is important for scheduled backups. A scheduled task must fail rather than wait indefinitely for user input.
Configures Git's SSH behavior.
BatchMode=yes prevents interactive authentication prompts.
ConnectTimeout=20 limits the time spent waiting for an unreachable SSH endpoint.
The SSH key itself is managed by the normal OpenSSH configuration.
Repositories are normally stored using their repository name:
project.git
GitHub can contain repositories with the same name under different owners.
For example:
alice/project
bob/project
would otherwise collide.
The script detects these collisions and uses:
alice__project.git
bob__project.git
This avoids overwriting one repository with another.
During discovery, the script records:
- full repository name
- SSH URL
- visibility
- fork status
- archived status
- GitHub's reported repository size
This information is used for display and backup processing.
It is not stored as a separate database.
The script deliberately does not automatically delete local mirrors that disappear from the GitHub API.
For example:
GitHub:
project-a
project-b
Local:
project-a.git
project-b.git
project-old.git
If project-old is no longer returned by GitHub, it is reported as an orphan:
ORPHANED MIRRORS
! project-old.git
The local backup remains untouched.
This can happen when a repository is:
- deleted
- renamed
- transferred
- no longer accessible to the account
The script cannot safely determine which of these happened, so it keeps the data.
If the expected mirror path already exists but is not a valid bare Git repository, the script does not overwrite it.
Instead:
project.git
is moved to:
project.git.broken-2026-09-28_08-00-00
The script then attempts to create a fresh mirror.
This protects unrelated files from accidental deletion.
Configuration can be used with monitoring or automation because the script returns distinct exit codes:
0 Backup completed successfully
1 Backup completed with repository errors
2 Fatal error
For example:
./github-backup.sh
STATUS=$?
if [ "$STATUS" -eq 0 ]; then
echo "Backup OK"
elif [ "$STATUS" -eq 1 ]; then
echo "Backup completed with errors"
else
echo "Backup failed"
fiThe script does not require a large environment-variable configuration system.
The main settings are intentionally kept directly in the script so that a NAS installation can be understood and maintained without additional configuration files.
The following optional environment variable is supported:
NO_COLOR=1This disables terminal colors.
Useful for logs, cron jobs and environments where ANSI escape sequences are undesirable:
NO_COLOR=1 ./github-backup.shA typical Synology installation can use:
BASE="/volume1/Archivum"
TOKEN_FILE="$HOME/.config/github/token"
LOG_DIR="$BASE/_logs"
LOG_KEEP=30The backup script can then be scheduled independently of the repository storage location.
For scheduled execution, see:
[Scheduling](Scheduling)
For restoring repositories from the resulting mirrors, see:
[Recovery](Recovery)