today 21.04.2025
local_offer
Category

phpMyAdmin in combination with froxlor and php-fpm

I noticed that my phpMyAdmin installation displayed the following message every time I logged in:

The configuration file now needs a secret passphrase (blowfish_secret).
The $cfg['TempDir'] (/var/lib/phpmyadmin/tmp/) is not accessible. phpMyAdmin is not able to cache templates and will be slow because of this.

And apache gave the following error:

[proxy_fcgi:error] [pid 2106071] [client XXX.XXX.XXX.XXX:XXXXX] AH01071: Got error 'PHP message: phpmyadmin: Failed to load /var/lib/phpmyadmin/blowfish_secret.inc.php Check group www-data has read access and open_basedir restrictions.PHP message: phpmyadmin: Failed to load /etc/phpmyadmin/config-db.php Check group www-data has read access and open_basedir restrictions.'

After investigating the issue, it turned out that the problem was caused by a combination of how I set up froxlor and php-fpm. Since froxlor managed its own vhost (which you can change, if you want, and set up the vhost manually) and, manages its fpm pool automatically, phpMyAdmin was running in the same pool as froxlor. This meant that phpMyAdmin was running under froxlor’s default Linux user froxlorlocal and couldn’t access the files under /var/lib/phpmyadmin (which are only accessible by the user www-data). And the open_basedir restrictions were not properly implemented since the phpMyAdmin default vhost specified rules for PHP, but I’m running php-fpm instead.

Luckily the issue could be rather easily resolved. I had to create a new fpm pool for phpMyAdmin and edit phpMyAdmin’s default vhost to use that pool.

Create phpMyAdmin fpm pool

First you must create a new file in your fpm directory (may differ depending how you set up your system):

touch /etc/php/8.1/fpm/pool.d/phpmyadmin.conf

Now we add the following lines to the newly created file:

[phpmyadmin]
listen = /run/php/php8.1-fpm.d/phpmyadmin.sock
listen.owner = www-data
listen.group = www-data

user = www-data
group = www-data

pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200

php_admin_value[upload_tmp_dir] = /var/lib/phpmyadmin/tmp
php_admin_value[open_basedir] = /usr/share/phpmyadmin/:/usr/share/doc/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/:/usr/share/javascript/

You might need to adjust some of the lines according to your specific environment.

Note the last two lines (php_admin_value[upload_tmp_dir] and php_admin_value[open_basedir]). They are taken from phpMyAdmin’s default vhost configuration, but are not in effect, because we use php-fpm and not “just” PHP (IfModule mod_php7.c isn’t applied in that case):

# limit libapache2-mod-php to files and directories necessary by pma
<IfModule mod_php7.c>
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
php_admin_value open_basedir /usr/share/phpmyadmin/:/usr/share/doc/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/:/usr/share/javascript/
</IfModule>

The php-fpm pool is properly set up. Now we must edit the phpMyAdmin vhost to run under that pool.

Edit phpMyAdmin default vhost

Open the vhost and add the following lines outside <directory></directory> (otherwise apache throws an error that ProxyPassMatch doesn’t go inside <directory>):

# Explicit FastCGI handler
ProxyPassMatch ^/phpmyadmin/(.*\.php)$ unix:/run/php/php8.1-fpm.d/phpmyadmin.sock|fcgi://localhost/usr/share/phpmyadmin/$1
ProxyPassMatch ^/phpmyadmin/(.*\.php)$ unix:/run/php/php8.1-fpm.d/phpmyadmin.sock|fcgi://localhost/usr/share/phpmyadmin$1index.php

The location on your system might differ, depending which Linux flavour you use, but it was located under /etc/phpmyadmin/apache.conf in my case (Trisquel Linux 11).

Here you can read more about $1.

You need both lines, otherwise you get a File not found. error in your browser. The first one maps any request, while the latter handles index.php specifically (which is not handled by the first line).

I originally tried to simply add as I did in other vhosts:

<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.1-fpm-phpmyadmin.sock|fcgi://localhost/"
</FilesMatch>

However, it didn’t have any effect and phpMyAdmin was still running in the wrong pool. Possibly it was overridden by the default froxlor vhost or fpm-pool. But using ProxyPassMatch did the trick and the errors are now gone.

Make sure that the path of your socket matches the one you defined in your pool config.

Here is the full phpMyAdmin vhost including the new lines for ProxyPassMatch:

# phpMyAdmin default Apache configuration

Alias /phpmyadmin /usr/share/phpmyadmin

<Directory /usr/share/phpmyadmin>
Options SymLinksIfOwnerMatch
DirectoryIndex index.php

# limit libapache2-mod-php to files and directories necessary by pma
<IfModule mod_php7.c>
php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
php_admin_value open_basedir /usr/share/phpmyadmin/:/usr/share/doc/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/:/usr/share/jav>
</IfModule>
</Directory>

# Explicit FastCGI handler
ProxyPassMatch ^/phpmyadmin/(.*\.php)$ unix:/run/php/php8.1-fpm.d/phpmyadmin.sock|fcgi://localhost/usr/share/phpmyadmin/$1
ProxyPassMatch ^/phpmyadmin/(.*\.php)$ unix:/run/php/php8.1-fpm.d/phpmyadmin.sock|fcgi://localhost/usr/share/phpmyadmin$1index.php

# Disallow web access to directories that don't need it
<Directory /usr/share/phpmyadmin/templates>
Require all denied
</Directory>
<Directory /usr/share/phpmyadmin/libraries>
Require all denied
</Directory>

We are done and it’s time to restart your services (change php-8.1-fpm according to your system):

systemctl restart php8.1-fpm
systemctl restart apache2