No description
Find a file
2025-11-17 19:50:06 +01:00
compose init, Versuch 3 2025-11-17 11:15:29 +01:00
config init 2025-11-17 10:40:23 +01:00
data init, Versuch 3 2025-11-17 11:15:29 +01:00
db_dumps init, Versuch 3 2025-11-17 11:15:29 +01:00
scripts Add host backup runner and clarify volume handling 2025-11-17 19:33:11 +01:00
.env.example Security improvements 2025-11-17 19:03:39 +01:00
.gitignore Security improvements 2025-11-17 19:03:39 +01:00
docker-compose.yml Default compose mounts and drop version key 2025-11-17 19:50:06 +01:00
README.md Add host backup runner and clarify volume handling 2025-11-17 19:33:11 +01:00

Borgmatic Backup Suite Full Docker Edition

Ein vollständiges, produktionsreifes Backup-System für Docker-Umgebungen mit Borgmatic und Docker Compose.

Inhalt

  • Zero-Downtime Backups für MySQL/MariaDB
  • Projektbasierte Datenbank-Dumps (seafile, nginx2-php-example, lychee)
  • Sicherung aller relevanten Docker-Volumes
  • Sicherung der Compose-/Stack-Konfigurationen
  • Portainer-Konfigurations-Export
  • Mehrere Backup-Repositories (lokal + SSH-Remote)
  • Health-Check-Skript
  • Restore-Workflow inkl. Post-Restore-Skript
  • Vollständig über .env konfigurierbar

Dieses Repository ist so aufgebaut, dass es direkt als Git-Repository verwendet werden kann.


Projektstruktur

borgmatic/
├── README.md
├── docker-compose.yml
├── .env
├── .env.example
├── config/
│   └── config.yaml
├── hooks/
│   ├── pre-backup.sh
│   └── post-backup.sh
├── scripts/
│   ├── install.sh
│   ├── test-backup.sh
│   ├── post-restore.sh
│   └── health.sh
├── compose/
│   └── .gitkeep
├── data/
│   ├── cache/
│   │   └── .gitkeep
│   └── ssh/
│       └── .gitkeep
└── db_dumps/
    ├── seafile/
    │   └── .gitkeep
    ├── nginx2-php-example/
    │   └── .gitkeep
    └── lychee/
        └── .gitkeep

Alle Pfade sind relativ zum Projektverzeichnis gehalten. Host-spezifische Pfade werden ausschließlich über die .env gesteuert.


Voraussetzungen

  • Docker
  • Docker Compose (Plugin oder eigenständiges Binary)
  • Ein vorhandenes Borg-Repository oder die Bereitschaft, eines zu initialisieren
  • Optional: SSH-Zugang zu einem Remote-Backup-Server

Konfiguration

.env / .env.example

Die Datei .env.example enthält alle benötigten Variablen und dient als Vorlage. Lege deine reale .env niemals ins Git-Repo.

TZ=Europe/Berlin

# Pfade relativ zum Projektverzeichnis
CONFIG_PATH=./config
HOOKS_PATH=./hooks
LOCAL_REPO_PATH=./repo
SSH_PATH=./data/ssh
CACHE_PATH=./data/cache
DB_DUMPS_PATH=./db_dumps
COMPOSE_PATH=./compose

# Pfad zum Docker-Volumes-Root auf dem Host
VOLUMES_PATH=/var/lib/docker/volumes

# Borgmatic / Borg Einstellungen
BORG_PASSPHRASE_FILE=/etc/borgmatic/passphrase
CRON=enabled
CRON_SCHEDULE=0 3 * * *

# Remote-Repositories (Platzhalter anpassen)
REMOTE_REPO1=ssh://backup@example.com/home/backup/your-repo
REMOTE_REPO2=

Vorgehen:

cp .env.example .env
# Danach .env anpassen (z. B. Remote-Repos, VOLUMES_PATH etc.)

Alle Pfade sind frei anpassbar. Standardmäßig zeigt LOCAL_REPO_PATH auf ./repo im Projektverzeichnis.


docker-compose.yml

Der borgmatic-Service läuft als eigenständiger Container und führt Backups nach Zeitplan aus:

version: "3.9"

services:
  borgmatic:
    image: ghcr.io/borgmatic-collective/borgmatic:latest
    container_name: borgmatic
    hostname: borgmatic
    restart: unless-stopped

    env_file:
      - .env

    volumes:
      - ${CONFIG_PATH}:/etc/borgmatic
      - ${HOOKS_PATH}:/etc/borgmatic/hooks
      - ${LOCAL_REPO_PATH}:/repo
      - ${SSH_PATH}:/root/.ssh
      - ${CACHE_PATH}:/root/.cache/borg
      - ${DB_DUMPS_PATH}:/db_dumps
      - ${COMPOSE_PATH}:/compose:ro
      - ${VOLUMES_PATH}:/volumes:ro

    cap_add:
      - SYS_ADMIN
    devices:
      - /dev/fuse
    security_opt:
      - apparmor:unconfined

Borgmatic-Konfiguration (config/config.yaml)

location:
  source_directories:
    - /volumes
    - /compose
    - /db_dumps
    # Eigene zusätzliche Verzeichnisse kannst du ergänzen, solange sie im Container gemountet sind.
    # Beispiel unten: Host-Pfad /home/user/important_data → Container-Pfad /extra_data
    # - /extra_data

  repositories:
    - /repo
    - ${REMOTE_REPO1}
    - ${REMOTE_REPO2}

storage:
  encryption_passphrase: null
  compression: auto,zstd
  archive_name_format: "{hostname}-{now}"

Die Verzeichnisse /volumes, /compose und /db_dumps sind Container-Pfade und werden über Docker-Volumes auf Host-Verzeichnisse gemappt. Weitere Host-Pfade einbinden:

  1. Im docker-compose.yml den Host-Pfad zusätzlich mounten, z. B.:
    services:
      borgmatic:
        volumes:
          - /home/user/important_data:/extra_data:ro
    
  2. In config/config.yaml den selben Container-Pfad aufnehmen (z. B. /extra_data).
  3. Optional: Den Pfad in .env als Variable pflegen, wenn du ihn konfigurierbar halten möchtest.

Damit landet das Verzeichnis sofort in den Backups.


Skripte

scripts/install.sh

  • prüft grundlegende Voraussetzungen
  • sorgt dafür, dass Verzeichnisse existieren
  • startet docker compose up -d für den borgmatic-Service

scripts/run-backups.sh

  • läuft auf dem Host
  • führt scripts/host-pre-backup.sh aus, startet den Container (falls gestoppt) und stößt direkt einen Borgmatic-Lauf an
  • kann z. B. per Cron (0 3 * * * /pfad/zum/projekt/scripts/run-backups.sh) oder systemd-Timer eingeplant werden

scripts/test-backup.sh

  • führt einen Testlauf mit docker compose run --rm borgmatic borgmatic --list aus
  • kann bei Bedarf auf --dry-run angepasst werden.

scripts/post-restore.sh

  • erwartet den Projektnamen als Argument
  • startet den entsprechenden Compose-Stack neu:
    • docker compose -f compose/<projekt>/docker-compose.yml up -d

scripts/health.sh

  • einfacher Health-Check:
    • gibt OK auf STDOUT zurück
  • kann von Monitoring-Tools abgefragt werden.

Backup-Workflow

  1. scripts/host-pre-backup.sh (auf dem Host): erstellt DB-Dumps und Container-Inspect-Daten, legt alles unter ./db_dumps ab.
  2. Borgmatic-Container: packt /volumes, /compose und /db_dumps in ein Archiv, speichert im lokalen Repo (/repo) und überträgt in die Remote-Repos (${REMOTE_REPO1}, ${REMOTE_REPO2}).
  3. Cron im Container steuert den Zeitpunkt (Standard: 03:00 Uhr).

Schnellstart

git clone <dein-repo> borgmatic
cd borgmatic

cp .env.example .env
# .env bearbeiten (Remote-Repos, VOLUMES_PATH usw.)

# Optional: lokale Borg-Repositories initialisieren
# docker compose run --rm borgmatic borg init --encryption=repokey /repo

# Installation / Initialstart
bash scripts/install.sh

# Testlauf
bash scripts/test-backup.sh

Restore Guide

1. Archiv-Liste anzeigen

docker compose run --rm borgmatic borgmatic --list

Oder direkt mit borg im Container:

docker compose run --rm borgmatic borg list /repo

2. Archiv mounten

docker compose run --rm borgmatic borg mount /repo::<ARCHIVNAME> /mnt

Danach stehen die gesicherten Daten unter /mnt zur Verfügung.

3. Projektbezogene Wiederherstellung

Beispiel: Wiederherstellung des Projekts lychee

  1. Compose-Konfiguration zurückspielen:

    cp -a /mnt/compose/lychee ./compose/lychee
    
  2. Datenbank-Dumps zurückspielen:

    cp -a /mnt/db_dumps/lychee ./db_dumps/lychee
    
  3. Stack starten:

    docker compose -f compose/lychee/docker-compose.yml up -d
    
  4. Datenbank wiederherstellen (Beispiel):

    docker exec -i lychee_mariadb mysql -uUSER -pPASS DBNAME          < db_dumps/lychee/lychee_mariadb_YYYY-MM-DD.sql
    
  5. Post-Restore:

    bash scripts/post-restore.sh lychee
    

Analog kann so auch seafile oder nginx2-php-example wiederhergestellt werden.

4. Komplettes System wiederherstellen

Für ein komplettes System:

  1. Borg-Repository auf neuen Host kopieren
  2. Dieses Repository (borgmatic-Projekt) aus Git klonen
  3. LOCAL_REPO_PATH in .env auf den lokalen Borg-Repo-Pfad setzen
  4. Archiv mounten
  5. compose/, db_dumps/ und ggf. weitere Verzeichnisse zurückspielen
  6. Stacks mit docker compose up -d wieder hochfahren
  7. Datenbanken importieren

Health-Check

bash scripts/health.sh

Ausgabe:

OK

Dies kann in jedem Monitoring-System als einfacher Command-Check verwendet werden.


Hinweise und Anpassungen

  • Die hier vordefinierten Container-Namen für die Datenbanken:
    • seafile-mysql
    • nginx2-php-example-1
    • lychee_mariadb können in hooks/pre-backup.sh angepasst werden.
  • Weitere Projekte können durch zusätzliche Unterordner in db_dumps/ und compose/ ergänzt werden.
  • Zusätzliche Repositories können in config/config.yaml eingetragen werden.