# Apache MPM tuning for memory-limited WordPress containers. # Bind-mounted read-only by the gateway into the container at # /etc/apache2/conf-enabled/zz-srv-tuning.conf, so the worker cap survives # container recreates (including image upgrades). Edit on the host and reload # Apache inside the container to apply: # docker exec -wordpress apache2ctl graceful # # WHY THIS EXISTS (incident 2026-07-02): # These containers run under a 1 GB memory cgroup (docker run --memory 1g). # The stock wordpress:latest image ships mpm_prefork with MaxRequestWorkers # 150. Under load (bot 404 crawls, xmlrpc.php abuse, wp-cron loopback pile-ups) # Apache spawns workers until the 1 GB cgroup is exhausted; the kernel OOM # killer then fires in a tight loop (~1 kill / 10 s). That (a) degrades the # site and (b) spams the HOST kernel log with a full cgroup process-table dump # per kill — /var/log/kern.log reached 1.2 GB in under 5 days. # # Capping workers converts an "OOM-kill storm" into graceful degradation: # under overload Apache queues then 503s instead of blowing the memory limit. # ~18 workers * ~50 MB RSS ~= 0.9 GB, leaving headroom under the 1 GB cap. # MaxConnectionsPerChild recycles workers to bound long-run memory growth. # # This is the SAME class of problem seen on the Flywheel-hosted sites (slow-404 # crawl + wp-cron worker exhaustion); the durable answer there and here is to # bound the worker pool so traffic spikes can't exhaust memory. StartServers 3 MinSpareServers 3 MaxSpareServers 6 MaxRequestWorkers 18 MaxConnectionsPerChild 1000