{% extends 'admin/shell.html.twig' %} {% set nav = 'system' %} {% block title %}System{% endblock %} {% block heading %}System und Update{% endblock %} {% block lead %}Welche Fassung läuft, ob ein Update möglich ist, und der Weg dorthin: sichern, Wartungszustand, Dateien tauschen, migrieren.{% endblock %} {% block content %}

Diese Installation

{{ state.maintenance ? 'Wartungszustand eingeschaltet' : 'im Betrieb' }}
Fassung
{{ state.version }}
Adresse der Verwaltung
/{{ adminPath }} {% if adminPath == 'admin' %} – die Adresse, die jeder Scanner zuerst probiert. Ändern mit php bin/console cms:admin:path <neu>; sie steht danach in .env.local und in keiner öffentlichen Datei. {% else %} – geändert. Sie wird in der robots.txt nicht genannt; notiere sie dir an einem sicheren Ort. Zurück mit php bin/console cms:admin:path admin. {% endif %}
Datenbank
{{ database.art }} {% if database.datei %} {{ database.datei }} {% if database.bytes %}· {{ (database.bytes / 1048576)|number_format(1, ',', '.') }} MB{% endif %} {% if not database.schreibbar %}
Nicht beschreibbar. Nach einem Upload per FTP gehört die Datei dem FTP-Benutzer; PHP läuft als ein anderer. SQLite braucht Schreibrechte auf die Datei und auf den Ordner darüber.{% endif %} {% else %} {{ database.adresse }} {% endif %}
Eingestellt in {{ database.quelle }}. Die Installationskonfiguration steht in .env. Explizite Server-Umgebungsvariablen haben Vorrang.
{% if state.worktree %}
Stand
{{ state.describe }}{% if state.commit != 'unbekannt' %} · Commit {{ state.commit }}{% endif %}
{% else %}
Eingerichtet über
das Releasearchiv – kein Git in diesem Verzeichnis, und dafür ist es auch nicht gedacht. Updates laufen über die Karte weiter unten.
{% endif %} {% if state.worktree %}
Verfügbar
{% if available %} {{ available }}{% if available == 'v' ~ state.version %} – das ist die installierte Fassung.{% endif %} {% elseif asked %} Kein Tag der Form v1.2.3 in der Herkunft gefunden. {% else %} Beim Repository nachfragen {% endif %}
{% endif %}
{% if state.maintenance %} {% endif %}
{# Die Vorprüfung gehört zum Updateweg über Git: Arbeitsverzeichnis sauber, Datenbank außerhalb von Git, Tag erreichbar. Auf einer Installation aus dem Releasearchiv prüft sie Bedingungen, die dort keine sind - und zeigt lauter rote Ausrufezeichen für etwas, das vollkommen in Ordnung ist. #} {% if state.worktree %}

Vorprüfung

Jede Bedingung wird geprüft, nicht angenommen
{% endif %} {# Waehrend das Archiv-Update auf seinen zweiten Schritt wartet, gehoert der Knopf dorthin - zwei Knoepfe, die dasselbe tun, sind eine Frage zu viel. #} {% if pendingMigrations|default([]) and not archivePending %}

Migrationen stehen aus

{{ pendingMigrations|length }} Stück

Der Code ist neuer als die Datenbank. Das passiert, wenn ein Update von Hand über FTP eingespielt wurde – dann fehlt der Schritt, den sonst der Updater übernimmt.

Lege vorher eine Sicherung an: Migrationen sind nicht umkehrbar, der Rückweg ist die Sicherung.

{% endif %}

{{ state.worktree ? 'Update aus dem Releasearchiv' : 'Update einspielen' }}

{{ state.worktree ? 'Alternative zum Weg über Git' : 'holt die neue Fassung und tauscht die Dateien' }}
{% if archivePending %}

Die Dateien der Fassung {{ archivePending.fassung }} liegen bereits (seit {{ archivePending.seit|slice(0, 16)|replace({"T": " "}) }} UTC). Es fehlen noch die Migrationen – bis dahin bleibt die Website im Wartungszustand.

{% else %}

Dieser Weg braucht kein Git: Er lädt das Archiv der neuen Fassung von der Releaseseite, vergleicht die Prüfsumme, sichert Datenbank und Medien, schaltet den Wartungszustand ein und ersetzt die Dateien der Anwendung. Unberührt bleiben var/, .env, .env.local, die geladenen Schriften und das erzeugte Stylesheet-Bündel. Der vorherige Stand wird beiseitegelegt, nicht gelöscht.

Danach folgt ein zweiter Knopf für die Migrationen. Das ist kein Umweg: Erst eine neue Anfrage startet mit dem Code der neuen Fassung – ein Prozess, der sich selbst ausgetauscht hat, arbeitet mit dem alten weiter.

{% if archiveVersion %}

Verfügbar: {{ archiveVersion }} (installiert: {{ state.version }}).

{% elseif asked %}

Die Releaseseite nennt nichts Neueres als {{ state.version }}.

{% else %}

Nachsehen, ob es etwas Neues gibt – das fragt die Releaseseite und dauert einen Moment.

{% endif %}

Leer lassen für die neueste veröffentlichte Fassung.

{% endif %}
{% if state.worktree %}

Update einspielen

{{ ready ? 'Vorprüfung bestanden' : 'erst die Vorprüfung erfüllen' }}

Der Updater sichert zuerst Datenbank und Umgebungsdateien, schaltet den Wartungszustand ein, wechselt auf den Tag, installiert Abhängigkeiten, migriert, räumt den Cache und prüft, ob die Installation antwortet. Scheitert ein Schritt, wird auf den vorherigen Stand zurückgesetzt – und nur wenn die Migration schon begonnen hatte, auch die Datenbank zurückgeschrieben.

Der Medienordner wird nicht gesichert. Er ist zu groß, und kein Update schreibt darin. Ein Update ist keine Datensicherung.

Auf manchen Hostings bricht ein Browseraufruf nach kurzer Zeit ab. Dann ist php bin/console cms:update der verlässliche Weg – dort gibt es dieselben Schritte mit --check, --dry-run und --to=v1.2.0.

Leer lassen für den höchsten verfügbaren Tag.

Prüft alles und verändert nichts. Nimm das Häkchen weg, wenn es wirklich laufen soll.

{% endif %} {% if steps is not empty %}

Letzter Durchlauf

Schritt für Schritt
    {% for step in steps %}
  1. {# `step.label` ist die Schreibweise bis 1.4.4. Sie muss hier stehen bleiben: Beim Update von 1.4.4 auf 1.4.5 schreibt der **alte** Code die Schritte in die Sitzung und der **neue** zeigt sie an - eine Fassung, die nur die neue Schreibweise kennt, könnte das Update, das sie selbst einspielt, nicht berichten. #} {{ step.step|default(step.label|default('Schritt')) }} {{ step.detail }}
  2. {% endfor %}
{% endif %}

Sicherungen

{{ backups|length }} vorhanden · var/backups

Eine Sicherung enthält die Datenbank als vollständige Kopie – nicht als Dateikopie während des Schreibens, die unbrauchbar sein kann – und den Medienordner. Nicht enthalten sind .env, vendor/ und der Quellcode: die kommen aus dem Repository, und .env enthält das Geheimnis dieser Installation.

Zurückspielen geht bewusst nur auf der Konsole: php bin/console cms:restore <name>. Ein Knopf, der die ganze Datenbank ersetzt, gehört nicht neben einen, der eine Seite speichert. Die tägliche Sicherung erledigt der Aufgabenplan – auch ohne Cronjob.

{% if backups is not empty %} {% for backup in backups %} {% endfor %}
Vorhandene Sicherungen
NameErstelltFassungInhaltGrößeZustand
{{ backup.name }} {{ backup.manifest ? backup.manifest.erstellt|date('d.m.Y H:i') : '—' }}{% if backup.manifest %}
{{ backup.manifest.anlass }}{% endif %}
{{ backup.manifest ? backup.manifest.fassung : '—' }} {% if backup.manifest %}{{ backup.manifest.inhalt.seiten }} Seiten, {{ backup.manifest.medien.dateien }} Dateien{% else %}—{% endif %} {{ (backup.bytes / 1048576)|number_format(1, ',', '.') }} MB {% if backup.intact %}unversehrt{% else %}Prüfsumme falsch{% endif %}

„Unversehrt“ heißt: die Prüfsumme der gesicherten Datenbank stimmt noch mit dem Manifest überein. Stimmt sie nicht, wird die Sicherung nicht eingespielt.

{% endif %}

Verlauf

var/updates.log
{% if state.log is empty %}

Noch kein Update über diesen Weg eingespielt.

{% else %} {% endif %}

KantSites · Arbeitsstand

{% endblock %}