#!/usr/bin/env bash export CONTAINER_ROLE="httpd_only" if [ -z "$environment" ]; then environment="PROD" fi # Generate self-signed SSL cert if not already present if [ ! -f /etc/pki/tls/certs/localhost.crt ]; then openssl req -newkey rsa:2048 -nodes \ -keyout /etc/pki/tls/private/localhost.key \ -x509 -days 3650 -subj "/CN=localhost" \ -out /etc/pki/tls/certs/localhost.crt fi # Create log directory mkdir -p /var/log/httpd # Remove default configs that conflict rm -f /etc/httpd/conf.d/userdir.conf # Configure RemoteIP for Docker network docker_network=$(ip addr show | grep eth0 | grep inet | awk -F " " '{print $2}') if [ -n "$docker_network" ]; then echo "RemoteIPInternalProxy $docker_network" >> /etc/httpd/conf.d/remoteip.conf fi # Detect memory and calculate Apache MPM tuning source /scripts/detect-memory.sh echo "Container memory: ${CONTAINER_MEMORY_MB}MB | Apache workers=${APACHE_MAX_REQUEST_WORKERS} | Role=${CONTAINER_ROLE}" # Generate MPM tuning config /scripts/create-apache-mpm-config.sh # Write SSL global config (matches standalone CAC behavior) cat <<'EOF' > /etc/httpd/conf.d/ssl-global.conf Listen 443 https SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog SSLSessionCache shmcb:/run/httpd/sslcache(512000) SSLSessionCacheTimeout 300 SSLCryptoDevice builtin EOF # Disable the default ssl.conf if present (we use per-vhost SSL) if [ -f /etc/httpd/conf.d/ssl.conf ]; then mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak fi # Ensure vhosts directory exists and is included mkdir -p /etc/httpd/conf.d/vhosts if ! grep -q 'IncludeOptional conf.d/vhosts/' /etc/httpd/conf/httpd.conf; then echo 'IncludeOptional conf.d/vhosts/*.conf' >> /etc/httpd/conf/httpd.conf fi # Start Apache /usr/sbin/httpd -k start # Start cron for log rotation /usr/sbin/crond # Graceful shutdown. bash is PID 1 here, and PID 1 only receives signals it # has a handler for, so without this trap `docker stop`'s SIGTERM was dropped: # docker waited the full 10s and SIGKILLed apache mid-request (exit 137), for # every site on the host at once. graceful-stop (WINCH) lets in-flight requests # finish; after 7s it falls back to TERM. Timeouts sum to < 10s so this # completes inside docker's default stop timeout. source /scripts/stop-services.sh TAIL_PID="" SLEEP_PID="" shutdown() { trap - TERM INT echo "entrypoint-shared-httpd: received stop signal, shutting down" stop_service httpd /etc/httpd/run/httpd.pid WINCH 7 '^/usr/sbin/httpd' stop_service crond /run/crond.pid TERM 1 '^/usr/sbin/crond' [ -n "$SLEEP_PID" ] && kill "$SLEEP_PID" 2>/dev/null [ -n "$TAIL_PID" ] && kill "$TAIL_PID" 2>/dev/null exit 0 } trap shutdown TERM INT # Tail Apache logs to docker logs. # Use a loop to pick up new log files as vhosts are added. # tail -f only watches files that exist at start time. touch /var/log/httpd/error_log while true; do LOG_FILES=$(find /var/log/httpd/ -name '*.log' -o -name '*_log' 2>/dev/null | sort) if [ -n "$TAIL_PID" ]; then kill "$TAIL_PID" 2>/dev/null wait "$TAIL_PID" 2>/dev/null fi tail -f $LOG_FILES & TAIL_PID=$! # Re-check for new log files every 60 seconds. Background + `wait` (not a # foreground sleep) so a stop signal runs the trap immediately instead of # after up to 60s. sleep 60 & SLEEP_PID=$! wait "$SLEEP_PID" done