Ctrl K
ComunidadGuías…

README.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# vps-github-backup

**Daily full-server backups of a Linux VPS to a private GitHub repository, with Discord alerts.**

If the VPS is wiped, you clone one repository on a new host and follow `RESTORE.md`: applications, databases and system configuration come back.

![bash](https://img.shields.io/badge/bash-4EAA25?style=flat-square&logo=gnubash&logoColor=white)
![python](https://img.shields.io/badge/python-3776AB?style=flat-square&logo=python&logoColor=white)
![license](https://img.shields.io/badge/license-MIT-blue?style=flat-square)

---

## Features

- **Applications**: any list of directories, compressed with zstd (`.env` files included)
- **Databases**: consistent online dumps of PostgreSQL, MySQL/MariaDB, Redis and SQLite
- **System config**: nginx, Let's Encrypt certificates, cron, systemd units, firewall, pm2 process list
- **Large assets**: images and uploads are stored as raw files, so git deduplicates them and each file is uploaded only once
- **GitHub limits handled**: files over 100 MB are split automatically
- **One snapshot, no bloat**: each run replaces the previous snapshot, so the repository does not grow forever
- **Discord alerts**: a webhook message or a bot DM when any step fails, plus a watchdog if no backup succeeded for 26 h
- **Sanity checks**: low disk space and suspiciously small database dumps are reported
- **Restore guide** shipped inside every snapshot

## How it works

```mermaid
flowchart LR
    A[cron 04:10] --> B[backup.sh]
    B --> C[code/*.tar.zst]
    B --> D[db dumps]
    B --> E[system config]
    B --> F[raw assets]
    C & D & E & F --> G[orphan commit]
    G -->|force push| H[(private GitHub repo)]
    B -.->|on failure| I[Discord alert]
    J[watchdog hourly] -.->|no success in 26 h| I
```

## Requirements

Linux with `bash`, `git`, `tar`, `zstd`, `python3`, `flock`. Plus the clients for the databases you back up (`sqlite3`, `pg_dumpall`, `mysqldump`, `redis-cli`).

```bash
apt install git zstd python3 sqlite3
```

## Installation

```bash
git clone https://github.com/Zodiachz/vps-github-backup.git
cd vps-github-backup
sudo ./install.sh
```

The installer copies the scripts to `/opt/vps-github-backup`, creates an SSH deploy key and adds two cron jobs (daily backup at 04:10, hourly watchdog). Then:

1. Create a **private** GitHub repository, for example `server-backup`.
2. In that repository, go to **Settings → Deploy keys → Add deploy key**, paste the key printed by the installer and tick **Allow write access**.
3. Edit `/opt/vps-github-backup/backup.conf`.
4. Test without pushing, then run for real:

```bash
sudo /opt/vps-github-backup/backup.sh --dry-run
sudo /opt/vps-github-backup/backup.sh
```

## Configuration

`backup.conf` is a bash file. Minimal example:

```bash
REPO_REMOTE="git@github.com:YOUR_USER/server-backup.git"
SSH_KEY="/root/.ssh/backup_deploy"

TAR_DIRS=("/opt/my-app" "/var/www/my-site")
RAW_DIRS=("/var/www/my-site/public/uploads")
SQLITE_DBS=("/opt/my-app/data/app.db")
POSTGRES=1
REDIS=1
PM2=1

DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
```

See [`backup.conf.example`](backup.conf.example) for every option.

### Discord alerts

| Method | Settings |
|---|---|
| Channel webhook | `DISCORD_WEBHOOK_URL` |
| Direct message from your bot | `DISCORD_BOT_TOKEN` + `DISCORD_USER_IDS` (the bot must share a server with you) |

You get an alert when:

- a step fails (archive, database dump, push)
- a database dump is smaller than `MIN_DUMP_BYTES`
- free disk space is below `MIN_FREE_GB`
- no backup has succeeded for `STALE_HOURS` (watchdog)

Successful runs stay silent.

## Snapshot layout

```
code/      application directories (.tar.zst), named after their path: /opt/my-app -> opt_my-app.tar.zst
db/        database dumps (.zst)
system/    etc.tar.zst, crontab, pm2 list, firewall rules, package list
assets/    raw large folders, named the same way
RESTORE.md step-by-step restore guide
SNAPSHOT.txt  date, host and size
```

## Restore

Clone the backup repository on the new server and follow [`RESTORE.md`](RESTORE.md).

## Security notes

- The backup contains your secrets (`.env` files, database contents, TLS keys). **Keep the repository private** and enable two-factor authentication on your GitHub account.
- Use a **deploy key**: it can only access that one repository, not your whole account.
- `backup.conf` holds your Discord token/webhook. It is created with `chmod 600` and ignored by git.

## Limits

- GitHub recommends repositories under 5 GB. Exclude replays, logs and build artifacts.
- A single push is limited to 2 GB. If your first snapshot is bigger, start with fewer `RAW_DIRS` and add them over the next runs (unchanged files are not uploaded again).
- The staging folder is wiped on every run. The script refuses system folders and any non-empty folder it did not create.
- Only the latest snapshot is kept. For history, run a second copy of the tool to another repository weekly.

## License

[MIT](LICENSE)