Zum Inhalt

Beispielarbeiten · Texte & Doku

Runbook: Betriebsanleitung mit Befehlen, Erwartungswerten und Wiederherstellung

Für einen erfundenen Betrieb: ein Runbook für einen Demo-Dienst mit täglichen Prüfungen, jedem Befehl mit erwartetem Ergebnis, Sicherung samt Prüfung, Wiederherstellung und typischen Fehlerbildern. Ein mitgelieferter Prüfer weist ein vages Runbook ab.

Musterarbeit (Demo), kein Kundenauftrag. Gebaut als Probeaufgabe mit erfundenen Beispieldaten; die Prüfzahlen unten stammen aus dem automatischen Prüflauf und sind nicht geschönt.

Was gebaut wurde

  • Jeder Schritt mit Befehl und erwartetem Ergebnis
  • Sicherung mit Prüfung und Wiederherstellung
  • Fehlerbilder mit Ursache und Handgriff
  • Dienst und Betrieb erfunden

RUNBOOK.md herunterladen

Wie geprüft wurde

Automatischer Prüflauf vom 29.10.2026, aus dem Protokoll (Testdaten erfunden, Zahlen gemessen):

  • Demo-Runbook mit 8 Abschnitten, Befehlen mit Erwartungswert, taeglichem Backup samt Pruefung, Wiederherstellung und 5 Fehlerbildern
  • 9 Pruefungen, Gegenprobe faellt durch

Grenzen

Was diese Probe nicht abdeckt, steht hier, damit niemand mehr erwartet:

  • Befehle sind fuer Linux/systemd/nginx/SQLite gedacht; andere Umgebungen brauchen eine Anpassung
  • Wir fuehren nichts auf dem Server des Kunden aus ohne dessen Zugang; die Befehle sind nicht an einem Kundenserver getestet
  • Zugangsdaten stehen nie im Dokument

Das Runbook

# Runbook - Demo-Projekt Kornblume-Shop (erfunden)

Musterarbeit von GL Tools. Projekt, Server und Namen sind erfunden; <PLATZHALTER> setzt der Kunde ein.

## Ueberblick

- App: Python (gunicorn), Datenbank SQLite unter /var/lib/kornblume/shop.db, Reverse-Proxy nginx, Dienst `kornblume.service`
- Server: <SERVER-NAME>, Benutzer `deploy`, Code unter /srv/kornblume (Git, Branch main)
- Gesundheitspruefung: `curl -fsS https://<DOMAIN>/health` -> erwartet: `{"status":"ok"}`

## Start und Stopp

```
sudo systemctl start kornblume
sudo systemctl status kornblume --no-pager
sudo systemctl stop kornblume
```
Erwartet: `active (running)`; nach dem Stopp `inactive (dead)`. Logs: `journalctl -u kornblume -n 100 --no-pager`.

## Deploy

```
cd /srv/kornblume
git describe --tags
git fetch --tags && git checkout <TAG>
.venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py migrate
sudo systemctl restart kornblume
curl -fsS https://<DOMAIN>/health
```
Erwartet: Health-Antwort `ok`. Vorher immer ein Backup ziehen (Abschnitt Backup) und das bisherige Tag notieren (erste Zeile).

## Rollback

```
cd /srv/kornblume
git checkout <VORIGES-TAG>
sudo systemctl restart kornblume
curl -fsS https://<DOMAIN>/health
```
Erwartet: `ok`. Wurde migriert, zuerst die Datenbank aus dem Backup von vor dem Deploy zurueckspielen (Abschnitt Wiederherstellung).

## Backup

Taeglich 02:30 per cron, 14 Tage aufbewahren:
```
sqlite3 /var/lib/kornblume/shop.db ".backup '/var/backups/kornblume/shop-$(date +%F).db'"
find /var/backups/kornblume -name 'shop-*.db' -mtime +14 -delete
```
Pruefung (woechentlich): `sqlite3 /var/backups/kornblume/shop-$(date +%F).db "PRAGMA integrity_check;"` -> erwartet: `ok`.
Ein Backup, das nie zurueckgespielt wurde, gilt als ungeprueft: einmal im Monat die Wiederherstellung auf einer Kopie ueben.

## Wiederherstellung

```
sudo systemctl stop kornblume
cp /var/lib/kornblume/shop.db /var/lib/kornblume/shop.db.defekt
cp /var/backups/kornblume/shop-<DATUM>.db /var/lib/kornblume/shop.db
sudo systemctl start kornblume
sqlite3 /var/lib/kornblume/shop.db "SELECT count(*) FROM orders;"
```
Erwartet: die Zahl entspricht dem Stand des Backups; Health-Pruefung `ok`. Die defekte Datei bleibt als `.defekt` zur Analyse liegen.

## Fehlerbilder

| Symptom | Pruefen | Behebung |
|---|---|---|
| 502 Bad Gateway | `systemctl status kornblume`, `journalctl -u kornblume -n 50` | `sudo systemctl restart kornblume`; bei Absturzschleife Rollback |
| Seite sehr langsam | `uptime`, `df -h /`, `free -m` | Platte voll: `sudo journalctl --vacuum-time=7d`; Speicher knapp: Dienst neu starten |
| `database is locked` | `fuser /var/lib/kornblume/shop.db` | Haengenden Prozess beenden, Dienst neu starten, Ursache in den Logs suchen |
| Zertifikat abgelaufen | `openssl s_client -connect <DOMAIN>:443 -servername <DOMAIN>` | `sudo certbot renew`, dann `sudo systemctl reload nginx` |
| Migration schlaegt beim Deploy fehl | Ausgabe von `manage.py migrate` | Nicht wiederholen: Rollback und Datenbank aus dem Backup von vor dem Deploy |

## Kontakte und Eskalation

1. Betreiber: <NAME>, <TELEFON> (werktags 8-18 Uhr)
2. Hoster-Support: <HOSTER-TICKETSYSTEM>
3. Faellt der Shop laenger als 30 Minuten aus: Kunden auf der Startseite und ueber <KANAL> informieren.

So etwas für deinen Betrieb?

Beschreib kurz, was du brauchst. Du bekommst einen Festpreis, bevor ich anfange; ohne dein Ja passiert nichts.

Zur Werkstatt