diff --git a/configs/default-index.conf b/configs/default-index.conf index 69f97ae..68cfa42 100644 --- a/configs/default-index.conf +++ b/configs/default-index.conf @@ -1,13 +1,2 @@ DirectoryIndex index.html index.htm index.php -Alias "/ping" "/var/www/html" - - - StartServers 2 - MinSpareThreads 10 - MaxSpareThreads 25 - ThreadLimit 64 - ThreadsPerChild 25 - MaxRequestWorkers 75 - ServerLimit 3 - MaxConnectionsPerChild 1000 - \ No newline at end of file +Alias "/ping" "/var/www/html" \ No newline at end of file diff --git a/scripts/create-apache-mpm-config.sh b/scripts/create-apache-mpm-config.sh new file mode 100755 index 0000000..13ba9c7 --- /dev/null +++ b/scripts/create-apache-mpm-config.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Generate Apache MPM event tuning config at runtime using detect-memory.sh values. + +cat < /etc/httpd/conf.d/mpm-tuning.conf + + StartServers ${APACHE_START_SERVERS} + MinSpareThreads ${APACHE_MIN_SPARE_THREADS} + MaxSpareThreads ${APACHE_MAX_SPARE_THREADS} + ThreadLimit 64 + ThreadsPerChild 25 + MaxRequestWorkers ${APACHE_MAX_REQUEST_WORKERS} + ServerLimit ${APACHE_SERVER_LIMIT} + MaxConnectionsPerChild ${APACHE_MAX_CONNECTIONS_PER_CHILD} + +EOF + +exit 0 diff --git a/scripts/create-php-config.sh b/scripts/create-php-config.sh index 7526a47..5fa253e 100644 --- a/scripts/create-php-config.sh +++ b/scripts/create-php-config.sh @@ -12,12 +12,15 @@ listen = /run/php-fpm/www.sock listen.owner = apache listen.group = apache -pm = dynamic -pm.max_children = 5 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 3 -pm.max_requests = 500 +pm = ${PHP_FPM_PM} +pm.max_children = ${PHP_FPM_MAX_CHILDREN} +pm.max_requests = ${PHP_FPM_MAX_REQUESTS} +pm.process_idle_timeout = ${PHP_FPM_PROCESS_IDLE_TIMEOUT} + +; Settings used when pm = dynamic (fallback if user overrides FPM_PM) +pm.start_servers = ${PHP_FPM_START_SERVERS} +pm.min_spare_servers = ${PHP_FPM_MIN_SPARE} +pm.max_spare_servers = ${PHP_FPM_MAX_SPARE} slowlog = /etc/httpd/logs/error_log request_slowlog_timeout = 3s @@ -28,4 +31,4 @@ php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache EOF -exit 0 \ No newline at end of file +exit 0 diff --git a/scripts/detect-memory.sh b/scripts/detect-memory.sh new file mode 100755 index 0000000..bf7f5d7 --- /dev/null +++ b/scripts/detect-memory.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# detect-memory.sh — Detect container memory and calculate tuning parameters. +# Must be sourced (not executed) so variables are available to the caller. + +# --- Memory detection (cgroups v2 → v1 → /proc/meminfo → fallback) --- +CONTAINER_MEMORY_BYTES="" + +# cgroups v2 +if [ -f /sys/fs/cgroup/memory.max ]; then + val=$(cat /sys/fs/cgroup/memory.max 2>/dev/null) + if [ "$val" != "max" ] && [ -n "$val" ]; then + CONTAINER_MEMORY_BYTES=$val + fi +fi + +# cgroups v1 +if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then + val=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null) + # Values near page-aligned max (like 9223372036854771712) mean "no limit" + if [ -n "$val" ] && [ "$val" -lt 8589934592000 ] 2>/dev/null; then + CONTAINER_MEMORY_BYTES=$val + fi +fi + +# /proc/meminfo (host memory — used when no cgroup limit is set) +if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /proc/meminfo ]; then + mem_kb=$(awk '/^MemTotal:/ {print $2}' /proc/meminfo) + if [ -n "$mem_kb" ]; then + CONTAINER_MEMORY_BYTES=$((mem_kb * 1024)) + fi +fi + +# Fallback +if [ -z "$CONTAINER_MEMORY_BYTES" ]; then + CONTAINER_MEMORY_BYTES=$((512 * 1024 * 1024)) +fi + +CONTAINER_MEMORY_MB=$((CONTAINER_MEMORY_BYTES / 1024 / 1024)) + +# --- Budget calculation --- +OS_RESERVE_MB=50 +FIXED_PROCESS_MB=50 +DEV_OVERHEAD_MB=0 +if [ "$environment" = "DEV" ]; then + DEV_OVERHEAD_MB=125 +fi + +AVAILABLE_MB=$((CONTAINER_MEMORY_MB - OS_RESERVE_MB - FIXED_PROCESS_MB - DEV_OVERHEAD_MB)) +if [ "$AVAILABLE_MB" -lt 60 ]; then + AVAILABLE_MB=60 +fi + +PHP_BUDGET_MB=$((AVAILABLE_MB * 80 / 100)) +APACHE_BUDGET_MB=$((AVAILABLE_MB * 20 / 100)) + +# --- PHP-FPM parameters --- +PHP_WORKER_ESTIMATE_MB=${PHP_WORKER_ESTIMATE_MB:-60} + +calc_max_children=$((PHP_BUDGET_MB / PHP_WORKER_ESTIMATE_MB)) +# Floor at 2, cap at 50 +if [ "$calc_max_children" -lt 2 ]; then + calc_max_children=2 +fi +if [ "$calc_max_children" -gt 50 ]; then + calc_max_children=50 +fi + +PHP_FPM_PM=${FPM_PM:-ondemand} +PHP_FPM_MAX_CHILDREN=${FPM_MAX_CHILDREN:-$calc_max_children} +PHP_FPM_PROCESS_IDLE_TIMEOUT=${FPM_PROCESS_IDLE_TIMEOUT:-10s} +PHP_FPM_MAX_REQUESTS=${FPM_MAX_REQUESTS:-500} + +# Dynamic mode fallbacks (used if user overrides FPM_PM=dynamic) +PHP_FPM_START_SERVERS=${FPM_START_SERVERS:-2} +PHP_FPM_MIN_SPARE=${FPM_MIN_SPARE_SERVERS:-1} +PHP_FPM_MAX_SPARE=${FPM_MAX_SPARE_SERVERS:-3} + +# --- Apache MPM parameters --- +# ServerLimit: roughly 1 process per ~25 workers, floor 2, cap 16 +calc_server_limit=$((APACHE_BUDGET_MB / 30)) +if [ "$calc_server_limit" -lt 2 ]; then + calc_server_limit=2 +fi +if [ "$calc_server_limit" -gt 16 ]; then + calc_server_limit=16 +fi + +# MaxRequestWorkers: ServerLimit * ThreadsPerChild (25) +calc_max_request_workers=$((calc_server_limit * 25)) +if [ "$calc_max_request_workers" -gt 400 ]; then + calc_max_request_workers=400 +fi + +# StartServers: 1 for ≤1GB, 2 for larger +calc_start_servers=1 +if [ "$CONTAINER_MEMORY_MB" -gt 1024 ]; then + calc_start_servers=2 +fi + +APACHE_START_SERVERS=${APACHE_START_SERVERS:-$calc_start_servers} +APACHE_SERVER_LIMIT=${APACHE_SERVER_LIMIT:-$calc_server_limit} +APACHE_MAX_REQUEST_WORKERS=${APACHE_MAX_REQUEST_WORKERS:-$calc_max_request_workers} +APACHE_MIN_SPARE_THREADS=${APACHE_MIN_SPARE_THREADS:-5} +APACHE_MAX_SPARE_THREADS=${APACHE_MAX_SPARE_THREADS:-15} +APACHE_MAX_CONNECTIONS_PER_CHILD=${APACHE_MAX_CONNECTIONS_PER_CHILD:-3000} + +# --- Export all variables --- +export CONTAINER_MEMORY_MB +export PHP_FPM_PM PHP_FPM_MAX_CHILDREN PHP_FPM_PROCESS_IDLE_TIMEOUT PHP_FPM_MAX_REQUESTS +export PHP_FPM_START_SERVERS PHP_FPM_MIN_SPARE PHP_FPM_MAX_SPARE +export APACHE_START_SERVERS APACHE_SERVER_LIMIT APACHE_MAX_REQUEST_WORKERS +export APACHE_MIN_SPARE_THREADS APACHE_MAX_SPARE_THREADS APACHE_MAX_CONNECTIONS_PER_CHILD diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 3010990..77acc7e 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -23,8 +23,12 @@ docker_network=$(ip addr show |grep eth0 |grep inet |awk -F " " {'print $2'}) echo "RemoteIPInternalProxy $docker_network" >> /etc/httpd/conf.d/remoteip.conf # /scripts/install-php$PHPVER.sh +source /scripts/detect-memory.sh +echo "Container memory: ${CONTAINER_MEMORY_MB}MB | PHP-FPM pm=${PHP_FPM_PM} max_children=${PHP_FPM_MAX_CHILDREN} | Apache workers=${APACHE_MAX_REQUEST_WORKERS}" + /scripts/create-vhost.sh /scripts/create-php-config.sh +/scripts/create-apache-mpm-config.sh if [ -f /etc/httpd/conf.d/ssl.conf ]; then mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak