🗃️ Committing everything that changed 🗃️

rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
This commit is contained in:
casjay
2025-09-05 18:39:12 -04:00
parent 51007bc2ea
commit fbb67569dd
2 changed files with 217 additions and 25 deletions

View File

@@ -93,7 +93,7 @@ DATABASE_DIR="" # set database dir
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Healthcheck variables # Healthcheck variables
HEALTH_ENABLED="yes" # enable healthcheck [yes/no] HEALTH_ENABLED="yes" # enable healthcheck [yes/no]
SERVICES_LIST="tini" # comma seperated list of processes for the healthcheck SERVICES_LIST="" # auto-detected from init.d scripts - can be overridden
HEALTH_ENDPOINTS="" # url endpoints: [http://localhost/health,http://localhost/test] HEALTH_ENDPOINTS="" # url endpoints: [http://localhost/health,http://localhost/test]
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Update path var # Update path var
@@ -341,7 +341,14 @@ if [ "$ENTRYPOINT_FIRST_RUN" != "no" ]; then
fi fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# if no pid assume container restart # if no pid assume container restart
[ -f "$ENTRYPOINT_PID_FILE" ] && [ -f "/run/__start_init_scripts.pid" ] || START_SERVICES="yes" # if no pid assume container restart - clean stale files on restart
if [ ! -f "$ENTRYPOINT_PID_FILE" ]; then
START_SERVICES="yes"
# Clean stale pid files from previous container runs
rm -f /run/__start_init_scripts.pid /run/init.d/*.pid /run/*.pid
elif [ ! -f "/run/__start_init_scripts.pid" ]; then
START_SERVICES="yes"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[ "$ENTRYPOINT_MESSAGE" = "yes" ] && __printf_space "40" "Container ip address is:" "$CONTAINER_IP4_ADDRESS" [ "$ENTRYPOINT_MESSAGE" = "yes" ] && __printf_space "40" "Container ip address is:" "$CONTAINER_IP4_ADDRESS"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@@ -70,7 +70,108 @@ __clean_variables() {
printf '%s' "$var" | grep -v '^$' printf '%s' "$var" | grep -v '^$'
} }
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
__no_exit() { [ -f "/run/no_exit.pid" ] || exec bash -c "trap 'sleep 1;rm -Rf /run/*;/tmp/*;/data/logs/start.log;exit 0' TERM INT;(while true; do echo $$ >/run/no_exit.pid;tail -qf /data/logs/start.log 2>/dev/null||sleep 20; done) & wait"; } # Auto-detect services from init.d scripts
__auto_detect_services() {
local discovered_services="tini" # Always include tini as init
local init_dir="/usr/local/etc/docker/init.d"
if [ -d "$init_dir" ]; then
for script in "$init_dir"/*.sh; do
if [ -f "$script" ]; then
# Extract service name from filename (remove number prefix and .sh suffix)
local service=$(basename "$script" | sed 's/^[0-9]*-//;s|\.sh$||g')
discovered_services="$discovered_services,$service"
fi
done
fi
echo "$discovered_services"
}
# Enhanced __no_exit function with service monitoring and proper failure handling
__no_exit() {
local monitor_services="${SERVICES_LIST:-$(__auto_detect_services)}"
local check_interval="${SERVICE_CHECK_INTERVAL:-30}"
local max_failures="${MAX_SERVICE_FAILURES:-3}"
declare -A failure_counts
# Initialize failure counters
IFS=',' read -ra services <<< "$monitor_services"
for service in "${services[@]}"; do
service="${service// /}" # trim whitespace
[ -n "$service" ] && failure_counts["$service"]=0
done
echo "🔍 Starting service supervisor - monitoring: $monitor_services"
echo "⏰ Check interval: ${check_interval}s, Max failures: $max_failures per service"
# Set up trap to handle termination gracefully
trap 'echo "🛑 Container terminating - cleaning up services"; kill $(jobs -p) 2>/dev/null; rm -f /run/*.pid /run/init.d/*.pid; exit 0' TERM INT EXIT
# Main supervision loop
while true; do
local failed_services=""
local running_services=""
local critical_failure=false
# Check each monitored service
IFS=',' read -ra services <<< "$monitor_services"
for service in "${services[@]}"; do
service="${service// /}" # trim whitespace
[ -z "$service" ] && continue
if __pgrep "$service" >/dev/null 2>&1; then
running_services="$running_services $service"
failure_counts["$service"]=0 # reset failure count on success
else
failed_services="$failed_services $service"
failure_counts["$service"]=$((${failure_counts["$service"]:-0} + 1))
echo "⚠️ Service '$service' not running (failure ${failure_counts["$service"]}/$max_failures)"
# Check if we've exceeded max failures for this service
if [ ${failure_counts["$service"]} -ge $max_failures ]; then
echo "💥 Service '$service' failed $max_failures times - this is critical!"
critical_failure=true
fi
fi
done
# If we have critical failures, terminate the container
if [ "$critical_failure" = true ]; then
echo "🚨 Critical service failure detected:"
echo " 💀 Dead services: $failed_services"
echo " ✅ Running services: $running_services"
echo " 🔄 Container will terminate to allow restart by orchestrator"
# Write final status to log
{
echo "$(date): CRITICAL FAILURE - Container terminating"
echo "Dead services: $failed_services"
echo "Running services: $running_services"
} >> "/data/logs/start.log"
# Terminate the container (PID 1 is the init process)
kill -TERM 1
exit 1
fi
# Log status periodically (every 10 cycles = ~5 minutes with 30s interval)
if [ $(($(date +%s) % 300)) -lt $check_interval ]; then
echo "📊 Service status - Running:$running_services Failed:$failed_services"
# Write to start.log for backward compatibility
echo "$(date): Services running:$running_services failed:$failed_services" >> "/data/logs/start.log"
fi
sleep "$check_interval"
done &
# Keep the original behavior for log tailing (for compatibility)
[ -f "/data/logs/start.log" ] && tail -f "/data/logs/start.log" >/dev/null 2>&1 &
# Wait for background processes
wait
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
__trim() { __trim() {
local var="${*//;/ }" local var="${*//;/ }"
@@ -642,46 +743,130 @@ __exec_command() {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Setup the server init scripts # Setup the server init scripts
__start_init_scripts() { __start_init_scripts() {
set -e
trap 'echo "❌ Fatal error in service startup - killing container"; rm -f /run/__start_init_scripts.pid; kill -TERM 1' ERR
[ "$1" = " " ] && shift 1 [ "$1" = " " ] && shift 1
[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -o pipefail -x$DEBUGGER_OPTIONS || set -o pipefail [ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -o pipefail -x$DEBUGGER_OPTIONS || set -o pipefail
local retPID=""
local basename="" local basename=""
local init_pids="" local init_pids=""
local retstatus="0" local retstatus="0"
local initStatus="0" local initStatus="0"
local failed_services=""
local successful_services=""
local init_dir="${1:-/usr/local/etc/docker/init.d}" local init_dir="${1:-/usr/local/etc/docker/init.d}"
local init_count="$(ls -A "$init_dir"/* 2>/dev/null | grep -v '\.sample' | wc -l)" local init_count="$(find "$init_dir" -name "*.sh" 2>/dev/null | wc -l)"
touch /run/__start_init_scripts.pid
mkdir -p "/tmp" "/run" "/run/init.d" "/usr/local/etc/docker/exec" if [ -n "$SERVICE_DISABLED" ]; then
chmod -R 777 "/tmp" "/run" "/run/init.d" "/usr/local/etc/docker/exec" echo "$SERVICE_DISABLED is disabled"
unset SERVICE_DISABLED
return 0
fi
echo "🚀 Starting container services initialization"
echo "📂 Init directory: $init_dir"
echo "📊 Services to start: $init_count"
# Create a fresh PID file to track this startup session
echo $$ > /run/__start_init_scripts.pid
mkdir -p "/tmp" "/run" "/run/init.d" "/usr/local/etc/docker/exec" "/data/logs/init"
chmod -R 777 "/tmp" "/run" "/run/init.d" "/usr/local/etc/docker/exec" "/data/logs/init"
if [ "$init_count" -eq 0 ] || [ ! -d "$init_dir" ]; then if [ "$init_count" -eq 0 ] || [ ! -d "$init_dir" ]; then
mkdir -p "/data/logs/init" echo "⚠️ No init scripts found in $init_dir"
while :; do echo "Running: $(date)" >"/data/logs/init/keep_alive" && sleep 3600; done & # Still create a minimal keep-alive for containers without services
while true; do
echo "$(date): No services - container keep-alive" >> "/data/logs/start.log"
sleep 3600
done &
else else
echo "📋 Found $init_count service scripts to execute"
if [ -d "$init_dir" ]; then if [ -d "$init_dir" ]; then
[ -f "$init_dir/service.sample" ] && __rm "$init_dir"/*.sample # Remove sample files
chmod -Rf 755 "$init_dir"/*.sh find "$init_dir" -name "*.sample" -delete 2>/dev/null
# Make scripts executable
find "$init_dir" -name "*.sh" -exec chmod 755 {} \; 2>/dev/null
# Execute scripts in numerical/alphabetical order
for init in "$init_dir"/*.sh; do for init in "$init_dir"/*.sh; do
if [ -x "$init" ]; then if [ -x "$init" ]; then
name="$(basename "$init")" basename="$(basename "$init")"
service="$(printf '%s' "$name" | sed 's/^[^-]*-//;s|.sh$||g')" service="$(printf '%s' "$basename" | sed 's/^[0-9]*-//;s|\.sh$||g')"
printf '# - - - executing file: %s\n' "$init"
eval "$init" && sleep 5 || sleep 3 printf '\n🔧 Executing service script: %s (service: %s)\n' "$init" "$service"
# Execute the init script and capture its exit code
if eval "$init"; then
sleep 5 # Give service more time to start properly
# Verify the service actually started by checking for PID
retPID=$(__get_pid "$service") retPID=$(__get_pid "$service")
if [ -n "$retPID" ]; then if [ -n "$retPID" ]; then
initStatus="0" initStatus="0"
printf '# - - - %s has been started - pid: %s\n' "$service" "${retPID:-error}" successful_services="$successful_services $service"
printf '✅ Service %s started successfully - PID: %s\n' "$service" "$retPID"
else else
# Service script succeeded but no PID found - this is suspicious
initStatus="1" initStatus="1"
printf '# - - - %s has falied to start - check log %s\n' "$service" "docker log $CONTAINER_NAME" failed_services="$failed_services $service"
printf '⚠️ Service %s script completed but no PID found\n' "$service"
fi fi
echo "" else
# Service script failed
script_exit_code="$?"
initStatus="1"
failed_services="$failed_services $service"
printf '❌ Init script %s failed with exit code %s\n' "$init" "$script_exit_code"
fi fi
else
printf '⚠️ Script %s is not executable, skipping\n' "$init"
fi
retstatus=$(($retstatus + $initStatus)) retstatus=$(($retstatus + $initStatus))
printf '\n'
done done
printf '📊 Service startup summary:\n'
printf ' ✅ Successful: %s\n' "${successful_services:-none}"
printf ' ❌ Failed: %s\n' "${failed_services:-none}"
printf ' 📈 Total status code: %s\n' "$retstatus"
# If any services failed to start, terminate the container immediately
if [ $retstatus -gt 0 ]; then
echo ""
echo "💥 Service startup failures detected!"
echo "🔄 Container will terminate to allow orchestrator restart"
echo "📝 Check container logs for detailed failure information"
# Write failure information to log
{
echo "$(date): SERVICE STARTUP FAILURE"
echo "Successful services: $successful_services"
echo "Failed services: $failed_services"
echo "Total errors: $retstatus"
} >> "/data/logs/start.log"
# Clean up and exit
rm -f /run/__start_init_scripts.pid
exit $retstatus
fi fi
fi fi
printf '%s\n' "$SERVICE_NAME started on $(date)" >"/data/logs/start.log" fi
# Write successful startup status to log
{
echo "$(date): Container startup completed successfully"
echo "Active services: $successful_services"
[ -n "$failed_services" ] && echo "Failed services: $failed_services"
echo "Status code: $retstatus"
} >> "/data/logs/start.log"
printf '\n🎉 All services initialized successfully!\n'
printf '🔍 Service monitoring will now begin...\n\n'
return $retstatus return $retstatus
} }
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1200,6 +1385,6 @@ export ENTRYPOINT_DATA_INIT_FILE DATA_DIR_INITIALIZED ENTRYPOINT_CONFIG_INIT_FIL
export ENTRYPOINT_PID_FILE ENTRYPOINT_INIT_FILE ENTRYPOINT_FIRST_RUN export ENTRYPOINT_PID_FILE ENTRYPOINT_INIT_FILE ENTRYPOINT_FIRST_RUN
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# export the functions # export the functions
export -f __get_pid __start_init_scripts __is_running __certbot __update_ssl_certs __create_ssl_cert export -f __get_pid __start_init_scripts __is_running __certbot __update_ssl_certs __create_ssl_cert __no_exit __auto_detect_services
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# end of functions # end of functions