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