by: Helge, published: Jan 31, 2023, in

Upgrading Ubuntu 20.04 to 22.04 & PHP 7.4 to 8.1 for WordPress

This post describes how I upgraded our webserver running WordPress on Apache from Ubuntu 20.04.5 LTS to 22.04.1 LTS. Please see this article for more information on the server’s original installation and configuration.

Backup

Before you begin, create a checkpoint (snapshot) in Hyper-V Manager. If anything goes wrong, a checkpoint makes it trivially easy to get back to the last working state.

Install All Available Updates

sudo apt update
sudo apt dist-upgrade
sudo apt autoremove

Reboot and check Apache’s error log:

sudo shutdown -r now
tail /var/log/apache2/error.log

Upgrade to Ubuntu 22.04.1

sudo do-release-upgrade

During the upgrade process:

  • Failure restarting some services: mysql. You will need to start these manually by running invoke-rc.d <service> start. That sorted itself out; no manual intervention was required.
  • When asked whether to install the updated version of /etc/ssh/sshd_config, select keep the local version.
  • When asked whether to install the updated version of /etc/logrotate.d/apache2, select yes.

DNS Servers via DHCP Broken

Hetzner servers typically get their IP configuration via DHCP. This was never an issue – until this upgrade. DHCP by itself works, but adding the nameserver received via DHCP to the DNS resolver’s configuration doesn’t. As a workaround, I added the Quad9 DNS server manually to /etc/systemd/resolved.conf:

[Resolve]
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net

Migrate from PHP 7.4 to PHP 8.1

PHP Package Name Changes

In the upgrade from Ubuntu 20.04 to 22.04, the PHP version is upgraded from 7.4 to 8.1, which is a good thing. What is not so great is that the names of all the PHP packages change from php7.4-* to php8.1-*. Due to that name change, Apache’s PHP configuration is broken after the upgrade and must be fixed manually.

Additionally, the upgrade routine is not clever enough to upgrade any manually installed PHP packages. The 7.4 packages are uninstalled instead of being replaced with their 8.1 counterparts. Run the following command to generate a list of all installed PHP packages so you can reinstall them for the new version in the next step:

dpkg -l | grep php | tee packages.txt

Install Missing PHP Modules

Add all the modules from the file packages.txt generated earlier. Note that some files were switched to a version-independent naming scheme (e.g., php-json), which is a good thing.

sudo apt install php8.1-bcmath php8.1-curl php8.1-fpm php8.1-gd php8.1-mbstring php8.1-mysql php8.1-tidy php-json php-xml php-xmlrpc php-zip

Apache Configuration

Disable the PHP 7.4 module and enable the PHP 8.1 module:

sudo a2enmod php8.1
sudo a2disconf php7.4-fpm
sudo a2enconf php8.1-fpm
sudo service apache2 restart

PHP 8.1 Hardening and Optimization

Edit the PHP configuration. If you are using FPM, it should be located in /etc/php/8.1/fpm/php.ini. Otherwise try /etc/php/8.1/apache2/php.ini.

Disabled Functions

Add the following to disable_functions: exec,system,shell_exec,passthrough

Opcache

Configure PHP’s opcache by setting:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=10
opcache.max_accelerated_files=10000

Upload Limit

Increase the upload limit:

upload_max_filesize = 50M
post_max_size = 50M

Increase PHP Resources

Depending on your workload, it may be necessary to increase the resources allocated to PHP. Edit the PHP configuration. Modify the following settings:

; Default: 30
max_execution_time = 120
; Default: 128M
memory_limit = 256M

PHP Restart

Restart PHP-FPM (or Apache, if you are not using PHP FPM):

sudo service php8.1-fpm restart

Remove Obsolete PHP Directories

Clean up remainders from earlier migrations:

sudo rm -r /etc/php/7.4

Purge PHP 7.4 packages:

sudo apt purge php7.4\*

Adjust the Logrotate Configuration

Edit /etc/logrotate.d/apache2 by modifying the rotate line and adding dateext:

rotate 30
dateext

Disable MPM_Prefork to Enable HTTP/2

The upgrade enabled mpm_prefork which doesn’t work with HTTP/2 (see this article). Replace it with mpm_event and disable regular PHP in Apache, which is OK, because we run PHP via FPM.

 sudo a2dismod php8.1
 sudo a2dismod mpm_prefork
 sudo a2enmod mpm_event
 sudo service apache2 restart

Check for Errors

Check Apache’s error log:

tail /var/log/apache2/error.log

Previous Article ownCloud Infinite Scale With OpenID Connect Authentication for Home Networks
Next Article restic: Encrypted Offsite Backup With Ransomware Protection for Your Homeserver