Files
gitea-ops/README.md
T
prajwal a181625c89 Initial commit: backup + mirror automation for self-hosted Gitea
Includes:
- gitea-backups/bin/backup.sh (per-push bundle + DB snapshot to local + S3)
- gitea-backups/bin/install-hooks.sh (idempotent post-receive shim installer)
- gitea-backups/bin/retention.sh (count-based retention: keep newest 7 dates)
- gitea-mirror/bin/auto-mirror.sh (Gitea -> GitHub push mirror automation,
  hardened against Gitea outages)
- crontab.txt (reference for the 3 cron entries)
- README.md (architecture, layout, bootstrap)
2026-05-09 06:02:09 +00:00

71 lines
3.0 KiB
Markdown

# gitea-ops
Source of truth for the Gitea install at `/home/ubuntu/gitea/` on this server, and the automation around it.
## Layout
```
gitea-ops/
├── README.md
├── crontab.txt # cron entries (install with: crontab crontab.txt)
├── gitea-backups/bin/
│ ├── backup.sh # called per push from each repo's post-receive hook
│ ├── install-hooks.sh # cron, every minute: ensures hook shim in every repo
│ └── retention.sh # cron, daily 03:00 UTC: keeps newest 7 date-folders
└── gitea-mirror/bin/
└── auto-mirror.sh # cron, every minute: ensures GitHub push-mirror per repo
```
The deployment target is fixed: scripts run from `/home/ubuntu/gitea-backups/bin/` and `/home/ubuntu/gitea-mirror/bin/`.
## Components
| Script | Trigger | Purpose |
|---|---|---|
| `backup.sh` | per `git push` (via post-receive hook) | Bundle repo + snapshot SQLite, upload both to local + S3 |
| `install-hooks.sh` | cron, 1 min | Drop the `zzz-backup` shim into every repo's `hooks/post-receive.d/` |
| `retention.sh` | cron, daily 03:00 UTC | Keep newest 7 calendar dates of backups (S3 + local), prune older |
| `auto-mirror.sh` | cron, 1 min | For every Gitea repo, ensure matching private GitHub repo + push mirror exist |
## Backup destinations
1. **Local**`/home/ubuntu/gitea-backups/repos/<owner>/<repo>/*.bundle` and `/home/ubuntu/gitea-backups/db/*-gitea.db.gz`
2. **S3**`s3://toqqer-gitea-backup/<YYYY-MM-DD>/repos/...` and `.../<YYYY-MM-DD>/db/...` (region `ap-south-1`)
3. **GitHub** — live mirror at `github.com/prajwalpatil-toqqer/<repo>` for every Gitea repo (real-time via `sync_on_commit`)
## Retention semantics
Keep the **most recent 7 calendar dates** that have backups, regardless of how old they are. Quiet periods don't empty the store — the last 7 active dates always persist.
## Required outside-of-repo state
Not committed (see `.gitignore`):
- `/home/ubuntu/gitea-mirror/gitea.token` — Gitea PAT (scopes: repo, user)
- `/home/ubuntu/gitea-mirror/github.token` — GitHub classic PAT (scope: repo)
- `/home/ubuntu/.aws/credentials` — IAM `gitea-backup-bot` (scoped to one bucket)
- `/home/ubuntu/.config/rclone/rclone.conf` — same key, rclone format
## Service unit
Gitea itself runs under user systemd:
- Unit: `~/.config/systemd/user/gitea.service`
- Persistence: `loginctl enable-linger ubuntu`
- Status: `systemctl --user status gitea`
- Logs: `journalctl --user -u gitea -f`
## Bootstrap a fresh server
```bash
# 1. Place the secret files (gitea.token, github.token, aws creds, rclone.conf) outside the repo
# 2. Mirror the directory layout:
mkdir -p /home/ubuntu/gitea-backups/{bin,db,repos,logs}
mkdir -p /home/ubuntu/gitea-mirror/{bin,logs}
cp gitea-backups/bin/* /home/ubuntu/gitea-backups/bin/
cp gitea-mirror/bin/* /home/ubuntu/gitea-mirror/bin/
chmod +x /home/ubuntu/gitea-backups/bin/*.sh /home/ubuntu/gitea-mirror/bin/*.sh
# 3. Install cron
crontab crontab.txt
```