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 runninginvoke-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
, selectkeep the local version
. - When asked whether to install the updated version of
/etc/logrotate.d/apache2
, selectyes
.
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