Zum Inhalt springen

Upgrade

Ein Upgrade ist eine geänderte Zeile in der .env und ein docker compose up -d. Der Container migriert die Datenbank, bevor er Anfragen beantwortet, und /health sagt, wann er fertig ist.

Was gilt

  • Heinzel Pro folgt semantischer Versionierung. Patch- und Minor-Releases (2.67.0 auf 2.68.2) werden in place aktualisiert. Ein Major-Release nennt Handarbeit im Changelog.
  • Die Version steht in der .env. Das Image-Tag latest wird nie benutzt; ein pull kann kein Upgrade aus Versehen sein.
  • Migrationen sind additiv und idempotent und laufen beim Start, vor der ersten Antwort. Neue Einstellungen bekommen Vorgaben.
  • Ein Befehl, der während des Neustarts auf einem Server lief, läuft dort als Job weiter; das neue Release holt sein Ergebnis ab. Sessions machen weiter, wo sie waren.
  • Ein Release läuft neben seinem Vorgänger auf derselben Datenbank, von einem zum nächsten; das braucht der Weg ohne Unterbrechung unten.

Das normale Upgrade

Am Beispiel von 2.67.0 auf 2.68.2, auf einem Host nach der Installationsanleitung.

  1. Die Hinweise zur Zielversion lesen. Das Changelog eines Releases nennt, was sich für Benutzer ändert; ein Abschnitt „Upgrade auf x.y“ nennt, was vorher zu tun ist. Meistens nichts.

  2. Sichern. Die Datenbank und die .env, beides in ein Verzeichnis außerhalb des Hosts.

    $ cd /opt/heinzel-pro
    $ sudo docker compose exec -T db pg_dump -U heinzel -Fc heinzel_pro \
      > /var/backups/heinzel-pro/vor-2.68.2.dump
    $ sudo cp .env /var/backups/heinzel-pro/env-vor-2.68.2
  3. Die Version ändern.

    $ sudo sed -i 's/^HEINZEL_VERSION=.*/HEINZEL_VERSION=2.68.2/' .env
    $ grep HEINZEL_VERSION .env
  4. Das Image holen, bevor etwas stoppt. Gibt es die Version nicht, scheitert dieser Schritt, und nichts hat sich geändert.

    $ sudo docker compose pull app
  5. Die Leute warnen. Mit HEINZEL_OPS_TOKEN in der .env sagt Heinzel Pro jedem, der gerade arbeitet, dass ein Neustart kommt, und wartet auf eine ruhige Minute. Siehe Neustart ankündigen. Ohne Token entfällt der Schritt; dann sind es etwa dreißig Sekunden, in denen keine Seite antwortet, und wer tippt, verliert seine halbe Nachricht.

  6. Neu starten.

    $ sudo docker compose up -d
  7. Prüfen. Erst dann ist das Upgrade fertig.

    $ curl -s http://127.0.0.1:4000/health
    {"database":"ok","pending_migrations":0,"rules_version":"3.3.1","status":"ok","version":"2.68.2"}

    Die Version ist die neue, pending_migrations ist 0. In der Anwendung steht sie unter Installation, Protokoll und rechts unten auf jeder Seite.

  8. Aufräumen. Das vorige Image bleibt für einen Schritt zurück; ältere können weg.

    $ sudo docker image ls ghcr.io/wintermeyer/heinzel-pro
    $ sudo docker image rm ghcr.io/wintermeyer/heinzel-pro:2.66.0

Neustart ankündigen

Ein Neustart unterbricht, wer gerade arbeitet. POST /ops/drain mit einer Frist in Sekunden (höchstens 900) und einem Grund sagt es allen: Jede offene Seite zeigt ein Banner mit dem spätesten Zeitpunkt, und Heinzel wartet auf eine ruhige Minute, in der keine Session mitten in einem Schritt ist, niemand tippt und kein Zeitplan fällig ist. Dann zählt das Banner eine halbe Minute herunter, in der nichts Neues startet, und GET /ops/drain meldet ready. Ist keine Seite offen und läuft nichts, kommt ready sofort.

Die Adresse antwortet nur dem Host selbst: über die Loopback-Adresse, mit Authorization: Bearer <HEINZEL_OPS_TOKEN> und ohne Forwarding-Header. Von außen bekommt sie ein 404, und der Proxy aus der Installationsanleitung lässt sie gar nicht erst durch. Aus dem Container heraus:

# Ankündigen: spätestens in zehn Minuten, Grund fürs Banner
$ sudo docker compose exec app sh -c '
  curl -s -X POST -H "Authorization: Bearer $HEINZEL_OPS_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"in\": 600, \"reason\": \"Upgrade auf 2.68.2\"}" \
    http://127.0.0.1:4000/ops/drain'
{"deadline":"2026-10-25T10:12:00Z","people":2,"ready":false,"running_sessions":1,…}

# Nachfragen, bis ready true ist
$ sudo docker compose exec app sh -c '
  curl -s -H "Authorization: Bearer $HEINZEL_OPS_TOKEN" http://127.0.0.1:4000/ops/drain'
{"deadline":"2026-10-25T10:12:00Z","people":0,"ready":true,"running_sessions":0,…}

# Zurücknehmen, wenn das Upgrade doch nicht stattfindet
$ sudo docker compose exec app sh -c '
  curl -s -X DELETE -H "Authorization: Bearer $HEINZEL_OPS_TOKEN" http://127.0.0.1:4000/ops/drain'

Ein Administrator der Installation kann die Ankündigung am Banner zurücknehmen oder den Countdown sofort starten. Das Release bringt in deploy/hosted/ das Skript heinzel-pro-drain mit, das fragt und wartet, und eine systemd-Unit, die es vor dem Herunterfahren des Hosts ausführt, etwa beim Reboot nach unattended-upgrades.

Ein Skript für alles

Die Schritte oben als Skript, das eine Version nimmt, das Image zuerst holt, die Leute warnt und erst dann neu startet, und das mit Fehler endet, wenn das neue Release nicht binnen zwei Minuten antwortet. Es ist eine gekürzte Fassung von deploy/hosted/deploy.sh aus dem Release.

#!/bin/sh
# upgrade.sh <version>: Heinzel Pro in /opt/heinzel-pro auf eine Version bringen.
set -eu
version=${1:?usage: upgrade.sh <version>}
cd /opt/heinzel-pro

printf '%s\n' "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' ||
  { echo "Keine Version: $version" >&2; exit 2; }

before=$(sed -n 's/^HEINZEL_VERSION=//p' .env)
sed -i "s/^HEINZEL_VERSION=.*/HEINZEL_VERSION=$version/" .env

# Zuerst holen: Für ein Image, das es nicht gibt, wird niemand gewarnt.
if ! docker compose pull app; then
  sed -i "s/^HEINZEL_VERSION=.*/HEINZEL_VERSION=$before/" .env
  echo "Das Image von $version ließ sich nicht holen; nichts geändert." >&2
  exit 1
fi

# Warnen und auf eine ruhige Minute warten, spätestens zehn Minuten.
drain() {
  docker compose exec -T app sh -c '
    curl -fsS -m 10 -X "$1" -H "Authorization: Bearer $HEINZEL_OPS_TOKEN" \
      -H "Content-Type: application/json" ${2:+-d "$2"} \
      http://127.0.0.1:4000/ops/drain' sh "$1" "${2:-}"
}
answer=$(drain POST "{\"in\": 600, \"reason\": \"Upgrade auf $version\"}") || answer=
deadline=$(( $(date +%s) + 630 ))
until case "$answer" in *'"ready":true'*) true ;; *) false ;; esac; do
  [ "$(date +%s)" -lt "$deadline" ] || break
  sleep 5
  answer=$(drain GET) || break
done

docker compose up -d

# Fertig ist es, wenn die neue Version antwortet und keine Migration aussteht.
for _ in $(seq 60); do
  health=$(docker compose exec -T app sh -c \
    'curl -fsS -m 5 http://127.0.0.1:4000/health' 2>/dev/null) || health=
  case "$health" in *"\"version\":\"$version\""*)
    case "$health" in *'"pending_migrations":0'*) echo "$health"; exit 0 ;; esac
  esac
  sleep 2
done
echo "Heinzel Pro $version kam binnen zwei Minuten nicht hoch." >&2
docker compose ps app >&2
exit 1
$ sudo sh upgrade.sh 2.68.2

Zurück

Ein Schritt zurück ist dieselbe Zeile mit der älteren Zahl und docker compose up -d. Hat das neue Release Migrationen mitgebracht, mit denen der alte Code nicht läuft, nehmen Sie diese zuerst zurück; das Changelog nennt den Zeitstempel:

$ sudo docker compose run --rm app bin/heinzel_pro eval \
  'HeinzelPro.Release.rollback(HeinzelPro.Repo, 20261011104222)'
$ sudo sed -i 's/^HEINZEL_VERSION=.*/HEINZEL_VERSION=2.67.0/' .env
$ sudo docker compose up -d

Die Alternative ist das Einspielen der Sicherung von vor dem Upgrade (siehe Betrieb, Wiederherstellen). Eine Migration, die sich nicht zurücknehmen lässt, sagt das im Changelog; dann ist die Sicherung der Weg.

Ohne Unterbrechung: zwei Slots

Ein Upgrade des einen Containers ist eine halbe Minute, in der keine Seite antwortet. Mit zwei Slots startet das neue Release neben dem alten, der Proxy schaltet um, sobald es gesund ist, und das alte stoppt, nachdem seine Leute gewarnt wurden. Im Release liegt in deploy/hosted/, was dazu gehört: docker-compose.slots.yml mit den Diensten blue und green im Netz des Hosts auf den Ports 4000 und 4001, nginx-upstream.conf und deploy-slots.sh, das die Schritte der Reihe nach ausführt.

Was das Skript tut:

  1. Das Image der neuen Version holen.
  2. Den freien Slot damit starten und warten, bis sein /health die neue Version mit pending_migrations 0 nennt. Die Migration läuft, während der alte Slot weiter bedient.
  3. Die Upstream-Zeile von nginx auf den neuen Slot schreiben und nginx neu laden. Neue Verbindungen landen beim neuen Release.
  4. Dem alten Slot den Neustart ankündigen und auf ready warten. Seine offenen Seiten verbinden sich neu, zum neuen Slot.
  5. Den alten Slot stoppen.

Zwei Releases teilen sich für diese Minuten die Datenbank. Drei Dinge halten sie auseinander, und dafür braucht die .env mehr:

VariableZweck
HEINZEL_NODE_IDName des Slots (blue, green). Eine Session wird von einem der beiden geführt; ein Slot, der stoppt, gibt seine Sessions zurück, einer, der abstürzt, verliert sie nach dreißig Sekunden an den anderen.
HEINZEL_NODE_ADDRESS, HEINZEL_CLUSTER_NODESEine Loopback-Adresse je Slot (127.0.0.1, 127.0.0.2) und beide Knoten, damit eine Seite auf dem neuen Slot sieht, was ein Runner auf dem alten tut.
HEINZEL_CLUSTER_COOKIEopenssl rand -hex 32, für beide gleich. Wer das Cookie kennt, führt im Knoten Code aus; deshalb startet ein Slot ohne eigenes Cookie nicht.
HEINZEL_LISTEN=loopbackIm Netz des Hosts würde das Release auf jeder Schnittstelle lauschen; so nur auf dem Host.
HEINZEL_DIST_PORTPort, über den die Knoten sprechen, Vorgabe 4370.

Die Compose-Datei der Slots setzt davon alles bis auf das Cookie und das Ops-Token. Zwei Grenzen: Die VPN-Ports lassen sich nur einmal binden, der neue Slot wartet, bis der alte sie freigibt, und ein Tunnel ist so lange unterbrochen. Und das Nebeneinander gilt von einem Release zum nächsten; wer Releases überspringt, macht ein Upgrade mit Stopp dazwischen.

Das Regelwerk, getrennt vom Release

Die Heinzel-Regeln sind Daten: Eine neue Regelversion braucht kein neues Image und keinen Neustart. Das Image bringt ein Regelwerk mit, und stündlich fragt die Installation beim öffentlichen Heinzel-Repository nach und übernimmt das neueste Release derselben Hauptversion. Eine neue Hauptversion wartet, bis ein Administrator der Installation sie unter Installation, Einstellungen, Regelwerk übernimmt, denn Hauptversionen verschieben Regeln zwischen Heinzel und Heinzel Pro.

Installation, Einstellungen, Regelwerk: die Version in Gebrauch, ihre Herkunft, seit wann, wie viele Sessions ein älteres Regelwerk lesen, der Haken für das automatische Update, ein Knopf, nach einer neueren Version zu sehen, der Upload eines Archivs und die Liste der aufbewahrten Regelwerke
Die Regelwerk-Seite: Version, automatisches Update, Upload für Installationen ohne Internet, und ein Klick zurück zu einer aufbewahrten Version.
  • Eine Session behält das Regelwerk, mit dem sie begonnen hat; ihr Menü bietet „Regeln neu laden“ an, sobald ein neueres gilt.
  • Ohne Internet laden Sie das .tar.gz eines Tags von github.com/wintermeyer/heinzel hoch. Es wird nur genommen, wenn es ist, was es sagt; nichts daraus wird ausgeführt.
  • Eine Version zurück ist ein Klick in der Liste; danach wird erst ein Release übernommen, das neuer ist als das verlassene.
  • HEINZEL_RULES_DIR steht über allem: ein eingehängtes Verzeichnis ist das Regelwerk, und die Seite bietet kein Update an.
  • Jedes Update und jeder Fehlschlag steht im Protokoll der Installation.

Wer von weiter her kommt

Einige ältere Schritte brauchten Handarbeit, und ihre Abschnitte stehen im Changelog. Die, über die man stolpert:

  • 2.10: Kein sudo-Passwort mehr. Vorher jedem Heinzel-Benutzer NOPASSWD geben oder root nehmen.
  • 2.24: HEINZEL_VERSION wird Pflicht; ohne die Zeile startet Compose nicht.
  • 2.29: Server haben keine Gruppe mehr; die CSV für den Import lautet hostname,port,user,description, und eine Richtliniendatei, die eine Gruppe nennt, wird abgelehnt, also neu exportieren.
  • 2.30: Die Anmeldung ist nach /auth/login gezogen; Monitore und Proxy-Regeln auf /users/log-in anpassen, die alten Adressen leiten weiter.
  • 2.51.1: entfernt zwei Spalten, die seit 2.50 niemand liest; ein Rollback geht danach bis 2.51.0, nicht weiter.

Ältere Schritte im Einzelnen

Die Abschnitte der Schritte, die Handarbeit brauchten, wie sie zu ihrer Zeit geschrieben wurden.

Upgrade auf 2.0 (Mandanten)

2.0 überführt alles, was eine Installation enthält, in einen Mandanten. Er heißt wie der Organisationsname aus den Einstellungen (oder „Default“). Im Alltag ändert sich nichts, bis ein zweiter Mandant angelegt wird.

  • Jeder Benutzer behält seine Rolle als Mitglied dieses Mandanten. Administratoren werden zusätzlich Administratoren der Installation; die Liste unter Installation, Konten prüfen, wenn nicht alle von ihnen Mandanten anlegen und Anmelderegeln ändern sollen.
  • Sitzungs-Timeout, Passwort-Anmeldung, Pflicht-2FA und Single Sign-on wandern von Allgemein in den neuen Reiter Anmeldung.
  • Anmeldungen werden ab jetzt für die Installation protokolliert. Das Audit-Protokoll eines Mandanten listet sie nicht mehr; die Administratoren der Installation sehen sie. Der Audit-Export nummeriert pro Mandant.
  • Die Anmeldeseite zeigt „Heinzel Pro“ statt des Organisationsnamens, der jetzt zu einem Mandanten gehört.
  • Alle werden einmal abgemeldet, weil das Sitzungs-Cookie jetzt verschlüsselt ist. „Angemeldet bleiben“ meldet von selbst wieder an.
  • Die beiden Migrationen (20261008094017, 20261008095012) schreiben jede Zeile der größeren Tabellen einmal um, unter einer Sperre: Es gibt eine Pause, die mit der Zahl der Nachrichten und Audit-Ereignisse wächst. Sie brauchen PostgreSQL 15 oder neuer (die Compose-Datei bringt 17 mit) und lassen sich nicht zurücknehmen. Vor dem Upgrade die Datenbank sichern und für den Weg zurück auf 1.x die Sicherung einspielen.

Upgrade auf 2.1 (mehrere Modellanbieter)

Das bisher konfigurierte Modell eines Mandanten wird sein erster Anbieter, der Standard, offen für alle Mitglieder und nach dem Modell benannt. Im Gebrauch ändert sich nichts, bis ein zweiter Anbieter dazukommt. Die Migration 20261008120857 verschiebt die Konfiguration aus den Einstellungen und lässt sich nicht zurücknehmen; vorher die Datenbank sichern. Die Migration 20261008122252 ergänzt Preise und Kosten. Sessions von vor dem Upgrade zeigen Modell und Tokens, aber keine Kosten.

Upgrade auf 2.3 (Autonomie-Stufen)

Aus den zwei Freigabemodi werden drei Stufen. „Immer fragen“ ist „Alles fragen“; „Lesebefehle automatisch“ ist „Lesen allein“, für den Mandanten und für jeden Server, bei dem das Häkchen gesetzt war. Die Obergrenze jedes Mandanten beginnt bei „Lesen allein“; nach dem Upgrade läuft also nichts, was vorher nicht lief. Ein Administrator der Installation hebt sie unter Mandanten an. Die Migration 20261008124115 lässt sich nicht zurücknehmen.

Upgrade auf 2.4 (Teilen)

Bestehende Sessions bleiben wie bisher für jedes Mitglied offen, zum Lesen und zum Schreiben, und die Vorgabe des Mandanten für neue steht auf demselben Wert. Sollen neue Sessions privat sein, unter Einstellungen, Allgemein ändern. Links für Menschen ohne Konto sind aus, bis ein Administrator sie erlaubt.

Upgrade auf 2.6 (Mandanten auf gemeinsamen Hosts)

In einer Installation mit einem Mandanten hinterlassen Server weiter Übergabenotizen im Systemjournal wie bisher. Mit mehreren Mandanten tut das kein Server, bis sein Mandant das Häkchen im Serverformular setzt. Auf Hosts bereits installierte Schlüssel behalten den Kommentar, mit dem sie installiert wurden; ein gemeinsamer Schlüssel von vor 2.6 trägt dort seinen Namen, bis er erneuert wird.

Upgrade auf 2.7 (Anbieter mit mehreren Modellen)

Jeder bestehende Modellanbieter wird zu einem Anbieter mit einem Modell, unter demselben Namen und mit demselben Schlüssel. Sollen mehrere Modelle unter einem Schlüssel stehen, den Anbieter öffnen, die weiteren ankreuzen und die dann doppelten Anbieter entfernen. Während ein Deploy umschaltet, kann das Release davor keinen Anbieter anlegen; alles andere läuft weiter.

Upgrade über 2.7 hinaus (eigene Proxys)

Die Adresse einer Anfrage kommt jetzt aus dem, was der eigene Reverse-Proxy meldet, nicht aus dem, was ein Client schickt. Hinter dem einen Proxy aus der Installationsanleitung ist nichts zu tun. Hinter zweien (Load-Balancer und Proxy) TRUSTED_PROXIES=2 setzen, sonst zählt das Anmelde-Limit jeden Besucher als den Load-Balancer. Das Zeitlimit, das der Agent für einen Befehl anfragen darf, steht auf 3600 s (Einstellungen, Richtlinie).

Jeder Mandant bleibt wie bisher auf UTC. Die Zeitzone wird unter Einstellungen, Allgemein gewählt; ab dann ist „0 9 *“ eines Zeitplans dort neun Uhr morgens. Prüfen Sie danach die Zeiten bestehender Zeitpläne.

Konten, die die Zwei-Faktor-Anmeldung schon nutzen, haben noch keine Recovery-Codes. Jede Person erzeugt sie einmal unter Konto, „Neue Recovery-Codes“.

Die Migrationen dieses Schritts legen Tabellen und Spalten an und schreiben keine bestehende Zeile um; sie laufen in Augenblicken. Was Sie danach sehen:

  • Sessions, Durchsicht listet jede beendete Session, in der ein ändernder Befehl ohne Freigabe lief, auch ältere, bis jemand Unbeteiligtes sie zeichnet. Das Dashboard zählt sie.
  • Die Freigaben-Seite zeigt, was geplante Läufe in der letzten Woche übersprungen haben.
  • Die zweite Freigabe eines unumkehrbaren Befehls verlangt eine Anmeldung, die höchstens fünf Minuten alt ist.
  • Die Server-Liste zeigt System, Platte und Laufzeit eines Hosts nach seinem nächsten Verbindungstest.
  • Vier Benachrichtigungs-Ereignisse sind neu und aus: eine zu lange wartende Freigabe, erhöhte Autonomie auf einem Server, das Modellbudget bei 80 %, die Wochenmail. Schalten Sie unter Einstellungen, Alarme ein, was Sie wollen.
  • Kein Server hat Wartungsfenster, kein Mandant ein Budget, eine Sperrliste oder Dauerfreigaben, bis Sie sie setzen.

Upgrade auf 2.9 (VPN-Verbindungen)

Das Image bringt die Helfer wireproxy, tailscaled und tailscale mit. Damit sich die Seite eines Mandanten einwählen kann, braucht die Installation offene UDP-Ports: Die Zeile unter ports aus der neuen docker-compose.yml in die eigene übernehmen, mit ss -lun prüfen, dass auf dem Host nichts auf 51900 bis 51919/udp lauscht (sonst startet der Container nicht), und den Bereich in der Firewall des Hosts öffnen, siehe installation.md. Ohne das bleibt eine solche Verbindung bei „wartet auf die Gegenseite“. Verbindungen, die Heinzel Pro selbst aufbaut, und solche in ein Tailscale-Netz brauchen nur den Weg nach außen. Die Migrationen legen eine Tabelle und eine Spalte an und schreiben keine bestehende Zeile um.

Upgrade auf 2.10 (kein sudo-Passwort)

Heinzel Pro hinterlegt kein sudo-Passwort mehr für einen Host. Geben Sie vor dem Upgrade Heinzels Benutzer auf jedem Host, für den im Serverformular eines eingetragen war, sudo ohne Passwort (NOPASSWD), oder lassen Sie Heinzel sich dort als root anmelden. Sonst scheitern Befehle mit sudo auf diesen Hosts nach dem Upgrade.

Die Migration (20261010152508) entfernt die Spalte und mit ihr die hinterlegten Passwörter. Ein Rollback bringt die Spalte leer zurück.

Upgrade auf 2.17 (Sessions in der Datenbank)

Die Tabellen und Spalten einer Session heißen nach ihr: aus conversations wird sessions, aus conversation_id wird session_id. Die Migration (20261010185251) benennt nur um, dauert also bei jeder Größe einen Augenblick, und ein Rollback benennt zurück. Die Rechte Ihrer Leute und die wartenden Jobs ziehen mit.

Drei Namen ändern sich dort, wo etwas von außen sie liest. Der Alarm-Webhook schickt zu einem Befehl session_id. Eine Richtliniendatei nennt die Einstellung session_sharing; eine vor dem Upgrade exportierte Datei lässt sie beim Import unberührt, exportieren Sie also neu. Und eigene Abfragen gegen die Datenbank brauchen die neuen Namen. Das Audit-Protokoll und sein Export behalten ihre (conversation.created, conversation_id): Was geschrieben wurde, bleibt, wie es geschrieben wurde.

Upgrade auf 2.18 (der Mandant in der Adresse)

Jede Adresse in einem Mandanten beginnt mit dessen Kürzel: /acme/sessions/…, wo vorher /sessions/… stand. Alte Adressen funktionieren weiter. Ein Lesezeichen oder ein Link aus einer älteren Mail führt in den Mandanten, den sein ?tenant= nennt, sonst in den, in dem in diesem Browser zuletzt gearbeitet wurde. Die API unter /api/v1/:tenant und der Alarm-Webhook bleiben, wie sie sind.

Ein Kürzel, das wie eine Seite der Anwendung heißt (servers, users, settings, api und ähnliche), würde für diese Seite gehalten. Die Migration (20261010192513) hängt an ein solches Kürzel -2 an; der Name des Mandanten bleibt. Trifft das einen Ihrer Mandanten, ändern sich seine API-Adresse und seine Webhook-Adresse mit. Sehen Sie nach dem Upgrade unter Mandanten nach.

Upgrade auf 2.20 (Neustarts, die niemand bemerkt)

Ein Befehl, der etwas ändert, läuft jetzt als Job auf seinem Host, in ~/.heinzel/jobs/<Befehls-ID> des Kontos, unter dem er läuft. Nach einem Neustart von Heinzel Pro wird er mit echtem Exit-Code und echter Ausgabe wieder abgeholt. Vor dem Upgrade ist nichts zu tun; die Migration (20261011104222) ergänzt fünf Spalten in commands. Der Host braucht sh und nohup und ein Home-Verzeichnis, in das das Konto schreiben darf; wo es keines gibt, läuft der Befehl wie bisher im SSH-Kanal. Siehe security.md, „Was auf einem Host liegen bleibt“.

Ein Befehl, der während dieses einen Upgrades läuft, wurde noch vom alten Release im Kanal gestartet und wird danach weiterhin als „unterbrochen, Ergebnis unbekannt“ gemeldet. Ab dem nächsten Neustart nicht mehr.

Von der Ausgabe eines Jobs bleiben 40.000 Bytes je Strom erhalten, von einer längeren die ersten 30.000 und die letzten 8.000.

Das Regelwerk zieht in die Datenbank (rule_bundles, Migration 20261011112537); das aus dem Image wird beim ersten Start gespeichert und gilt weiter. Siehe „Regelwerk“ unten.

Ein Neustart lässt sich den Leuten, die gerade arbeiten, vorher ankündigen. Setzen Sie HEINZEL_OPS_TOKEN in der .env und rufen Sie deploy/hosted/heinzel-pro-drain auf, bevor Sie den Container stoppen; siehe installation.md, „Neustart ankündigen“. Ohne das Token ändert sich nichts.

Upgrade auf 2.23 (kein Budget, keine Ortsvorgabe, kein Kundenportal)

Zwei Einstellungen sind weg, und was sie zurückhielten, läuft nach dem Upgrade.

Ein Mandant, der verlangte, dass seine Prompts in der EU oder im eigenen Netz verarbeitet werden, ist daran nicht mehr gebunden: Jeder Anbieter, der eingeschaltet und für eine Person offen ist, lässt sich wieder wählen. Sehen Sie vor dem Upgrade unter Einstellungen, Allgemein nach „Wo Prompts dieses Mandanten verarbeitet werden dürfen“. Wo dort nicht „überall“ steht, schalten Sie die Modelle aus, die nicht genutzt werden dürfen, oder beschränken Sie sie auf die Personen, die es dürfen.

Ein Mandant mit Monatsbudget wird bei 100 % nicht mehr angehalten und bei 80 % nicht mehr gewarnt. Die Ausgaben werden weiter gezählt und stehen im Monatsbericht.

An der Datenbank ist nichts zu tun: Die Spalten bleiben in diesem Release, und das Release davor läuft neben diesem. Eine früher exportierte Richtliniendatei wird gelesen wie bisher; die Vorgabe darin wird nicht angewendet.

Das Kundenportal ist weg, mit der Rolle „Kunde (nur Portal)“. Wer sie hatte, bleibt Mitglied mit der Rolle „Nichts von sich aus“ und ohne Einzelrechte: Die Person kann sich anmelden und darf nichts. Geben Sie ihr unter Benutzer eine Rolle oder entfernen Sie sie.

Die Einstellungen sind in Seiten aufgeteilt. Was unter Allgemein stand, steht jetzt unter Allgemein, Richtlinie, Befehle und Richtlinie als Datei; Alarme aus dem Monitoring, die Markierungen in seinen Graphen und der Versand des Audit-Protokolls sind von Alarme nach Anbindungen gezogen.

Upgrade auf 2.24 (die Version wird genannt)

docker-compose.yml nimmt nicht mehr das Image-Tag latest, wenn nichts angegeben ist. Bevor Sie die neue Compose-Datei übernehmen, muss in .env die Zeile HEINZEL_VERSION=2.24.0 stehen; ohne sie startet Compose nicht und nennt die fehlende Zeile. Wer die Variable immer gesetzt hat, ändert die Zahl und sonst nichts.

Dieses Release hat keine Migration. Es läuft also neben 2.23, und ein Schritt zurück braucht nur die ältere Zahl.

Womit sich Ihre Installation verbindet, ändert sich nicht. Der Sicherheitsleitfaden listet jetzt jedes Ziel auf („Was die Installation verlässt“). Die Ablehnung von Adressen, die zur Installation selbst zurückführen, gilt nur mit HEINZEL_HOSTED=true, und das setzt eine Installation im eigenen Rechenzentrum nicht.

Upgrade auf 2.28 (Übergabenotizen)

Ein Server, der bisher Übergabenotizen bekam, bekommt und liest sie weiter; Schreiben und Lesen sind jetzt zwei Häkchen im Serverformular. Die Zeile setzt von hier an Heinzel Pro zusammen und nicht mehr das Modell, in der Form [Name/Konto] Satz statt [Name as Konto] Satz — because Grund. Wer das Journal auswertet, passt sein Muster an. Vorgabe ist der Name der Person, ausführlich, nur bei Änderungen, in der Sprache der Systemmails und ohne Link (ab 2.28.3 mit Link); ändern unter Einstellungen, Richtlinie.

Upgrade auf 2.29 (Server ohne Gruppen)

Ein Server hat keine Gruppe mehr. Was entscheidet, was geschehen darf, geht dabei nicht verloren: Aus einer Sperrregel und einer Dauerfreigabe für eine Gruppe wird je eine für jeden Server, der darin war, und wem die Server einer Gruppe gezeigt wurden, dem werden diese Server namentlich gezeigt. Ein später angelegter Server gehört nicht dazu; er wird nach Name oder Tag gewählt. Eine verwaltete Datei, die für eine Gruppe eingetragen war, gilt von hier an auf jedem Server.

Drei Dinge ändern sich nach außen. Die API nimmt kein group_name mehr und gibt kein group mehr zurück. Die CSV für den Serverimport lautet hostname,port,user,description: Steht in der vierten Spalte noch die Gruppe, wird sie als Beschreibung gelesen. Und eine Richtliniendatei, die eine Gruppe nennt, wird als Ganzes abgelehnt, also neu exportieren.

Upgrade auf 2.30 (Adressen und ein Recht)

Die Anmeldung ist von /users/log-in und /users/register nach /auth/login und /auth/register gezogen, das eigene Konto nach /account, und drei Reiter der Einstellungen heißen in der Adresse wie ihre Seite. Die alten Adressen leiten weiter, auch der Anmeldelink in einer Mail von vor dem Upgrade. Die Adresse, die bei Ihrem Identity-Provider eingetragen ist, /auth/oidc/callback, bleibt dieselbe. Eine Proxy-Regel oder ein Monitor für /users/log-in sollte /auth/login nennen.

Der Freigabemodus, die zweite Freigabe und die übrigen Einstellungen der Richtlinie verlangen jetzt das Recht, festzulegen, was Heinzel zurückhält, auf der Einstellungsseite wie in der Richtliniendatei. Ein Administrator, dem dieses Recht genommen wurde, kann sie dort nicht mehr ändern; geben Sie es zurück, wo das nicht gemeint war.

Upgrade auf 2.35 (Administratoren der Installation bleiben draußen)

Ein Administrator der Installation betritt nicht mehr jeden Mandanten als Administrator. Ab dieser Version betritt er die Mandanten, in denen er Mitglied ist, mit der Rolle, die er dort hat. Wer in keinem Mitglied war, wird beim Upgrade Administrator des ältesten Mandanten, damit die Seiten der Installation erreichbar bleiben; alle anderen Mandanten, die er bisher öffnen konnte, sind für ihn zu, bis ihre Administratoren ihn einladen. Die Seite Mandanten zeigt, wer jeweils Administrator ist.

Zum Start werden vier Tarife angelegt (Friends & Family, Team, Business, Enterprise). Sie ändern keinen bestehenden Mandanten; bearbeiten oder entfernen lassen sie sich unter Installation, Tarife.

Upgrade auf 2.36 (die eigenen Seiten der Installation)

Mandanten, Tarife und Mailversand sowie die Reiter Anmeldung, Lizenz und Regelwerk der Einstellungen verlassen den Mandanten: Sie liegen unter /installation, hinter dem Eintrag Installation unten in der Navigation, und stehen allein den Administratoren der Installation offen. Lesezeichen auf die alten Adressen führen weiter. Zwei Seiten sind dort neu: Konten, mit allen, die sich anmelden können, und ihren Mandanten, und Protokoll, mit der eigenen Audit-Kette der Installation und ob die Installation läuft. Das Audit-Protokoll eines Mandanten zeigt von nun an allein die Kette des Mandanten; der Export der Installation ist nach Installation, Protokoll gewandert. Ein Administrator der Installation ohne Mandanten öffnet die Installation von der Seite aus, die ihm das sagt.

Upgrade auf 2.51.1 (Zugänge statt Benutzer am Server)

Seit 2.50 meldet sich Heinzel über die Zugänge eines Servers an (server_logins). 2.51.1 entfernt die Spalten ssh_user und sudo der Tabelle servers, die seit 2.51.0 niemand mehr liest. Ein Rollback geht danach bis 2.51.0 zurück, nicht weiter: 2.50 liest beide Spalten noch und scheitert an jedem Server, ein Release vor 2.50 kennt keine Zugänge. Die Migration lässt sich nicht zurücknehmen; stattdessen die Sicherung von vor dem Upgrade einspielen.