Skip to content

Commit 3719df4

Browse files
committed
feat: add Coolify deployment with versioned Spaces backups and monitoring
1 parent ea7c5a0 commit 3719df4

30 files changed

Lines changed: 3403 additions & 896 deletions

‎.dockerignore‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ backups
77
build
88
dist
99
tests
10+
11+
.env
12+
.env.*
13+
*.pem
14+
*.key
15+
.uv-cache

‎.env.example‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# REQUIRED: fill these six values. They intentionally have no fake working defaults.
2+
GITHUB_APP_ID=
3+
# Comma-separated users/orgs where the App is installed on All repositories.
4+
GITHUB_APP_OWNERS=
5+
# Single-line base64 of the downloaded App PEM; treat as a secret.
6+
GITHUB_APP_PRIVATE_KEY_BASE64=
7+
# DigitalOcean Spaces key/secret, NOT a DigitalOcean API token.
8+
AWS_ACCESS_KEY_ID=
9+
AWS_SECRET_ACCESS_KEY=
10+
# Bucket name only: it may contain other applications' files outside SPACES_PREFIX/.
11+
SPACES_BUCKET=
12+
13+
# OPTIONAL: working defaults; change region to match your existing bucket.
14+
SPACES_REGION=fra1
15+
# Reserve this folder exclusively for this worker. Nested prefixes are allowed.
16+
SPACES_PREFIX=github-backup
17+
BACKUP_INTERVAL_HOURS=1
18+
# Recent changed versions plus older UTC calendar checkpoints; deduplicated.
19+
BACKUP_RETENTION=3
20+
BACKUP_KEEP_WEEKLY=2
21+
BACKUP_KEEP_MONTHLY=2
22+
BACKUP_KEEP_OLDEST=true
23+
# 0 disables the age floor to keep the above count policy bounded.
24+
BACKUP_MIN_AGE_DAYS=0
25+
BACKUP_MANIFEST_RETENTION=14
26+
# Budget counts only live objects inside SPACES_PREFIX/, not the shared bucket.
27+
BACKUP_MAX_STORAGE_GIB=100
28+
BACKUP_WORKERS=1
29+
BACKUP_TIMEOUT_HOURS=12
30+
BACKUP_CPUS=0.5
31+
BACKUP_MEMORY_LIMIT=512m
32+
# Optional comma-separated numeric IDs of intentionally deleted repos; never purges data.
33+
ACKNOWLEDGED_MISSING_REPOSITORIES=
34+
35+
# OPTIONAL: disabled when empty. Copy a Push monitor's secret URL from Uptime Kuma.
36+
UPTIME_KUMA_PUSH_URL=
37+
# Enable only for Kuma reached over a trusted private HTTP network.
38+
UPTIME_KUMA_ALLOW_HTTP=false
39+
UPTIME_KUMA_TIMEOUT_SECONDS=5
40+
# 0 = automatic: 2 * BACKUP_INTERVAL_HOURS + 1 (3 hours with default hourly checks).
41+
UPTIME_KUMA_MAX_SUCCESS_AGE_HOURS=0

‎CONTRIBUTING.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ privilege, predictable recovery, and backward compatibility ahead of convenience
1010
private repository names, proprietary source, or real backup data in an issue or pull request.
1111
- Keep pull requests focused. Large behavior changes should describe migration and restore impact.
1212

13+
## Deployment documentation
14+
15+
The README is the primary **Coolify + Docker Compose + GitHub App + Spaces** installation guide.
16+
Keep `compose.yaml`, `.env.example`, `docs/COOLIFY.md`, and `docs/MONITORING.md` aligned when
17+
changing environment variables or defaults. Keep CLI/systemd/PAT alternatives in `docs/CLI.md`.
18+
Container logs must use stdout/stderr; monitoring failure must not interrupt backup persistence,
19+
and secret Push URLs must never appear in logs. Test actual backup status and missing-heartbeat
20+
behavior rather than unconditionally reporting a running process as successful.
21+
1322
## Development setup
1423

1524
Python 3.11 or newer, Git, and Git LFS are required. Docker is required for container changes.

‎Dockerfile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
1818
GITHUB_BACKUP_DESTINATION=/backups \
1919
DEBIAN_FRONTEND=noninteractive
2020

21+
RUN mkdir /cache && chown 10001:10001 /cache
2122
RUN apt-get update \
2223
&& apt-get install --no-install-recommends -y ca-certificates git git-lfs openssl \
2324
&& rm -rf /var/lib/apt/lists/* \

‎README.md‎

Lines changed: 126 additions & 756 deletions
Large diffs are not rendered by default.

‎SUPPORT.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
`github-backup` is a community-maintained project and has no guaranteed response time or paid
44
support channel.
55

6-
- Read the [README](README.md), especially preflight checks, monitoring, restore, and
7-
troubleshooting.
6+
- Start with the [Coolify-first README](README.md), [deployment/environment guide](docs/COOLIFY.md),
7+
and [logging/Uptime Kuma guide](docs/MONITORING.md). Alternative CLI installs are in
8+
[the CLI reference](docs/CLI.md).
89
- Search [existing issues](https://github.com/drhdev/github-backup/issues) before opening a new
910
one.
1011
- Use the bug-report template for reproducible operational defects and the feature template for
1112
proposals.
1213
- Include the application version, Python or container version, operating system, storage mode,
13-
sanitized configuration, command, exit code, and relevant sanitized logs.
14-
- Never post tokens, credentials, private repository names, private URLs, proprietary source,
14+
sanitized configuration, command, exit code, and relevant sanitized stdout/stderr logs.
15+
For Coolify include the Compose source revision, health state, and scheduler completion event.
16+
- Never post tokens, credentials, private repository names, private URLs (including Uptime Kuma Push URLs), proprietary source,
1517
manifests, or backup contents.
1618

1719
Suspected vulnerabilities or credential/private-data exposure must be reported through the

‎compose.yaml‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
services:
2+
github-backup:
3+
build: .
4+
# Build this checkout; published images before this feature lack the scheduler.
5+
entrypoint: ["python", "-m", "github_backup.scheduler"]
6+
command: []
7+
hostname: github-backup
8+
restart: unless-stopped
9+
init: true
10+
read_only: true
11+
cap_drop: [ALL]
12+
security_opt: [no-new-privileges:true]
13+
stop_grace_period: 90s
14+
pids_limit: 128
15+
cpus: "${BACKUP_CPUS:-0.5}"
16+
mem_limit: ${BACKUP_MEMORY_LIMIT:-512m}
17+
tmpfs:
18+
- /tmp:rw,noexec,nosuid,size=64m,mode=1777
19+
volumes:
20+
- backup-cache:/cache
21+
environment:
22+
GITHUB_APP_ID: ${GITHUB_APP_ID:?Set GitHub App ID}
23+
GITHUB_APP_OWNERS: ${GITHUB_APP_OWNERS:?Set comma-separated account and organization names}
24+
GITHUB_APP_PRIVATE_KEY_BASE64: ${GITHUB_APP_PRIVATE_KEY_BASE64:?Set base64 PEM private key}
25+
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:?Set Spaces key}
26+
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:?Set Spaces secret}
27+
AWS_EC2_METADATA_DISABLED: "true"
28+
SPACES_BUCKET: ${SPACES_BUCKET:?Set Spaces bucket name}
29+
SPACES_REGION: ${SPACES_REGION:-fra1}
30+
SPACES_PREFIX: ${SPACES_PREFIX:-github-backup}
31+
BACKUP_INTERVAL_HOURS: ${BACKUP_INTERVAL_HOURS:-1}
32+
BACKUP_RETENTION: ${BACKUP_RETENTION:-3}
33+
BACKUP_MAX_STORAGE_GIB: ${BACKUP_MAX_STORAGE_GIB:-100}
34+
BACKUP_KEEP_WEEKLY: ${BACKUP_KEEP_WEEKLY:-2}
35+
BACKUP_KEEP_MONTHLY: ${BACKUP_KEEP_MONTHLY:-2}
36+
BACKUP_KEEP_OLDEST: ${BACKUP_KEEP_OLDEST:-true}
37+
BACKUP_MANIFEST_RETENTION: ${BACKUP_MANIFEST_RETENTION:-14}
38+
BACKUP_MIN_AGE_DAYS: ${BACKUP_MIN_AGE_DAYS:-0}
39+
ACKNOWLEDGED_MISSING_REPOSITORIES: ${ACKNOWLEDGED_MISSING_REPOSITORIES:-}
40+
BACKUP_TIMEOUT_HOURS: ${BACKUP_TIMEOUT_HOURS:-12}
41+
UPTIME_KUMA_PUSH_URL: ${UPTIME_KUMA_PUSH_URL:-}
42+
UPTIME_KUMA_ALLOW_HTTP: ${UPTIME_KUMA_ALLOW_HTTP:-false}
43+
UPTIME_KUMA_TIMEOUT_SECONDS: ${UPTIME_KUMA_TIMEOUT_SECONDS:-5}
44+
UPTIME_KUMA_MAX_SUCCESS_AGE_HOURS: ${UPTIME_KUMA_MAX_SUCCESS_AGE_HOURS:-0}
45+
BACKUP_WORKERS: ${BACKUP_WORKERS:-1}
46+
healthcheck:
47+
test: ["CMD", "python", "-m", "github_backup.scheduler", "health"]
48+
interval: 60s
49+
timeout: 10s
50+
retries: 3
51+
start_period: 60s
52+
logging:
53+
driver: json-file
54+
options:
55+
max-size: "10m"
56+
max-file: "3"
57+
volumes:
58+
backup-cache:

0 commit comments

Comments
 (0)