{% extends 'admin/shell.html.twig' %} {% set nav = 'system' %} {% block title %}System{% endblock %} {% block scripts %}{% endblock %} {% block heading %}System und Update{% endblock %} {% block lead %}Fassung, Updateweg und Sicherungen dieser Installation.{% endblock %} {% block content %}

Diese Installation

{{ state.maintenance ? 'Wartungszustand eingeschaltet' : 'im Betrieb' }}
Fassung
{{ state.version }}
Verwaltung
/{{ adminPath }} {% if adminPath == 'admin' %} – Standardpfad, den jeder Scanner zuerst probiert. Ändern: php bin/console cms:admin:path <neu>. {% else %} – geändert; steht in keiner öffentlichen Datei. Zurück: 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. SQLite braucht Schreibrechte auf die Datei und auf den Ordner darüber – nach einem FTP-Upload gehört sie dem FTP-Benutzer.{% endif %} {% else %} {{ database.adresse }} {% endif %}
Eingestellt in {{ database.quelle }}; Server-Umgebungsvariablen haben Vorrang.
Adresse
{% if origin.adresse %}{{ origin.adresse }}{% else %}Nicht eingetragen.{% endif %} {% if origin.passt %} – Canonical, Sitemap und Feed nennen sie; die Schreibweise {{ origin.adresse matches '{^https?://www\.}' ? 'ohne' : 'mit' }} www leitet hierher um. {% else %}
Diese Verwaltung läuft gerade unter {{ origin.host }}. Canonical, Sitemap und Feed nennen trotzdem die eingetragene Adresse. Stimmt die nicht mehr, unten ändern. {% endif %} {% if origin.quelle == '.env' %} {# Wie „WordPress-Adresse“: eine Stelle für mit oder ohne www. Vor dem Speichern fragt die Installation sich selbst unter der neuen Adresse an. #} {% set host = origin.adresse|split('://')|last|split(':')|first %} {% set twin = host starts with 'www.' ? host|slice(4) : 'www.' ~ host %}
{% if originRejected %} {% endif %}

Nur Schema und Domain. Vor dem Speichern wird geprüft, ob die Website unter der neuen Adresse antwortet – sonst leitete die andere Schreibweise ins Leere, die Verwaltung eingeschlossen.{% if origin.adresse and host matches '/^[a-z0-9-]+(\.[a-z0-9-]+)+$/' and not (host matches '/^[0-9.]+$/') %} Umstellen auf .{% endif %}

{% else %}
Eingestellt in der Server-Umgebung; sie hat Vorrang vor .env und lässt sich nur beim Hoster ändern. {% endif %}
{% if state.worktree %}
Stand
{{ state.describe }}{% if state.commit != 'unbekannt' %} · Commit {{ state.commit }}{% endif %}
{% else %}
Eingerichtet über
Releasearchiv – kein Git; Updates laufen über die Karte 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

{{ checks|length }} Bedingungen
{% 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 – typisch nach einem Update von Hand über FTP.

Vorher sichern: Migrationen sind nicht umkehrbar, der Rückweg ist die Sicherung.

{% endif %} {# Update mit einem Klick (ADR 113), nach dem Vorbild von reiseSoft: Beim Öffnen fragt die Seite selbst nach einer neuen Fassung, zeigt die Hinweise dazu und einen Knopf. Danach laufen die Schritte sichtbar durch - bis „abgeschlossen“ oder „zurückgeschaltet“. Ohne Skript bleiben die Formulare darunter. #}

Update

Installiert {{ state.version }}
{% 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.

{% endif %}
Weitere Möglichkeiten

Ohne Git: Archiv laden, Prüfsumme vergleichen, Datenbank und Medien sichern, Wartungsseite an, Dateien tauschen, Datenbank anpassen, prüfen. Unberührt bleiben var/, .env, die geladenen Schriften und das erzeugte Stylesheet-Bündel.

Leer lassen für die neueste veröffentlichte Fassung. Dieser Weg funktioniert auch ohne JavaScript.

Auf aktualisieren?

Vorher werden Datenbank und Medien automatisch gesichert. Die Website zeigt etwa eine Minute lang eine Wartungsseite. Schlägt etwas fehl, wird automatisch auf {{ state.version }} zurückgeschaltet.

{% if state.worktree %}

Update einspielen

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

Sichern, Wartungszustand ein, auf den Tag wechseln, Abhängigkeiten, Migrationen, Cache, Antwortprüfung. Scheitert ein Schritt, wird zurückgesetzt – die Datenbank nur, wenn die Migration schon begonnen hatte.

Zwei Hinweise vorab

Der Medienordner wird nicht gesichert. Ein Update ist keine Datensicherung.

Bricht der Browseraufruf auf dem Hosting ab: php bin/console cms:update – 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.

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

Letzter Durchlauf

{{ steps|length }} Schritte
    {% 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 %}

Inhalte übertragen

Export und Import · var/pakete

Ein Inhaltspaket enthält Seiten mit allen Fassungen, Bereiche, Menüs, Medien und PDFs, Formulare, Weiterleitungen, Kategorien, Übersetzungen, Design und Einstellungen. Nicht darin: Anfragen, Statistik, Zugangsdaten zu Diensten (Turnstile) und – ohne Häkchen – die Konten.

Exportieren

Nur nötig, wenn die andere Website noch kein Konto hat. Das Paket enthält dann die Passwort-Hashes – nicht weitergeben.

Importieren

Höchstens {{ uploadLimit }} je Upload (Einstellung des Hostings). Größere Pakete per FTP nach var/pakete/ legen, dann erscheinen sie hier zur Auswahl.

{% if packages is not empty %}
Oder ein Paket aus var/pakete/ {% for package in packages %} {% endfor %}
{% endif %}

Ohne Häkchen bleiben Benutzer und Passwörter dieser Website, wie sie sind.

Vorher wird automatisch eine Sicherung angelegt; während des Imports antwortet die Website mit der Wartungsseite.

Sicherungen

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

Eine Sicherung enthält die Datenbank als vollständige Kopie und den Medienordner – nicht .env, vendor/ und den Quellcode.

Zurückspielen nur auf der Konsole: php bin/console cms:restore <name>. Die tägliche Sicherung erledigt der Aufgabenplan.

{% 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 stimmt noch. 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 %} {# Zwanzig Protokollzeilen sind auf einem Handy zwanzig Absätze. Die jüngsten fünf stehen offen, der Rest liegt eine Umdrehung dahinter. #} {% if state.log|length > 5 %}
Ältere Einträge ({{ state.log|length - 5 }})
    {% for line in state.log|slice(5) %}
  • {{ line }}
  • {% endfor %}
{% endif %} {% endif %}

KantSites · Arbeitsstand

{% endblock %}