Skip to content

Configuration

Csaba Polyak edited this page Sep 28, 2026 · 1 revision

Configuration

The backup engine keeps its configuration near the beginning of github-backup.sh.

The default configuration is designed for a Linux/NAS environment.

Configuration variables

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"

BASE

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.


TOKEN_FILE

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/token

Do not commit this file to the repository.


LOG_DIR

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.


LOG_KEEP

Number of recent log files to retain.

Default:

LOG_KEEP=30

After each successful script execution, older logs beyond this number are removed.

For example:

LOG_KEEP=90

keeps approximately 90 log files.

The script does not rotate or delete repository mirrors as part of log rotation.


LOCK_DIR

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.


API

GitHub API endpoint.

Default:

API="https://api.github.com"

There normally should be no reason to change this value.


SSH configuration

Git operations use SSH.

The script sets:

export GIT_TERMINAL_PROMPT=0
export GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=20"

GIT_TERMINAL_PROMPT

Disables Git's interactive credential prompt.

This is important for scheduled backups. A scheduled task must fail rather than wait indefinitely for user input.

GIT_SSH_COMMAND

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.


Repository naming

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.


Repository metadata

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.


Orphaned mirrors

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.


Invalid local targets

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.


Exit codes

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"
fi

Environment variables

The 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=1

This disables terminal colors.

Useful for logs, cron jobs and environments where ANSI escape sequences are undesirable:

NO_COLOR=1 ./github-backup.sh

Recommended NAS configuration

A typical Synology installation can use:

BASE="/volume1/Archivum"
TOKEN_FILE="$HOME/.config/github/token"
LOG_DIR="$BASE/_logs"
LOG_KEEP=30

The 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)

Clone this wiki locally