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.
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.unlockentfernt,conf.phpweiterhin 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_amountinllx_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.