noisebridge-wiki/modules/wiki-primary/backup.nix
Jet 8cfede9f57
Some checks failed
CI / check (push) Has been cancelled
CI / deploy (push) Has been cancelled
feat: init
2026-03-17 04:07:44 -07:00

97 lines
3 KiB
Nix

{ config, pkgs, lib, ... }:
let
backupScript = pkgs.writeShellScript "wiki-backup" ''
set -euo pipefail
BACKUP_DIR="/var/backups/mysql"
TEXTFILE_DIR="/var/lib/prometheus-node-exporter/textfile"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Cleanup old local backups (keep 7 days)
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} + 2>/dev/null || true
# Dump database with mydumper
echo "Starting database dump..."
${pkgs.mydumper}/bin/mydumper \
--database noisebridge_mediawiki \
--outputdir "$BACKUP_DIR/$TIMESTAMP" \
--threads 2 \
--compress \
--routines \
--triggers \
--events \
--logfile "$BACKUP_DIR/mydumper.log"
# Sync to Backblaze B2
echo "Syncing to Backblaze B2..."
export RCLONE_CONFIG_B2_TYPE=b2
export RCLONE_CONFIG_B2_ACCOUNT=$(cat ${config.age.secrets.b2-credentials.path} | ${pkgs.jq}/bin/jq -r .keyID)
export RCLONE_CONFIG_B2_KEY=$(cat ${config.age.secrets.b2-credentials.path} | ${pkgs.jq}/bin/jq -r .applicationKey)
SYNC_SUCCESS=0
${pkgs.rclone}/bin/rclone sync "$BACKUP_DIR" b2:noisebridge-wiki-backup/mysql/ \
--transfers 4 \
--checkers 8 \
--b2-hard-delete \
&& SYNC_SUCCESS=1
# Sync uploaded images to B2
${pkgs.rclone}/bin/rclone sync /var/lib/mediawiki/images/ b2:noisebridge-wiki-backup/images/ \
--transfers 4 \
--checkers 8 \
|| SYNC_SUCCESS=0
# Back up Tor hidden service keys (losing these = losing the .onion address)
${pkgs.rclone}/bin/rclone sync /var/lib/tor/onion/ b2:noisebridge-wiki-backup/tor-keys/ \
--transfers 1 \
|| true
# Write metrics for Prometheus textfile collector (no leading whitespace!)
cat > "$TEXTFILE_DIR/backup.prom" <<'METRICS'
# HELP backup_latest_timestamp_seconds Unix timestamp of latest backup
# TYPE backup_latest_timestamp_seconds gauge
METRICS
echo "backup_latest_timestamp_seconds $(date +%s)" >> "$TEXTFILE_DIR/backup.prom"
cat >> "$TEXTFILE_DIR/backup.prom" <<METRICS
# HELP backup_b2_sync_success Whether the last B2 sync succeeded (1=success, 0=failure)
# TYPE backup_b2_sync_success gauge
backup_b2_sync_success $SYNC_SUCCESS
METRICS
echo "Backup complete."
'';
in
{
systemd.services.wiki-backup = {
description = "Wiki database and image backup to Backblaze B2";
after = [ "mysql.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = backupScript;
User = "root";
IOSchedulingClass = "idle";
CPUSchedulingPolicy = "idle";
};
};
systemd.timers.wiki-backup = {
description = "Daily wiki backup timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 04:00:00";
Persistent = true;
RandomizedDelaySec = "15m";
};
};
systemd.tmpfiles.rules = [
"d /var/backups/mysql 0750 root root -"
];
age.secrets.b2-credentials = {
file = ../../secrets/b2-credentials.age;
owner = "root";
group = "root";
mode = "0400";
};
}