Skip to main content
Home
Schatzchaeschtli 2026

Main navigation

  • Home
User account menu
  • Log in

Breadcrumb

  1. Home

Protokoll Update Drupal 10 > 11 (hbmhealthcare)

By PierreAdmin , 28 October 2026

Detailliertes Protokoll der Schritte zum Update von hbmhealthcare von Drupal 10.6 auf Drupal 11.4. Zuerst auf local das Upate durchführen und dann zum testen auf stage und live überspielen.

Voraussetzungen für Drupal 11

Drupal entwickelt aktuell zwei Hauptversionen parallel weiter. Drupal 10.6 ist im gleichen Zeitraum wie Drupal 11.3 erschienen und enthält bereits Datenbank-Änderungen, die es in Drupal 11 erst ab 11.3 gibt. Ein Sprung von 10.6 auf z.B. 11.2 wäre darum ein Rückschritt: Die Datenbank wäre schon weiter als der Code, und die Update-Kette würde nicht passen. Deshalb sperrt Drupal diese Kombination.

  • MariaDB ≥ 10.6
  • PHP 8.3

Lokal vorbereiten

  • Live-DB auf local einspielen.
  • Upgrade Status enablen (Contrib Module)

1 -- Upgrade Status

  • Upgrade Status aufrufen: Reports > Upgrade Status.
    Die Seite zeigte 90 % kompatibilität an. 
    • Update: 3 Module, zu denen es aber Drupal 11 kompatible Updates gibt. 
    • Scan: hbm Theme und hbmcustom Modul wird als inkompatibel angezeigt und sollte gescannt werden. Ein Scan gibt in der Regel gute und weiterführende Infos über die Issues aus.

1.1 -- Updates

  • Flood control
    Version 3 für Drupal 11 verfügbar, Update läuft problemlos.
  • jQuery UI Datepicker: wurde nirgends benutzt (Wahrscheinlich ein Überbleibsel aus Drupal 8)
    Zuerst deinstalliert, dann aus Composer entfernt.
  • Seven bleibt bis zum Redesign und Rlaunch das Backendtheme, damit das Backend sich nicht ändert (Standard wäre bei Drupal 11 Claro. Die aktuellste Beta braucht Drupal 11.3, darum können wir hier das Update erst nach dem Core Update machen.

2 -- Core-Update

  • grep -n "drupal/core" composer.json
    • grep sucht in einer Datei nach einem Text, -n zeigt die Zeilennummer dazu. 
      Hier: «Zeig mir alle Zeilen in der composer.json, in denen drupal/core vorkommt.» 
      Ergebnis waren drei Pakete mit ihrer Version ^10:

      • drupal/core: der Drupal-Kern
      • drupal/core-composer-scaffold: kopiert index.php, .htaccess usw. an ihren Platz
      • drupal/core-dev: Entwickler-Werkzeuge (nur lokal)
    • Das war reine Vorbereitung: Wir mussten wissen, welche Core-Pakete das Projekt hat, bevor wir den Befehl schreiben. Bei neueren Projekten heisst das Hauptpaket z.B. drupal/core-recommended.

  • composer require drupal/core:^11.3 drupal/core-composer-scaffold:^11.3 --no-update
  • composer require --dev drupal/core-dev:^11.3 --no-update
    • composer require trägt in der composer.json ein, welche Version man will, hier ^11.3 statt ^10. Mit --no-update ändert Composer nur die Datei composer.json, lädt aber noch nichts herunter.

    • Warum? Würde Composer sofort nach dem ersten Paket loslegen, hätte es Core 11 mit core-dev 10 kombinieren müssen, und das passt nicht zusammen. Also zuerst bei allen drei die Wunschversion eintragen, dann alle gemeinsam aktualisieren.
    • --dev beim zweiten Befehl, weil core-dev im Entwickler-Bereich der composer.json steht.

  • composer update drupal/core drupal/core-composer-scaffold drupal/core-dev --with-all-dependencies --dry-run
    • Die Liste der Pakete sagt: nur diese dürfen sich ändern.
    • --with-all-dependencies erlaubt zusätzlich, alles mitzuziehen, was diese Pakete brauchen (Symfony, Twig usw.).
    • --dry-run: Sollte eigentlich immer vor einem solchen Schritt durchgeführt werden. Die Installation wird durchgespielt, ohne aber irgend etwas zu ändern.

    • Stolperstein: symfony/console 7.4 blockiert. Schuld war ein Hilfspaket von Drush. Lösung: drush/drush mit ins Update nehmen.

      • Damit sucht Composer eine Kombination, die mit den neuen Wunschversionen funktioniert, lädt sie herunter und schreibt das Ergebnis in die composer.lock.

  • composer update drupal/core drupal/core-composer-scaffold drupal/core-dev drush/drush --with-all-dependencies
    • Frage nach symfony/runtime: mit y erlauben.

    • Core, Scaffold und core-dev gemeinsam auf ^11.3. Ergebnis: D11.4.11.

  • Drush updb
    Drush cr
    • Seven auf die neueste Beta updaten.
      Seven 2 zeigt bei Paragraphs neu den Reiter Behavior. Bei uns ohne Funktion, harmlos. Ist so wie ich das gelesen habe eher ein Bug in seven, da er eigentlich nicht angezeigt werden sollte, wenn ungenutzt.

3 -- Kontrolle

  • Backend und Frontend sauber durchchecken. Besonders Seiten mit Views und weiteren Funktionserweiterungen.
    • Teams, Portfolio: Feeds
    • News: Eigenes PHP Script und Aggregator
    • Homepage: Newsslider
    • Generell JS: Slider und animierte Grafiken
  • Inhalte erstellen, Daten uploaden, Bilder uploaden, Sprachumstellungen

3.1 -- Stolperstein: Filter Medienmitteilungen

  • Problem: 
    Bei den Medienmitteilungen zeigte «Ad hoc Button» nichts, «Corporate Button» alles (DE und EN). Die Buttons filtern per JavaScript nach einer Klasse, die das versteckte Feld «Title (News-Type)» in der View view_hbm_media_releases erzeugt.

  • Ursache:
    Im Rewrite Feld in der View:

    • {% if '##ADHOCSTART##' in title_1|render %}
    • Unter D11 (neueres Twig) liefert |render ein Markup-Objekt statt Text. in kann darin nicht suchen, also war die Prüfung immer falsch.

  • Lösung:
    |striptags ergänzen:

    • {% if '##ADHOCSTART##' in title_1|render|striptags %}
  • Weitere mögliche Problemstellen suchen:
    • grep -rn "in .*|render" config/sync web/themes/custom

3.2 -- Nachkontrolle local

  • Scaffold-Dateien prüfen/diffen
    .htaccess, robots.txt, index.php, update.php, development.services.yml, default.services.yml, default.settings.php
  • .htaccess: Schutz für package-lock.json, WebP-Dateityp, Statistics-Ausnahme entfernt (Modul nicht mehr im Core), Brotli-Regeln. Alles Standard.
  • robots.txt: avif/webp erlaubt, /web.config entfernt, /search? gesperrt. Nichts Eigenes verloren. Diff ohne Zeilenenden-Rauschen:
  • composer audit: 
    Damit werden alle Sicherheitsupdates angezeigt:
    • Rabbit Hole und Shield updates eingespielt.
  • web/.php-ini und web/.php-version aus dem Git genommen (legt Plesk an).
  • Status Report: nur Hinweise für D12 (Contact, History, HTML5 validation)
    • Wichtig: Nicht erschrecken. Nach Core Update wird hier natürlich schon auf Drupal 12 getestet.
  • Upgrade Status deinstallieren
  • Final config exportieren, committen und alles auf Gitlab pushen 
  • drush cex
    git commit
    git push

4 -- Update auf stage schieben

  • Live-DB auf stage einspielen.
  • Schreibschutz für settings entfernen:
    • chmod 755 web/sites/default
      chmod 644 web/sites/default/settings.php
  • git status
    git fetch
    git pull
    • chmod 555 web/sites/default
      chmod 444 web/sites/default/settings.php
  • composer install --no-dev
  • drush updb
    • Stolperstein: fehlendes Modul jquery_ui_datepicker. Die DB kam von live, wo das Modul noch aktiv war, der Code war aber schon weg. Modul per Drush aus core.extension und key_value ausgetragen, dann lief updb.
  • drush cim
  • drush cr
  • Stolperstein: Drush startet nicht (open_basedir). Plesk hatte beim D10-Go-live im Home-Ordner .php-ini angelegt, die auf die php.ini der Domain zeigte. Lösung: ~/.php-ini auf /opt/plesk/php/8.3/etc/php.ini umgestellt, überflüssige Plesk-Dateien in den web-Ordnern gelöscht, usephp83 in der .bash_profile entfernt. Details im Artikel «PHP im Terminal: Plesk bei MVA vs. Metanet».

  • Fehlende Bilder und Dokumente von live per rsync (gugg hier) nachgezogen.

  • Getestet: Shield, Filter Medienmitteilungen, Seiten, Status Report. Alles gut.

5 -- Update auf LIVE

Die Live-DB bleibt, wir tauschen nur den Code im bestehenden httpdocs aus. Kein Ordner wird verschoben. Die Site ist nur wenige Minuten im Wartungsmodus.

  • DB-Backup:
    zuerst manuellen DB-Dumb speichern
  • Sicheheitskopie von httpdocs:
    Für den Fall der Fälle den alten Stand duplizieren in _backups/DATUM/
    DB sichern, dann httpdocs in den Backup-Ordner kopieren.
  • Externe Cronläufe deaktivieren (z.B. in Plesk) 
  • Altes Modul jquery_ui_datepicker deinstalliert
  • Wartungsmodus ein: drushh maint:set 1
  • default und settings.php beschreibbar machen
  • git status
    git fetch
    git pull
  • composer install --no-dev
  • drush updb
  • drush cim
  • drush cr
  • default und settings.php schützen
  • Wartungsmodus aus: drushh maint:set 0
  • Externe Cronläufe wieder einschalten
  • TESTEN!
    Seiten, Status Report, Filter Medienmitteilungen
  • Aktuellen Datenbank-Dump erstellen

Nebenbei aufgeräumt:

  • web/index.html: Plesk-Platzhalter vom D10-Go-live, gelöscht.
  • Alter D8-Cronjob für feeds_http_fetcher*: zeigte auf den nicht mehr existierenden Ordner sites/default/files/tmp. Feeds 3 räumt seine Zwischendateien selbst auf, der Job ist überflüssig.
  • Backup-and-Migrate-Leichen: 
    In private/tmp lagen rund 700 MB bam…-Dateien, die Rohdateien manueller Backups. Automatische Backups per Cron lassen keine liegen. Bekanntes Verhalten des Moduls. Lösung: den alten Cronjob umgebaut, er löscht jetzt täglich bam*-Dateien, die älter als 60 Minuten sind:
    • find /var/www/vhosts/hbmhealthcare.com/httpdocs/private/tmp -name "bam*" -mmin +60 -delete
  • To do:

    • .gitignore-Kommentar zu den Plesk-Dateien anpassen

    • alte hbmcustomFeed-Kopien aus dem Webroot entfernen

    • 95er-Backup zippen

    • Altlasten auf dem Server (test., dev., privat-hbm)

    • PHP 8.4 auf stage testen

    • Für D12/Relaunch: Contact, History, HTML5-Validierung, Seven > Claro, core-recommended.

  • drupal
  • update
  • upgrade
  • php-ini
  • php-version
Drupal

Tag Suche

Categories (Taxonomie-Menu)

  • Drupal
    • Module
    • Theming
    • Views
  • Webentwicklung
    • Composer
    • CSS/SCSS
    • Deployment
    • Drush
    • Git
    • HTML
    • JavaScript
    • PHP
    • SSH
    • SVG
    • VS Code
  • Datenbank
    • mySQL
  • Server
    • Apache
    • DNS
    • Domains
    • Plesk
    • SSL/TLS
  • System
    • Mac
    • Unix
    • Windows