HowTo: Upgrade to Nextcloud 26 on Debian Bullseye

Preamble

  • This HowTo does not apply to any Nextcloud container/VM/snap appliance, but is for bare metal installs on Debian Bullseye only!
  • This HowTo was written with best efforts, but without guarantee. I cannot be held responsible for any damage to your system or data!

Background

Nextcloud 26 is about to be released on 2023-03-21, which drops support for PHP 7.4, the PHP version shipped by the current stable Debian Bullseye.

The upcoming Debian Bookworm release is expected this summer, but it ships PHP 8.2, which is not supported by Nextcloud 25 yet.

Since there is no Nextcloud version which supports both, PHP 7.4 of Debian Bullseye and PHP 8.2 of Debian Bookworm, an upgrade is impossible, using official system packages and unmodified Nextcloud versions only.

This HowTo walks you through two possible solutions to get you unstuck and Nextcloud upgraded to version 26 on Debian Bullseye.

First, do a backup!

As always, before doing any such changes to your production server, create/update a full system backup and a dedicated backup of your Nextcloud data and database. At best try the steps first on a testing clone of your Nextcloud server to sort out surprises in the middle of the process. If not the case already, incorporate these steps into your general server maintenance routines.

1. Ondrej’s PHP repository

Ondrej Sury is the official Debian PHP (and Apache2, …) package maintainer and maintains additional APT repositories from where one can install latest software on older Debian versions.

His PHP repo can be used to install PHP 8.1 on Debian Bullseye. However, using this repository implies a number of risks you need to be aware of and which may bite you in the long term. This is hence not the preferred solution in the author’s personal opinion, especially if you are not experienced with APT, solving package conflicts and downgrading packages manually via dpkg CLI:

  • If you install PHP via unversioned meta package like apt install php-fpm, you basically switch to a rolling release model, as on Ondrej’s repository these packages always pull the very latest PHP version. This can either lead to multiple concurrent PHP installs or break your Nextcloud, which does not support latest PHP once released, like currently PHP 8.2.
    Usually this can be solved by installing the versioned packages explicitly (needed for PHP 8.1 anyway) like apt install php8.1-fpm, but there are official Debian packages which depend on unversioned meta packages, like phpMyAdmin. APT pinning can be used to prevent meta package installs from this repository.
  • The repository ships not only PHP, but also newer versions of system libraries, which some of the PHP packages depend on. This can cause conflicts if other Debian packages depend on the version provided by the official Debian repository.
    It can furthermore cause issues if you later need to remove the repository, e.g. because you upgraded to Debian Bookworm, not supported by the PHP repo yet, or because your company demands to remove any 3rd party repositories (while there is no reason to not trust Ondrej if one trusts Debian). If you then e.g. try to install development headers (*-dev packages) for one of these libraries, APT errors out with conflicts due to the version mismatch between runtime library and development headers.
    With bi-directional version dependencies which cannot be solved without a downgrade, apt cannot solve it, but manual downloads and downgrades via dpkg are required. A downgrade may even be needed after a Bookworm upgrade, since the PHP repo ships package versions beyond any official Debian repo.

However, for Nextcloud-only systems, or with some knowledge or support, these are acceptable risks, which can be further minimised by applying some strict APT pinning, e.g. with the following here document command block:

cat << 'EOF' > /etc/apt/preferences.d/php
Package: *
Pin: origin packages.sury.org
Pin-Priority: -1

Package: php8.1-* libapache2-mod-php8.1 libpcre2-* libgd3 libgd-dev
Pin: origin packages.sury.org
Pin-Priority: 500
EOF

Install the repository itself this way:

sudo curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
echo 'deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bullseye main' | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update

Then you can install PHP 8.1 and all needed modules, using the versioned php8.1-* package names. Remember to adjust webserver configs in case, pointing to the new PHP 8.1 socket, or using the unversioned generic socket /run/php/php-fpm.sock. On Apache2, these commands will do:

a2dismod php7.4
a2enmod php8.1
a2disconf php7.4-fpm
a2enconf php8.1-fpm
systemctl restart apache2

Also don’t forget to port custom configs you may have done from /etc/php/7.4 to /etc/php/8.1. After verified that Nextcloud and everything works well with the new PHP instance, you may remove the old PHP 7.4 packages:

apt purge $(dpkg --get-selections | mawk '/php7.4/{print $1}')

This may additionally remove the old unversioned meta packages, which is fine. Just verify that nothing unwanted is removed before confirming it.

2. Upgrading to Debian Bookworm

Even that Debian Bookworm has not been released yet, but is the Debian testing branch, at time of writing, the first two package freezing stages have been passed, which means that all larger library/runtime system transitions and backend software upgrades have been finished, including PHP 8.2, MariaDB 10.11, PostgreSQL 15 and Python 3.11. While new upstream software versions can still be merged and you will see a significantly larger amount of available package upgrades following apt update compared to a stable Debian release, large surprises and breaking changes are not expected anymore (while no guarantee can be given!).

While a distribution upgrade always bears risks, nowadays Debian maintainers usually have CI/CD pipelines to test and take care of smooth distro upgrades. However, it cannot be ruled out that you need to apply configuration changes manually, especially if you changed them manually before (instead of using own drop-in/overrides configs, like conf.d directories and similar). I tested the Bullseye to Bookworm upgrade with a typical Nextcloud installation, Apache2, Nginx and Lighttpd webserver, multiple times, and so far no major quirks appeared, respectively they have been sorted in the meantime. I’ll keep this topic updated in case any issues appear, and how to resolve them.

The bonus of upgrading to Bookworm is that you lift the whole system onto a future-prove stage, including latest PHP 8.2. This may be necessary anyway earlier or later, as long as you do not prefer setting up the system from scratch, which is always a recommended clean alternative to major distribution upgrades.

First of all upgrade all packages to the latest stage, using the current package lists:

apt update
apt upgrade
apt full-upgrade

Carefully check the outputs for any error and sort them out before doing further changes.

Then migrate package the package lists from Bullseye to Bookworm:

sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list
sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list.d/*.list
apt update

Again, carefully check the output of the last command. There may be 3rd party software lists which have no bookworm suite yet, including Ondrej’s PHP repository if your applied it before, or SBC vendor repositories. Often, packages from bullseye suites can be installed and run on Bookworm as well. But also check whether you really need affected lists. If they were only to provide newer software versions, like Ondrej’s PHP repo, they may not be needed on Bookworm so that you can remove them:

rm /etc/apt/sources.list.d/php.list
rm /etc/apt/preferences.d/php
rm /usr/share/keyrings/deb.sury.org-php.gpg

Then apply the actual distribution upgrade:

apt upgrade
apt full-upgrade
head -4 /etc/os-release

Two currently known quirks may need to be solved:

  • The mariadb-server package was left removed instead of upgraded to v10.11.
  • The Redis configuration needs to explicitly allow failing to bind on IPv6 now, which previously was implicit. Only relevant if you do not use IPv6, but save to apply in any case.
apt install mariadb-server
sed -i '/^bind 127.0.0.1 ::1$/c\bind 127.0.0.1 -::1' /etc/redis/redis.conf
systemctl restart redis-server

If you use PostgreSQL, you need to migrate the database from v13 to v15:

systemctl stop postgresql
pg_dropcluster 15 main
pg_upgradecluster 13 main
pg_dropcluster 13 main
systemctl start postgresql

In case you installed the versioned PHP packages before, you need to install PHP 8.2 and all needed modules, using the php8.2-* package names. Remember to adjust webserver configs in case, pointing to the new PHP 8.2 socket, or using the unversioned generic socket /run/php/php-fpm.sock. On Apache2, these commands will do:

a2dismod php7.4
a2enmod php8.2
a2disconf php7.4-fpm
a2enconf php8.2-fpm
systemctl restart apache2

Also don’t forget to port custom configs you may have done from /etc/php/7.4 to /etc/php/8.2. After verified that Nextcloud and everything works well with the new PHP instance, you may remove the old PHP 7.4 packages:

apt purge $(dpkg --get-selections | mawk '/php7.4/{print $1}')

This may additionally remove the old unversioned meta packages, which is fine. Just verify that nothing unwanted is removed before confirming it.

Finally, if the kernel was upgraded, do a reboot, otherwise at least restart systemd via systemctl daemon-reexec. If everything worked well, you can autoremove obsolete packages:

apt autopurge

Now remember that Nextcloud 25 does not support PHP 8.2. However, aside of a few deprecation warnings, it does actually work fine, and we only need it to run the update to Nextcloud 26, which does support PHP 8.2. To allow this, we need to do a little temporary hack:

sed -i 's/>= 80200/>= 80300/' /var/www/nextcloud/lib/versioncheck.php

In case, adjust the path to your Nextcloud installation directory.

Now you should be able to perform the update to Nextcloud 26.

Footnotes

If you run into any issues or have any feedback, please reply to this topic. This is meant to stay work-in-progress as I will keep it updated with recent info, solutions for possible new quirks etc.

8 Likes

Hi ! Thank you very much for this HowTo !
I think you forgot to add the package php8.1 in the here document.

became

Package: php8.1 php8.1-* libapache2-mod-php8.1 libpcre2-* libgd3 libgd-dev
Pin: origin packages.sury.org
Pin-Priority: 500
EOF

Without this edit, I obtain an error when trying to install the basic php8.1 package.

php, php8.1 etc are just meta packages which pull in any actual PHP implementation, like libapache2-mod-php8.1 (the default which I’d not recommend) , php8.1-fpm (which I’d recommend) or php8.1-cgi. Pick one of those, preferably PHP-FPM for any production system, instead of the meta package.