PHP 7.4 und 8.3 liegen beide auf dem Server, php -v meldet 8.3, und der Cronjob für die alte Anwendung bricht trotzdem ab.

Kommandozeile, FPM-Dienst und einzelne Vhosts entscheiden unabhängig voneinander, welche Version sie benutzen. Wer an einer Stelle umstellt, ändert an den beiden anderen nichts.

Mehrere Versionen nebeneinander sind dabei kein Sonderfall. Sobald du PHP über Sury beziehst, ist es der Normalzustand: Die Pakete tragen die Versionsnummer im Namen und stören sich nicht.

Welche Versionen installiert sind

ls /etc/php/
systemctl list-units 'php*-fpm*' --no-pager

Das erste Kommando listet die Konfigurationsverzeichnisse, also alle installierten Versionen. Das zweite zeigt, welche FPM-Dienste tatsächlich laufen — eine installierte Version muss nicht gestartet sein.

Die drei Ebenen

Drei Stellen entscheiden, und sie tun es unabhängig voneinander:

EbeneEntscheidet überGesteuert durch
Kommandozeilephp im Terminal, Cronjobs, Composerupdate-alternatives
FPM-Dienstwelcher Dienst überhaupt läuftsystemctl je Version
Vhostwelche Version eine Website benutztSocket im Webserver

Diese drei sind unabhängig. Ein Server kann auf der Kommandozeile 8.3 nutzen, während eine Website über 7.4 läuft und eine zweite über 8.2.

Standardversion der Kommandozeile

Debian verwaltet das über update-alternatives. Interaktiv auswählen:

sudo update-alternatives --config php

Oder direkt setzen:

sudo update-alternatives --set php /usr/bin/php8.3

Prüfen mit php -v. Jede Version bleibt zusätzlich unter ihrem vollen Namen erreichbar:

php7.4 -v
php8.3 -v
Tipp
Schreib in Cronjobs und Startskripten immer die ausgeschriebene Version — php8.3 /pfad/script.php statt php /pfad/script.php. Dann bleibt der Job heil, wenn jemand später die Standardversion umstellt. Das ist eine der häufigsten Ursachen für Aufgaben, die monatelang unbemerkt scheitern.

Neben php verwalten weitere Einträge eigene Werkzeuge, etwa phar und phar.phar. update-alternatives --get-selections | grep php zeigt sie alle.

FPM-Dienste

Jede Version bringt einen eigenen Dienst und einen eigenen Socket mit:

/run/php/php7.4-fpm.sock
/run/php/php8.3-fpm.sock

Gestartet wird je Version:

sudo systemctl enable --now php8.3-fpm
sudo systemctl status php7.4-fpm

Welche Sockets tatsächlich existieren, zeigt ls -la /run/php/. Nur diese kannst du im Webserver ansprechen — ein Socket für eine Version, deren Dienst nicht läuft, ist nicht vorhanden.

Auch die Konfiguration ist getrennt. Jede Version hat eigene Dateien:

/etc/php/7.4/fpm/php.ini
/etc/php/7.4/fpm/pool.d/www.conf
/etc/php/8.3/fpm/php.ini
/etc/php/8.3/fpm/pool.d/www.conf

Eine Einstellung, die du in 8.3 änderst, gilt nicht für 7.4.

Pro Vhost eine eigene Version in Apache

Innerhalb des Vhosts legst du fest, an welchen Socket PHP-Dateien gehen:

<VirtualHost *:443>
    ServerName alt.example.com
    DocumentRoot /var/www/alt

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

Ein zweiter Vhost auf derselben Maschine zeigt dann auf php8.3-fpm.sock. Voraussetzung ist, dass die nötigen Module aktiv sind:

sudo a2enmod proxy_fcgi setenvif
sudo systemctl reload apache2

Solange mod_php aktiv ist, übernimmt es alle PHP-Dateien, und die Vhost-Einstellung läuft ins Leere. Erst abschalten:

sudo a2dismod php8.3
sudo systemctl restart apache2

Pro Vhost eine eigene Version in nginx

Hier steckt die Entscheidung im fastcgi_pass:

server {
    server_name alt.example.com;
    root /var/www/alt;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }
}

Für den nächsten Server-Block tauschst du nur den Socket. Danach testen und neu laden:

sudo nginx -t && sudo systemctl reload nginx

Eigene FPM-Pools statt eines gemeinsamen

Standardmäßig bedient ein Pool namens www alle Websites einer Version. Für getrennte Anwendungen lohnt sich ein eigener Pool je Website, weil sie dann unter verschiedenen Systembenutzern laufen und nicht gegenseitig in ihren Dateien lesen können.

Dafür legst du neben www.conf eine zweite Datei im selben Verzeichnis an, etwa /etc/php/8.3/fpm/pool.d/kunde1.conf, mit eigenem Poolnamen, eigenem user, eigener group und einem eigenen listen-Socket. Anschließend den Dienst neu starten und den neuen Socket im Vhost eintragen.

Eine kompromittierte Website kommt so nicht an die Dateien der anderen, und ein Pool, der sich festfährt, reißt die übrigen nicht mit.

Prüfen, welche Version wo gilt

php -v
php8.3 -v
ls -la /run/php/
systemctl list-units 'php*-fpm*' --no-pager

Für eine konkrete Website ist die verlässlichste Probe ein kurzes Skript mit phpinfo(), das du nach dem Blick sofort wieder löschst. Es zeigt neben der Version auch, welche php.ini tatsächlich geladen wurde.

Achtung
Ein liegengebliebenes phpinfo()-Skript verrät Pfade, Erweiterungen, Versionsnummern und Konfigurationswerte. Lege es nicht unter einem Namen wie info.php ab und lass es nicht stehen.

Eine Version wieder loswerden

sudo systemctl disable --now php7.4-fpm
sudo apt purge 'php7.4-*'

Vorher prüfen, dass kein Vhost und kein Cronjob mehr darauf zeigt — sonst liefert die Website nach dem Entfernen eine Fehlerseite statt PHP. Das Verzeichnis /etc/php/7.4/ bleibt bei apt remove stehen und verschwindet erst mit purge.

Fehlerbehebung

ProblemUrsache und Lösung
php -v zeigt eine andere Version als die WebsiteKommandozeile und Vhost sind getrennt. update-alternatives --config php betrifft nur das Terminal.
Cronjob nutzt die falsche VersionIm Job steht php statt php7.4. Ausgeschriebene Version eintragen.
Vhost-Einstellung wirkt nichtmod_php ist noch aktiv und fängt alle PHP-Dateien ab. Mit a2dismod abschalten.
Webserver meldet, der Socket fehleDer FPM-Dienst dieser Version läuft nicht. Mit systemctl enable --now starten.
Änderung an der php.ini ohne WirkungDatei der falschen Version bearbeitet, oder der falsche Zweig aus cli und fpm.
Erweiterung fehlt nur in einer VersionErweiterungen sind je Version zu installieren, etwa php7.4-gd zusätzlich zu php8.3-gd.
Nach dem Entfernen einer Version FehlerseiteEin Vhost zeigt noch auf den gelöschten Socket.

Häufige Fragen zu mehreren PHP-Versionen

Können PHP 7.4 und 8.3 gleichzeitig laufen?

Ja. Die Pakete tragen die Versionsnummer im Namen, haben getrennte Konfigurationsverzeichnisse und eigene FPM-Dienste. Sie stören sich nicht.

Wie wechsle ich die PHP-Version auf der Kommandozeile?

Mit sudo update-alternatives --config php interaktiv oder --set php /usr/bin/php8.3 direkt. Das betrifft nur das Terminal und Cronjobs, nicht die Websites.

Wie gebe ich einer einzelnen Website eine andere Version?

Über den FPM-Socket. In Apache mit SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost/" innerhalb des Vhosts, in nginx über fastcgi_pass im passenden location-Block.

Warum ändert sich nichts, obwohl ich den Vhost angepasst habe?

Meist ist mod_php in Apache noch aktiv. Es übernimmt alle PHP-Dateien, bevor die Vhost-Einstellung greift. Mit a2dismod php<version> abschalten und Apache neu starten.

Muss ich Erweiterungen für jede Version einzeln installieren?

Ja. php8.3-gd gilt nur für 8.3; für 7.4 brauchst du zusätzlich php7.4-gd. Pakete ohne Versionsnummer landen bei der Standardversion.