I am trying to convert an Wordpress-PHP-Apache2 (mpm_prefork) server to Wordpress-PHPFPM-Apache2 (mpm_event) server. The current docker environment has become much slower with increased concurrent access to Wordpress.
Current environment: Ubuntu 24.04.4, docker 28.1.1, WP 6.9.4, php 8.4, apache2 2.4, mariadb 10.11
docker-compose.yml:
volumes:
wordpress:
external: true
wplogs:
external: true
mariadb_wp2:
external: true
mysql_tmp:
external: true
mysql_run:
external: true
services:
db:
image: mariadb-chmod
restart: always
command: [
'--lower_case_table_names=1',
'--transaction-isolation=READ-COMMITTED',
'--autocommit=1'
]
environment:
MYSQL_DATABASE: bitnami_wordpress
MYSQL_USER: bn_wordpress
MYSQL_PASSWORD: *********
MYSQL_ROOT_USER: root
MYSQL_RANDOM_ROOT_PASSWORD: '1'
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-u", "bn_wordpress", "--password=*********"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- mariadb_wp2:/var/lib/mysql
- mysql_tmp:/tmp
- mysql_run:/run/mysqld
wordpress:
image: wp-php-apache
restart: always
ports:
- 443:443
dns:
- 81.130.111.248
- 81.130.111.249
depends_on: [ db ]
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: bn_wordpress
WORDPRESS_DB_PASSWORD: *********
WORDPRESS_DB_NAME: bitnami_wordpress
WORDPRESS_AUTH_KEY: ***************
WORDPRESS_SECURE_AUTH_KEY: ***************
WORDPRESS_LOGGED_IN_KEY: ***************
WORDPRESS_NONCE_KEY: ***************
WORDPRESS_AUTH_SALT: ***************
WORDPRESS_SECURE_AUTH_SALT: ***************
WORDPRESS_LOGGED_IN_SALT: ***************
WORDPRESS_NONCE_SALT: ***************
WORDPRESS_CONFIG_EXTRA: |
define( 'FORCE_SSL_ADMIN', true );
define( 'WP_TEMP_DIR', dirname(__FILE__) . '/wp-content/temp/' );
healthcheck:
test: ["CMD", "/usr/bin/healthcheck"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- wordpress:/var/www/html
- wplogs:/var/log/apache2
- ./wp_000-default.conf:/etc/apache2/sites-available/000-default.conf:ro
- ./default-ssl.conf:/etc/apache2/sites-available/default-ssl.conf:ro
- ./mpm_prefork.conf:/etc/apache2/mpm_prefork.conf:ro
- ./mpm_worker.conf:/etc/apache2/mpm_worker.conf:ro
- ./mpm_event.conf:/etc/apache2/mpm_event.conf:ro
- ./wp_ports.conf:/etc/apache2/ports.conf:ro
- ./docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh:ro
- /etc/lego/certificates/hollandnumerics.org.uk.crt:/etc/ssl/certs/hollandnumerics.org.uk.crt:ro
- /etc/lego/certificates/hollandnumerics.org.uk.key:/etc/ssl/certs/hollandnumerics.org.uk.key:ro
mpm_prefork.conf:
StartServers 20
MaxRequestWorkers 40
MinSpareServers 1
MaxSpareServers 40
MaxConnectionsPerChild 0
ServerLimit 40
MaxClients 40
docker-entrypoint.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
# Apache gets grumpy about PID files pre-existing
rm -f /var/log/apache2/httpd.pid
if [[ "$1" == apache2* ]] || [ "$1" = 'php-fpm' ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-www-data}"
group="${APACHE_RUN_GROUP:-www-data}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
pound='#'
user="${user#$pound}"
group="${group#$pound}"
;;
*) # php-fpm
user='www-data'
group='www-data'
;;
esac
else
user="$uid"
group="$gid"
fi
if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then
# if the directory exists and WordPress doesn't appear to be installed AND the permissions of it are root:root, let's chown it (likely a Docker-created directory)
if [ "$uid" = '0' ] && [ "$(stat -c '%u:%g' .)" = '0:0' ]; then
chown "$user:$group" .
fi
echo >&2 "WordPress not found in $PWD - copying now..."
if [ -n "$(find -mindepth 1 -maxdepth 1 -not -name wp-content)" ]; then
echo >&2 "WARNING: $PWD is not empty! (copying anyhow)"
fi
sourceTarArgs=(
--create
--file -
--directory /usr/src/wordpress
--owner "$user" --group "$group"
)
targetTarArgs=(
--extract
--file -
)
if [ "$uid" != '0' ]; then
# avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted"
targetTarArgs+=( --no-overwrite-dir )
fi
# loop over "pluggable" content in the source, and if it already exists in the destination, skip it
# https://github.com/docker-library/wordpress/issues/506 ("wp-content" persisted, "akismet" updated, WordPress container restarted/recreated, "akismet" downgraded)
for contentPath in \
/usr/src/wordpress/.htaccess \
/usr/src/wordpress/wp-content/*/*/ \
; do
contentPath="${contentPath%/}"
[ -e "$contentPath" ] || continue
contentPath="${contentPath#/usr/src/wordpress/}" # "wp-content/plugins/akismet", etc.
if [ -e "$PWD/$contentPath" ]; then
echo >&2 "WARNING: '$PWD/$contentPath' exists! (not copying the WordPress version)"
sourceTarArgs+=( --exclude "./$contentPath" )
fi
done
tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}"
echo >&2 "Complete! WordPress has been successfully copied to $PWD"
fi
wpEnvs=( "${!WORDPRESS_@}" )
if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then
for wpConfigDocker in \
wp-config-docker.php \
/usr/src/wordpress/wp-config-docker.php \
; do
if [ -s "$wpConfigDocker" ]; then
echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})"
# using "awk" to replace all instances of "put your unique phrase here" with a properly unique string (for AUTH_KEY and friends to have safe defaults if they aren't specified with environment variables)
awk '
/put your unique phrase here/ {
cmd = "head -c1m /dev/urandom | sha1sum | cut -d\\ -f1"
cmd | getline str
close(cmd)
gsub("put your unique phrase here", str)
}
{ print }
' "$wpConfigDocker" > wp-config.php
if [ "$uid" = '0' ]; then
# attempt to ensure that wp-config.php is owned by the run user
# could be on a filesystem that doesn't allow chown (like some NFS setups)
chown "$user:$group" wp-config.php || true
fi
break
fi
done
fi
fi
a2enmod ssl
a2ensite default-ssl.conf
service apache2 restart
service apache2 stop
exec "$@"
wp-php-apache Dockerfile:
FROM wordpress:6.9.4-php8.4-apache
mariadb Dockerfile:
FROM mariadb:10.11
RUN chmod 1777 /tmp
What changes should be made to use php-fpm and mpm_event instead?
Thanks in advance…Phil