Dolibarr über die Kommandozeile aktualisieren

Dolibarr ohne Web-Assistenten aktualisieren: upgrade.php, upgrade2.php und step5.php, ein Schritt pro Version, die upgrade.unlock-Falle, die Schritt 2 ohne Fehlermeldung blockiert, und ein vollständiges Skript mit Sicherung und Rücksprung, getestet von 22 bis 24.

Betroffene Versionen
Dolibarr 22.0.5, 23.0.4 und 24.0.1 auf 24.0.2 aktualisiert (offizielle .tgz-Archive) · Debian 13, PHP 8.4, MariaDB 11.8
Was geprüft wurde
Tests am 19.10.2026 auf Debian 13 (PHP 8.4.26, MariaDB 11.8.6) mit den offiziellen Archiven von SourceForge: Neuinstallationen von 22.0.5, 23.0.4 und 24.0.1 mit dem Web-Assistenten, mit einem Geschäftspartner, einer Rechnung, einem Anhang, einem API-Schlüssel und einem Ordner in custom/; die Befehle dieser Seite unter einem sudo-Konto ausgeführt; das Skript von allen drei Versionen aus gestartet; Migration in einem einzigen Aufruf, zweiter Schritt durch upgrade.unlock blockiert, Skripte aus einem anderen Ordner und unter einem anderen Konto gestartet; erzwungener Fehler (ALTER-Recht entzogen), um den Rücksprung zu testen; Struktur jeder Datenbank Spalte für Spalte mit einer neuen 24.0.2 verglichen; REST-API vorher und nachher aufgerufen. Code von Dolibarr 24.0.2 gelesen (install/upgrade.php, upgrade2.php, step5.php, inc.php, check.php).

Der Web-Assistent von Dolibarr (/install) erledigt das Update mit ein paar Klicks. Wenn Sie Ihren Server aber per SSH verwalten, mehrere Instanzen betreiben oder die Seite vor dem Ende abbricht, wollen Sie dasselbe über die Kommandozeile starten. Dolibarr erlaubt das: Es sind die drei Skripte, die der Assistent aufruft, upgrade.php, upgrade2.php und step5.php.

Die Befehle sind kurz. Die Fallen sieht man nicht: Diese Skripte melden „alles in Ordnung“ (Rückgabewert 0), auch wenn sie nichts getan haben. Drei davon haben wir am 19. Oktober 2026 ausgelöst und dann ein Skript geschrieben, das sie umgeht, getestet mit Updates von 22.0.5, 23.0.4 und 24.0.1 auf 24.0.2.

Diese Seite gilt für eine Installation aus dem .tgz-Archiv, wie in unserer Anleitung Dolibarr auf Ubuntu oder Debian installieren: Code in /var/www/dolibarr, Dokumente in /var/lib/dolibarr/documents. Mit dem offiziellen Docker-Image lesen Sie besser Dolibarr unter Docker aktualisieren.

Bevor Sie anfangen

Das Update selbst macht Dolibarr selten kaputt: Probleme machen externe Module, die PHP-Version und Anpassungen (siehe Dolibarr-Update ohne Ausfälle). Unser kostenloses Modul Update-Bereitschaftsprüfung prüft das vorher, ohne etwas zu verändern.

Notieren Sie dann die Version Ihrer Datenbank, nicht die der Dateien: Sie bestimmt die Schritte.

sudo mariadb -N dolibarr -e "SELECT name, value FROM llx_const WHERE name LIKE 'MAIN_VERSION_LAST_%' AND entity = 0"

Der höchste angezeigte Wert ist Ihre aktuelle Version. Ersetzen Sie dolibarr durch den Namen Ihrer Datenbank und llx_ durch Ihr Präfix, falls es abweicht (beides steht in conf.php).

1. Sichern

Auch wenn Sie sich auf die Sicherung Ihres Hosters verlassen: Der Rücksprung weiter unten braucht diese hier.

sudo mariadb-dump --single-transaction --routines dolibarr > ~/dolibarr-base.sql
sudo tar -czf ~/dolibarr-documents.tgz -C /var/lib/dolibarr documents

Die alten Dolibarr-Dateien bleiben im nächsten Schritt erhalten. Mehr dazu: Dolibarr sichern und wiederherstellen.

2. Dateien ersetzen

Legen Sie die neue Version in einen neuen Ordner, statt sie über die alte zu kopieren: So verschwinden Dateien, die zwischen zwei Versionen entfernt wurden, wirklich, und der alte Ordner dient als Rückweg. Danach kopieren Sie zwei Dinge zurück: conf.php und den Ordner custom der externen Module.

cd /tmp
curl -fL -o dolibarr-24.0.2.tgz "https://sourceforge.net/projects/dolibarr/files/Dolibarr%20ERP-CRM/24.0.2/dolibarr-24.0.2.tgz/download"
sudo tar --no-same-owner -xzf /tmp/dolibarr-24.0.2.tgz -C /var/www
sudo mv /var/www/dolibarr /var/www/dolibarr-alt
sudo mv /var/www/dolibarr-24.0.2 /var/www/dolibarr
sudo cp -a /var/www/dolibarr-alt/htdocs/conf/conf.php /var/www/dolibarr/htdocs/conf/
sudo cp -a /var/www/dolibarr-alt/htdocs/custom/. /var/www/dolibarr/htdocs/custom/

cp -a behält Eigentümer und Rechte von conf.php bei (in unserem Test www-data, nur lesbar).

3. Datenbank migrieren: ein Schritt pro Version

Jeder Schritt führt von einer Hauptversion zur nächsten, mit den drei Skripten in dieser Reihenfolge. Die Nummern werden x.0.0 geschrieben: Dolibarr ignoriert die letzte Ziffer Ihrer Version (die 5 von 22.0.5) und wählt in beiden Fällen dieselbe Datei.

Von 22 auf 24, zwei Schritte:

sudo touch /var/lib/dolibarr/documents/upgrade.unlock
cd /var/www/dolibarr/htdocs/install
sudo -u www-data php upgrade.php 22.0.0 23.0.0 > /tmp/schritt1.html
sudo -u www-data php upgrade2.php 22.0.0 23.0.0 >> /tmp/schritt1.html
sudo -u www-data php step5.php 22.0.0 23.0.0 auto upgrade_23.0.0 >> /tmp/schritt1.html
sudo -u www-data php upgrade.php 23.0.0 24.0.0 > /tmp/schritt2.html
sudo -u www-data php upgrade2.php 23.0.0 24.0.0 >> /tmp/schritt2.html
sudo -u www-data php step5.php 23.0.0 24.0.0 >> /tmp/schritt2.html

Von einer 23.x oder 24.0.x, ein einziger Schritt (das ist auch der Schritt für ein kleines Update, 24.0.1 auf 24.0.2):

sudo touch /var/lib/dolibarr/documents/upgrade.unlock
cd /var/www/dolibarr/htdocs/install
sudo -u www-data php upgrade.php 23.0.0 24.0.0 > /tmp/schritt1.html
sudo -u www-data php upgrade2.php 23.0.0 24.0.0 >> /tmp/schritt1.html
sudo -u www-data php step5.php 23.0.0 24.0.0 >> /tmp/schritt1.html

Bei einem größeren Abstand fügen Sie nach demselben Muster einen Schritt pro Version hinzu: Alle Schritte außer dem letzten enden mit auto upgrade_ und der erreichten Version.

4. Prüfen, dann wieder sperren

grep -o '[0-9.]*-[0-9.]*\.sql' /tmp/schritt*.html | sort -u
sudo mariadb -N dolibarr -e "SELECT value FROM llx_const WHERE name = 'MAIN_VERSION_LAST_UPGRADE' AND entity = 0"

Der erste Befehl muss eine Datei pro Schritt zeigen (schritt1.html:22.0.0-23.0.0.sql, dann schritt2.html:23.0.0-24.0.0.sql; bei einem einzigen Schritt nur 23.0.0-24.0.0.sql): Das ist das einzige verlässliche Zeichen, dass die Migration gelaufen ist. Der zweite muss die neue Version zeigen. Setzen Sie dann die Schutzmaßnahmen aus der Installationsanleitung wieder:

sudo rm -f /var/lib/dolibarr/documents/upgrade.unlock
sudo find /var/www/dolibarr/htdocs -path /var/www/dolibarr/htdocs/custom -prune -o -exec chmod a-w {} +
sudo chmod 400 /var/www/dolibarr/htdocs/conf/conf.php

Melden Sie sich an und prüfen Sie unter EinstellungenModule/Anwendungen, dass Ihre externen Module noch aktiv sind. Behalten Sie /var/www/dolibarr-alt ein paar Tage, bevor Sie es löschen.

Die Fallen, die wir ausgelöst haben

Was man tut Was passiert Rückgabewert
upgrade.php starten, während install.lock existiert, ohne upgrade.unlock Ein Satz „The install/upgrade pages have been disabled…“, die Datenbank bleibt unberührt 0
Zwei Schritte ohne auto upgrade_23.0.0 am Ende des ersten hintereinander starten step5.php löscht upgrade.unlock nach Schritt 1: Schritt 2 wird wie oben blockiert 0
Von 22 auf 24 in einem einzigen Aufruf Beide SQL-Dateien laufen, aber die drei Datenmigrationen der 23 werden übersprungen 0
Das Skript aus einem anderen Ordner starten Failed opening required '../filefunc.inc.php' 255
Das Skript unter einem Konto starten, das conf.php nicht lesen kann Permission denied bei conf.php 255

Die zweite ist die gefährlichste. In unserem Test zeigte die Datenbank nach Schritt 1 schon „24.0.2“, obwohl Schritt 2 nicht gelaufen war: Es fehlten 3 Tabellen und 37 Spalten der Version 24, und die REST-API antwortete mit 401 auf einen Schlüssel, der vorher funktionierte. Der Web-Assistent umgeht die Falle, indem er Zwischenschritten upgrade_23.0.0 übergibt (so steht es in install/check.php): Die Datenbank wird dann als 23.0.0 markiert, und upgrade.unlock bleibt bis zum letzten Schritt liegen.

Die dritte sieht man nicht sofort. Mit einem einzigen Aufruf 2224 war die Struktur am Ende dieselbe wie mit zwei Schritten, aber die Datenmigrationen der 23 liefen nicht (in unserer Datenbank wurde der API-Schlüssel nicht in seine neue Tabelle übernommen und der Signaturschlüssel der unveränderbaren Logs nicht angelegt). In 24.0.2 ging nichts sichtbar kaputt: Genau das ist das Problem. Bei drei oder mehr Versionen Abstand ist es schlimmer: Laut dem Code von upgrade.php werden nur die erste und die letzte SQL-Datei gewählt, wie unser Docker-Test von 20 auf 24 gezeigt hat (unvollständige Datenbank, ohne jede Fehlermeldung).

Die beiden letzten Fälle brechen mit einem sichtbaren Fehler ab: Arbeiten Sie in htdocs/install und starten Sie die Skripte mit dem Konto des Webservers (www-data unter Debian und Ubuntu).

Das vollständige Skript

Das Skript unten erledigt alles Obige der Reihe nach und hält beim ersten Zweifel an. Es liest die Datenbankparameter aus conf.php, berechnet die Schritte, sichert, ersetzt die Dateien, migriert Schritt für Schritt, prüft nach jedem Schritt, dass die SQL-Datei gelaufen ist und die Datenbank die richtige Version trägt, und sperrt danach wieder. Schlägt etwas fehl, legt es die alten Dateien zurück und spielt die Datenbanksicherung wieder ein.

Kopieren Sie es in eine Datei maj-dolibarr.sh, passen Sie die fünf Zeilen oben an und starten Sie es:

sudo bash maj-dolibarr.sh
#!/bin/bash
# Dolibarr über die Kommandozeile aktualisieren (Installation aus dem .tgz-Archiv).
# Anleitung und Erklärungen: https://dolix.fr/de/notizen/dolibarr-script-mise-a-jour/
# Getestet am 19.10.2026 auf Debian 13 (PHP 8.4, MariaDB 11.8): 22.0.5, 23.0.4 und 24.0.1 -> 24.0.2.
# Als root starten (sudo bash maj-dolibarr.sh), außerhalb der Arbeitszeiten.
set -euo pipefail

# --- Anpassen ---------------------------------------------------------------
NOUVELLE=24.0.2                     # zu installierende Version
DOLI=/var/www/dolibarr              # Ordner, der htdocs/ enthält
DOCS=/var/lib/dolibarr/documents    # Dokumentenordner ($dolibarr_main_data_root)
SAUV=/root/sauvegardes-dolibarr     # Ablage der Sicherungen
WEB=www-data                        # Benutzer des Webservers
# -----------------------------------------------------------------------------

CONF=$DOLI/htdocs/conf/conf.php
DATE=$(date +%Y%m%d-%H%M%S)
TRAVAIL=$SAUV/$DATE
[ "$(id -u)" -eq 0 ] || { echo "Als root starten (sudo)."; exit 1; }
[ -f "$CONF" ] || { echo "conf.php nicht gefunden: $CONF"; exit 1; }
mkdir -p "$TRAVAIL"; chmod 700 "$SAUV" "$TRAVAIL"

# Datenbankparameter, aus conf.php gelesen
lire() { php -r 'include $argv[1]; echo ${$argv[2]}??"";' "$CONF" "$1"; }
DB_HOTE=$(lire dolibarr_main_db_host); DB_PORT=$(lire dolibarr_main_db_port)
DB_NOM=$(lire dolibarr_main_db_name); DB_USER=$(lire dolibarr_main_db_user)
DB_MDP=$(lire dolibarr_main_db_pass); PREFIXE=$(lire dolibarr_main_db_prefix)
case "$DB_MDP" in crypted:*|dolcrypt:*)
  echo "Verschlüsseltes Passwort in conf.php: dieses Skript kann es nicht lesen."; exit 1;; esac
MYCNF=$(mktemp); chmod 600 "$MYCNF"; trap 'rm -f "$MYCNF"' EXIT
printf '[client]\nhost=%s\nport=%s\nuser=%s\npassword="%s"\n' \
  "$DB_HOTE" "${DB_PORT:-3306}" "$DB_USER" "$DB_MDP" > "$MYCNF"
SQL() { mariadb --defaults-extra-file="$MYCNF" -N "$DB_NOM" -e "$1"; }

# Version der Datenbank (nicht der Dateien)
ACTUELLE=$(SQL "SELECT value FROM ${PREFIXE:-llx_}const WHERE name IN
  ('MAIN_VERSION_LAST_UPGRADE','MAIN_VERSION_LAST_INSTALL') AND entity=0" | sort -V | tail -1)
[ -n "$ACTUELLE" ] || { echo "Datenbankversion nicht gefunden."; exit 1; }
M=${ACTUELLE%%.*}; C=${NOUVELLE%%.*}
[ "$M" -le "$C" ] || { echo "Die Datenbank ($ACTUELLE) ist neuer als $NOUVELLE."; exit 1; }

# Schritte: einer pro Hauptversion (22 -> 23, dann 23 -> 24), nie 22 -> 24 auf einmal
ETAPES=()
if [ "$M" -eq "$C" ]; then ETAPES=("$((C - 1)).0.0 $C.0.0")
else for ((v = M; v < C; v++)); do ETAPES+=("$v.0.0 $((v + 1)).0.0"); done; fi
echo "Datenbank auf $ACTUELLE, Ziel $NOUVELLE. Schritte:"; printf '  %s\n' "${ETAPES[@]}"
read -r -p "Sicherung, dann Update. Fortfahren? (j/N) " R; [ "$R" = j ] || exit 1

# 1. Neue Version herunterladen und entpacken (noch wird nichts verändert)
curl -fsSL -o "$TRAVAIL/dolibarr-$NOUVELLE.tgz" \
  "https://sourceforge.net/projects/dolibarr/files/Dolibarr%20ERP-CRM/$NOUVELLE/dolibarr-$NOUVELLE.tgz/download"
tar --no-same-owner -xzf "$TRAVAIL/dolibarr-$NOUVELLE.tgz" -C "$TRAVAIL"
[ -f "$TRAVAIL/dolibarr-$NOUVELLE/htdocs/install/upgrade.php" ] || { echo "Archiv unvollständig."; exit 1; }

# 2. Sicherungen: Datenbank, Dokumente (die alten Dateien bleiben in Schritt 3 erhalten)
mariadb-dump --defaults-extra-file="$MYCNF" --single-transaction --routines --skip-disable-keys "$DB_NOM" > "$TRAVAIL/base.sql"
tar -czf "$TRAVAIL/documents.tgz" -C "$(dirname "$DOCS")" "$(basename "$DOCS")"
echo "Sicherungen in $TRAVAIL"

# 3. Dateien ersetzen: neuer Ordner, dann conf.php und externe Module
ANCIEN=$DOLI-alt-$DATE
mv "$DOLI" "$ANCIEN"
mv "$TRAVAIL/dolibarr-$NOUVELLE" "$DOLI"
cp -a "$ANCIEN/htdocs/conf/conf.php" "$DOLI/htdocs/conf/conf.php"
cp -a "$ANCIEN/htdocs/custom/." "$DOLI/htdocs/custom/"
chown -R "$WEB:$WEB" "$DOLI/htdocs/custom"

retour() {
  set +e
  echo "FEHLER bei Schritt $1: zurück zur Version $ACTUELLE."
  rm -rf "$DOLI"; mv "$ANCIEN" "$DOLI"; rm -f "$DOCS/upgrade.unlock"
  echo "Alte Dateien wiederhergestellt."
  # Datenbank leeren (auch die von der Migration angelegten Tabellen), dann die Sicherung einspielen
  { echo "SET FOREIGN_KEY_CHECKS=0;"
    SQL "SELECT CONCAT('DROP TABLE \`', table_name, '\`;') FROM information_schema.tables
         WHERE table_schema = DATABASE()"; } | mariadb --defaults-extra-file="$MYCNF" "$DB_NOM" \
  && mariadb --defaults-extra-file="$MYCNF" "$DB_NOM" < "$TRAVAIL/base.sql" \
  && echo "Datenbank wiederhergestellt." \
  || echo "DATENBANK NICHT WIEDERHERGESTELLT: $TRAVAIL/base.sql von Hand einspielen."
  echo "Protokolle der Migration: $TRAVAIL/*.html"; exit 1
}

# 4. Datenbank Schritt für Schritt migrieren, als Benutzer des Webservers
cd "$DOLI/htdocs/install"
for E in "${ETAPES[@]}"; do
  set -- $E
  # step5.php löscht upgrade.unlock, sobald die Datenbank die Version der Dateien erreicht: bei jedem Schritt neu anlegen
  touch "$DOCS/upgrade.unlock"
  if [ "$2" = "$C.0.0" ]; then FIN=""; ATTENDU=$NOUVELLE     # letzter Schritt
  else FIN="auto upgrade_$2"; ATTENDU=$2; fi                  # Zwischenschritt, wie der Web-Assistent
  for P in upgrade.php upgrade2.php step5.php; do
    A=""; [ "$P" = step5.php ] && A=$FIN
    runuser -u "$WEB" -- php "$P" "$1" "$2" $A > "$TRAVAIL/$1-$2-$P.html" 2>&1 || retour "$P $1 -> $2"
  done
  # Rückgabewert 0, selbst wenn install.lock alles blockiert: Ergebnis prüfen
  grep -q "$1-$2.sql" "$TRAVAIL/$1-$2-upgrade.php.html" || retour "$1 -> $2 (SQL-Skript nicht ausgeführt)"
  V=$(SQL "SELECT value FROM ${PREFIXE:-llx_}const WHERE name='MAIN_VERSION_LAST_UPGRADE' AND entity=0")
  [ "$V" = "$ATTENDU" ] || retour "$1 -> $2 (Datenbank auf $V statt $ATTENDU)"
  echo "Schritt $1 -> $2: OK (Datenbank auf $V)"
done
rm -f "$DOCS/upgrade.unlock"

# 5. Wieder sperren, wie nach der Installation
[ -f "$DOCS/install.lock" ] || touch "$DOCS/install.lock"
find "$DOLI/htdocs" -path "$DOLI/htdocs/custom" -prune -o -exec chmod a-w {} +
chmod 400 "$DOLI/htdocs/conf/conf.php"
echo "Fertig. Alte Dateien: $ANCIEN (nach der Kontrolle löschen)."

Was es nicht tut: Es prüft keine externen Module, es kann kein verschlüsseltes Passwort in conf.php lesen (es hält an), und es verwendet die Befehle mariadb und mariadb-dump (auf einem MySQL-Server heißen sie mysql und mysqldump: nicht getestet).

Was wir mit diesem Skript geprüft haben

  • 22.0.524.0.2 (zwei Schritte), 23.0.424.0.2 und 24.0.124.0.2: Datenbankversion 24.0.2, Geschäftspartner, Rechnung, Anhang und Ordner in custom/ vorhanden, API-Schlüssel akzeptiert, /install-Seiten wieder gesperrt, upgrade.unlock entfernt, conf.php weiterhin nur lesbar.
  • Struktur Spalte für Spalte mit einer neu installierten 24.0.2 verglichen: identisch, bis auf eine Spalte bei Datenbanken aus 22 und 23 (retained_warranty_amount in llx_facture, deren Anlage im offiziellen Skript der 24 auskommentiert ist und die keine PHP-Datei von 24.0.2 verwendet).
  • Erzwungener Fehler (ALTER-Recht des Datenbankbenutzers entzogen): Das Skript hielt beim ersten Schritt an, legte die alten Dateien zurück und spielte die Datenbank wieder ein; Struktur und Inhalt wie vorher, API wieder auf 22.0.5.
  • Dauer auf unserer Testdatenbank: 37 Sekunden, Download inklusive. Eine echte Datenbank braucht länger: Starten Sie es außerhalb der Arbeitszeiten.

Von Hand zurückspringen

Wenn Sie die Schritte von Hand ausgeführt haben und etwas nicht stimmt:

sudo rm -rf /var/www/dolibarr
sudo mv /var/www/dolibarr-alt /var/www/dolibarr
sudo mariadb -e "DROP DATABASE dolibarr; CREATE DATABASE dolibarr CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
sudo mariadb dolibarr < ~/dolibarr-base.sql

Prüfen Sie vorher, dass Ihre Datenbank in utf8mb4 ist (das ist der Fall, wenn Sie unserer Installationsanleitung gefolgt sind).

Wenn die Migration hängt

Lesen Sie die Dateien /tmp/schritt*.html (beim Skript die im Sicherungsordner): Jede abgelehnte Abfrage steht dort mit ihrer Fehlermeldung. Wenn Sie nicht weiterkommen, ist genau das die Diagnose für 90 €: eine Stunde an Ihrem Dolibarr, danach schriftlich die Ursache und was die Behebung kosten würde.

Siehe auch

DolibarrUpdateAktualisierungSkriptKommandozeileupgrade.phpupgrade2.phpstep5.phpupgrade.unlockinstall.lockSSH