Change Management bei Server-Updates

Server-Updates laufen entweder nach Plan oder mitten in der Nacht als Notfall. Wer Change Management hat weiß vorher welche der beiden Varianten es wird.

Was Change Management für Server bedeutet

Nicht der Enterprise-Prozess mit wochenlangen Freigabe-Committees.
Für kleine Teams: vor jedem nicht-trivialen Eingriff kurz durchdenken was passiert, was schiefgehen kann, wie man zurückrollt.

Standard-Changes vs. normale Changes

Standard-Changes sind routinemäßige, gut verstandene Aktionen mit bekanntem Risiko.

- apt upgrade (security patches)  → Standard, kein Review
- Nginx-Konfiguration ändern       → Standard, vorher testen
- PHP-Version upgraden             → Normal Change, Planung nötig
- Datenbankschema ändern           → Normal Change, Backup vorher

Change-Protokoll führen

2025-05-26 23:00 — PHP 8.2 → 8.3 Upgrade
Grund: 8.2 EOL, Sicherheits-Updates enden
Vorbereitung: Lokales Testen auf Staging, composer audit ausgeführt
Rollback: php8.2-fpm reaktivieren, update-alternatives umschalten
Ergebnis: OK, keine Fehler

Eine einfache Textdatei oder ein privates Wiki reicht.

Wartungsfenster kommunizieren

Für Systeme mit Benutzern: geplante Wartung ankündigen.

// maintenance.php
$maintenanceUntil = new DateTime('2025-05-26 23:30:00');

if (new DateTime() < $maintenanceUntil) {
    http_response_code(503);
    header('Retry-After: ' . $maintenanceUntil->format('D, d M Y H:i:s \G\M\T'));
    include 'templates/maintenance.php';
    exit;
}

503 statt 200 damit Suchmaschinen keine kaputten Seiten indexieren.

Rollback-Plan

Vor jedem Update: wie macht man es rückgängig?

# Vor PHP-Upgrade: aktuellen Stand notieren
php -v
php -m | sort > /root/php-modules-before-upgrade.txt

# Nach Upgrade: vergleichen
php -m | sort > /root/php-modules-after-upgrade.txt
diff /root/php-modules-before-upgrade.txt /root/php-modules-after-upgrade.txt

Wenn etwas schiefgeht: was genau muss zurückgesetzt werden? Wer muss informiert werden?

Backup vor dem Change

Obligatorisch für alle Datenbankänderungen:

# Backup vor der Migration
mysqldump myapp | gzip > /backup/pre-migration-$(date +%Y%m%d_%H%M).sql.gz

Das dauert 30 Sekunden und hat schon viele schlimme Nächte verhindert.