Files
almalinux/rootfs/usr/local/etc/docker/functions/entrypoint.sh
casjay cce1fe8739
Some checks are pending
almalinux-10-dev / almalinux-10-dev (push) Waiting to run
almalinux-10 / almalinux-10 (push) Waiting to run
almalinux-8-dev / almalinux-8-dev (push) Waiting to run
almalinux-8 / almalinux-8 (push) Waiting to run
almalinux-9-dev / almalinux-9-dev (push) Waiting to run
almalinux-9 / almalinux-9 (push) Waiting to run
almalinux / release-almalinux (push) Waiting to run
🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-30 18:27:25 -05:00

1719 lines
68 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# shellcheck shell=bash
# - - - - - - - - - - - - - - - - - - - - - - - - -
##@Version : 202511301726-git
# @@Author : Jason Hempstead
# @@Contact : git-admin@casjaysdev.pro
# @@License : LICENSE.md
# @@ReadME : docker-entrypoint --help
# @@Copyright : Copyright: (c) 2023 Jason Hempstead, Casjays Developments
# @@Created : Sunday, Sep 03, 2023 01:40 EDT
# @@File : docker-entrypoint
# @@Description : functions for my docker containers
# @@Changelog : newScript
# @@TODO : Refactor code
# @@Other :
# @@Resource :
# @@Terminal App : no
# @@sudo/root : no
# @@Template : functions/docker-entrypoint
# - - - - - - - - - - - - - - - - - - - - - - - - -
# shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329
# - - - - - - - - - - - - - - - - - - - - - - - - -
# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
if [ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ]; then
export DEBUGGER_OPTIONS="$(<"/config/.debug")"
fi
if [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; then
set -xo pipefail -x$DEBUGGER_OPTIONS
export DEBUGGER="on"
else
set -o pipefail
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
__remove_extra_spaces() { sed 's/\( \)*/\1/g;s|^ ||g'; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__printf_space() {
local pad=$(printf '%0.1s' " "{1..60})
local padlength=$1
local string1="$2"
local string2="$3"
local message
message+="$(printf '%s' "$string1") "
message+="$(printf '%*.*s' 0 $((padlength - ${#string1} - ${#string2})) "$pad") "
message+="$(printf '%s\n' "$string2") "
printf '%s\n' "$message"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__mkdir() {
if [ -n "$1" ]; then
mkdir -p "$@" 2>/dev/null || true
fi
}
__rm() {
if [ -n "$1" ] && [ -e "$1" ]; then
rm -Rf "${1:?}" 2>/dev/null || true
fi
}
__grep_test() {
if grep -sh "$1" "$2" 2>/dev/null | grep -qwF "${3:-$1}"; then
return 0
else
return 1
fi
}
__netstat() {
if [ -f "$(type -P netstat 2>/dev/null)" ]; then
netstat "$@" 2>/dev/null
else
return 10
fi
}
__cd() {
if [ ! -d "$1" ]; then
mkdir -p "$1" 2>/dev/null || return 1
fi
builtin cd "$1" || return 1
}
__is_in_file() {
if [ -e "$2" ] && grep -Rsq "$1" "$2" 2>/dev/null; then
return 0
else
return 1
fi
}
__curl() {
if curl -q -sfI --max-time 3 -k -o /dev/null "$@" 2>/dev/null; then
return 0
else
return 10
fi
}
__find() {
if find "$1" -mindepth 1 -type ${2:-f,d} 2>/dev/null | grep '.'; then
return 0
else
return 10
fi
}
__pcheck() {
if [ -n "$(which pgrep 2>/dev/null)" ] && pgrep -x "$1" &>/dev/null; then
return 0
else
return 10
fi
}
__file_exists_with_content() {
if [ -n "$1" ] && [ -f "$1" ] && [ -s "$1" ]; then
return 0
else
return 2
fi
}
__sed() {
if sed -i 's|'$1'|'$2'|g' "$3" 2>/dev/null; then
return 0
elif sed -i "s|$1|$2|g" "$3" 2>/dev/null; then
return 0
else
return 0
fi
}
__ps() {
if [ -f "$(type -P ps 2>/dev/null)" ]; then
if ps "$@" 2>/dev/null | sed 's|:||g' | grep -Fw " ${1:-$SERVICE_NAME}$"; then
return 0
else
return 10
fi
else
return 10
fi
}
__is_dir_empty() {
if [ -n "$1" ]; then
if [ "$(ls -A "$1" 2>/dev/null | wc -l)" -eq 0 ]; then
return 0
else
return 1
fi
else
return 1
fi
}
__get_ip6() {
local ip6
ip6="$(ip a 2>/dev/null | grep -w 'inet6' | awk '{print $2}' | grep -vE '^::1|^fe' | sed 's|/.*||g' | head -n1 | grep '.')"
if [ -n "$ip6" ]; then
echo "$ip6"
else
echo ''
fi
}
__get_ip4() {
local ip4
ip4="$(ip a 2>/dev/null | grep -w 'inet' | awk '{print $2}' | grep -vE '^127.0.0' | sed 's|/.*||g' | head -n1 | grep '.')"
if [ -n "$ip4" ]; then
echo "$ip4"
else
echo '127.0.0.1'
fi
}
__find_and_remove() {
find "${2:-/etc}" -iname "$1" -exec rm -Rfv {} \; 2>/dev/null || true
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__pgrep() {
local count=3
local srvc="${1:-SERVICE_NAME}"
local found=0
if [ -z "$srvc" ] || [ "$srvc" = "SERVICE_NAME" ]; then
return 10
fi
while [ $count -ge 0 ]; do
if pgrep -x "$srvc" >/dev/null 2>&1; then
found=1
break
elif pgrep -f "$srvc" >/dev/null 2>&1; then
found=1
break
elif ps -ef 2>/dev/null | grep -v grep | grep -qw "$srvc"; then
found=1
break
fi
if [ $count -gt 0 ]; then
sleep 1
fi
count=$((count - 1))
done
if [ $found -eq 1 ]; then
return 0
else
return 10
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_file_relative() {
if [ ! -e "$1" ]; then
return 0
fi
find "$1"/* -not -path '*env/*' -not -path '.git*' -type f 2>/dev/null | sed 's|'$1'/||g' | sort -u | grep -v '^$' | grep '.' || true
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_directory_relative() {
if [ ! -d "$1" ]; then
return 0
fi
find "$1"/* -not -path '*env/*' -not -path '.git*' -type d 2>/dev/null | sed 's|'$1'/||g' | sort -u | grep -v '^$' | grep '.' || true
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__pid_exists() {
local result=""
result="$(ps -ax --no-header 2>/dev/null | sed 's/^[[:space:]]*//g' | awk -F' ' '{print $1}' | sed 's|:||g' | grep '[0-9]' | sort -uV | grep "^$1$" 2>/dev/null || echo '')"
if [ -n "$result" ]; then
return 0
else
return 1
fi
}
__is_running() {
local result=""
result="$(ps -eo args --no-header 2>/dev/null | awk '{print $1,$2,$3}' | sed 's|:||g' | sort -u | grep -vE 'grep|COMMAND|awk|tee|ps|sed|sort|tail' | grep "$1" | grep "${2:-^}" 2>/dev/null || echo '')"
if [ -n "$result" ]; then
return 0
else
return 1
fi
}
__get_pid() {
local result=""
result="$(ps -ax --no-header 2>/dev/null | sed 's/^[[:space:]]*//g;s|;||g;s|:||g' | awk '{print $1,$5}' | sed 's|:||g' | grep "$1$" | grep -v 'grep' | awk -F' ' '{print $1}' | grep '[0-9]' | sort -uV | head -n1 | grep '.' 2>/dev/null || echo '')"
if [ -n "$result" ]; then
echo "$result"
return 0
else
return 1
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__format_variables() { printf '%s\n' "${@//,/ }" | tr ' ' '\n' | sort -RVu | grep -v '^$' | tr '\n' ' ' | __clean_variables | grep '.' || return 0; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__clean_variables() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
var="$(printf '%s\n' "$var" | sed 's/\( \)*/\1/g;s|^ ||g')"
printf '%s' "$var" | grep -v '^$'
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__no_exit() {
local monitor_interval="${SERVICE_MONITOR_INTERVAL:-60}"
local failure_threshold="${SERVICE_FAILURE_THRESHOLD:-3}"
local monitor_services="${SERVICES_LIST:-tini}"
local failed_services=""
local failure_count=0
[ -f "/run/no_exit.pid" ] && return 0
exec bash -c "
trap 'echo \"Container shutdown requested\"; rm -f /run/no_exit.pid /run/*.pid; exit 0' TERM INT
echo \$\$ > /run/no_exit.pid
while true; do
if [ -n \"$monitor_services\" ] && [ \"$monitor_services\" != \"tini\" ]; then
for service in \$(echo \"$monitor_services\" | tr ',' ' '); do
if [ \"\$service\" != \"tini\" ] && ! pgrep -x \"\$service\" >/dev/null 2>&1; then
echo \"⚠️ Service \$service is not running\" >&2
failed_services=\"\$failed_services \$service\"
failure_count=\$((failure_count + 1))
fi
done
if [ \$failure_count -ge $failure_threshold ]; then
echo \"❌ Too many service failures (\$failure_count), exiting container\" >&2
exit 1
fi
if [ -n \"\$failed_services\" ]; then
echo \"⚠️ Failed services:\$failed_services\" >&2
failed_services=\"\"
fi
fi
sleep $monitor_interval
done &
wait
"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__trim() {
local var="${*//;/ }"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
var="$(echo "$var" | __remove_extra_spaces | sed "s| |; |g;s|;$| |g" | __remove_extra_spaces)"
printf '%s' "$var" | sed 's|;||g' | grep -v '^$'
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__banner() {
local message="$*"
local total_width=80
local content_width=$((total_width - 14)) # Account for "# - - - " and " - - - #"
printf '# - - - %-*s - - - #\n' "$content_width" "$message"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__service_banner() {
local icon="${1:-🔧}"
local message="${2:-Processing}"
local service="${3:-service}"
local full_message="$message $service"
local total_width=80
local content_width=$((total_width - 14)) # Account for "# - - - " and " - - - #"
local icon_width=2 # Most emojis are 2 chars wide
local text_width=$((content_width - icon_width * 2 - 2)) # Account for both icons and spaces
printf '# - - - %s %-*s %s - - - #\n' "$icon" "$text_width" "$full_message" "$icon"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_php_bin() { find -L '/usr'/*bin -maxdepth 4 -name 'php-fpm*' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_php_ini() { find -L '/etc' -maxdepth 4 -name 'php.ini' 2>/dev/null | head -n1 | sed 's|/php.ini||g' | grep '.' || echo ''; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_nginx_conf() { find -L '/etc' -maxdepth 4 -name 'nginx.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_caddy_conf() { find -L '/etc' -maxdepth 4 -type f -iname 'caddy.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_lighttpd_conf() { find -L '/etc' -maxdepth 4 -type f -iname 'lighttpd.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_cherokee_conf() { find -L '/etc' -maxdepth 4 -type f -iname 'cherokee.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_httpd_conf() { find -L '/etc' -maxdepth 4 -type f -iname 'httpd.conf' -o -iname 'apache2.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_mysql_conf() { find -L '/etc' -maxdepth 4 -type f -name 'my.cnf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_pgsql_conf() { find -L '/var/lib' '/etc' -maxdepth 8 -type f -name 'postgresql.conf' 2>/dev/null | head -n1 | grep '.' || echo ''; }
__find_couchdb_conf() { return; }
__find_mongodb_conf() { return; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__random_password() { cat "/dev/urandom" | tr -dc '0-9a-zA-Z' | head -c${1:-16} && echo ""; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_working_dir() {
local service_name="$SERVICE_NAME" # get service name
local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables
local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables
# set working directories
[ "$home" = "$workdir" ] && workdir=""
[ "$home" = "/root" ] && home="/tmp/$service_name"
[ -z "$home" ] && home="${workdir:-/tmp/$service_name}"
# Change to working directory
[ -n "$WORK_DIR" ] && [ -n "$EXEC_CMD_BIN" ] && workdir="$WORK_DIR"
[ -z "$WORK_DIR" ] && [ "$HOME" = "/root" ] && [ "$RUNAS_USER" != "root" ] && [ "$PWD" != "/tmp" ] && home="${workdir:-$home}"
[ -z "$WORK_DIR" ] && [ "$HOME" = "/root" ] && [ "$SERVICE_USER" != "root" ] && [ "$PWD" != "/tmp" ] && home="${workdir:-$home}"
# create needed directories
if [ -n "$home" ]; then
if [ ! -d "$home" ]; then
mkdir -p "$home"
fi
fi
if [ -n "$workdir" ]; then
if [ ! -d "$workdir" ]; then
mkdir -p "$workdir"
fi
fi
if [ "$SERVICE_USER" != "root" ] && [ -d "$home" ]; then
chmod -f 777 "$home"
fi
if [ "$SERVICE_USER" != "root" ] && [ -d "$workdir" ]; then
chmod -f 777 "$workdir"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# cd to dir
__cd "${workdir:-$home}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
echo "Setting the working directory to: $PWD"
# - - - - - - - - - - - - - - - - - - - - - - - - -
export WORK_DIR="$workdir" HOME="$home"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__exec_service() {
local count=6
echo "Starting $1"
eval "$@" 2>>/dev/stderr >>/data/logs/start.log &
while [ $count -ne 0 ]; do
sleep 3
if __pgrep $1; then
touch "/run/init.d/$1.pid"
break
else
count=$((count - 1))
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__update_ssl_certs() {
[ -f "/config/env/ssl.sh" ] && . "/config/env/ssl.sh"
if [ -f "$SSL_CERT" ] && [ -f "$SSL_KEY" ]; then
mkdir -p /etc/ssl
[ -f "$SSL_CA" ] && cp -Rf "$SSL_CA" "/etc/ssl/$SSL_CA"
[ -f "$SSL_KEY" ] && cp -Rf "$SSL_KEY" "/etc/ssl/$SSL_KEY"
[ -f "$SSL_CERT" ] && cp -Rf "$SSL_CERT" "/etc/ssl/$SSL_CERT"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__certbot() {
[ -n "$(type -P 'certbot')" ] || return 1
local options="$1"
local statusCode=0
local domain_list=""
local certbot_key_opts=""
local ADD_CERTBOT_DOMAINS=""
local CERTBOT_DOMAINS="${CERTBOT_DOMAINS:-$HOSTNAME}"
local CERT_BOT_MAIL="${CERT_BOT_MAIL:-ssl-admin@$CERTBOT_DOMAINS}"
local certbot_key_opts="--key-path $SSL_KEY --fullchain-path $SSL_CERT"
mkdir -p "/config/letsencrypt"
__symlink "/etc/letsencrypt" "/config/letsencrypt"
is_renewal="$(find /etc/letsencrypt/renewal -type f 2>/dev/null || false)"
[ -f "/config/env/ssl.sh" ] && . "/config/env/ssl.sh"
[ -f "/config/certbot/env.sh" ] && . "/config/certbot/env.sh"
if [ -n "$SSL_KEY" ]; then
mkdir -p "$(dirname "$SSL_KEY")" 2>/dev/null || true
else
echo "The variable SSL_KEY is not set" >&2
return 1
fi
if [ -n "$SSL_CERT" ]; then
mkdir -p "$(dirname "$SSL_CERT")" 2>/dev/null || true
else
echo "The variable SSL_CERT is not set" >&2
return 1
fi
domain_list="$CERTBOT_DOMAINS www.$CERTBOT_DOMAINS mail.$CERTBOT_DOMAINS"
domain_list="$(echo "$domain_list" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
if [ "$CERT_BOT_ENABLED" != "true" ]; then
export CERT_BOT_ENABLED=""
return 10
fi
if [ -z "$CERT_BOT_MAIL" ]; then
echo "The variable CERT_BOT_MAIL is not set" >&2
return 1
fi
if [ -z "$CERTBOT_DOMAINS" ]; then
echo "The variable CERTBOT_DOMAINS is not set" >&2
return 1
fi
for domain in $CERTBOT_DOMAINS; do
[ -n "$domain" ] && ADD_CERTBOT_DOMAINS+="-d $domain "
done
if [ -n "$is_renewal" ]; then
options="renew"
ADD_CERTBOT_DOMAINS=""
else
options="certonly"
fi
certbot_key_opts="$certbot_key_opts $ADD_CERTBOT_DOMAINS"
if [ -f "/config/certbot/setup.sh" ]; then
eval "/config/certbot/setup.sh"
statusCode=$?
elif [ -f "/etc/named/certbot.sh" ]; then
eval "/etc/named/certbot.sh"
statusCode=$?
elif [ -f "/config/certbot/dns.conf" ]; then
if certbot $options -n --dry-run --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/certbot/dns.conf $certbot_key_opts; then
certbot $options -n --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/certbot/dns.conf $certbot_key_opts
fi
statusCode=$?
elif [ -f "/config/certbot/certbot.conf" ]; then
if certbot $options -n --dry-run --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/certbot/certbot.conf $certbot_key_opts; then
certbot $options -n --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/certbot/certbot.conf $certbot_key_opts
fi
statusCode=$?
elif [ -f "/config/named/certbot-update.conf" ]; then
if certbot $options -n --dry-run --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/named/certbot-update.conf $certbot_key_opts; then
certbot $options -n --agree-tos --expand --dns-rfc2136 --dns-rfc2136-credentials /config/named/certbot-update.conf $certbot_key_opts
fi
statusCode=$?
else
certbot_key_opts="$certbot_key_opts --webroot ${WWW_ROOT_DIR:-/usr/local/share/httpd/default}"
if [ -n "$ADD_CERTBOT_DOMAINS" ]; then
certbot $options --agree-tos -m $CERT_BOT_MAIL certonly --webroot "${WWW_ROOT_DIR:-/usr/local/share/httpd/default}" $certbot_key_opts
statusCode=$?
else
statusCode=1
fi
fi
[ $statusCode -eq 0 ] && __update_ssl_certs
return $statusCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__display_user_info() {
if [ -n "$user_name" ] || [ -n "$user_pass" ] || [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then
__banner "User info"
[ -n "$user_name" ] && __printf_space "40" "username:" "$user_name" && echo "$user_name"
[ -n "$user_pass" ] && __printf_space "40" "password:" "saved to ${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && echo "$user_pass"
[ -n "$root_user_name" ] && __printf_space "40" "root username:" "$root_user_name" && echo "$root_user_name"
[ -n "$root_user_pass" ] && __printf_space "40" "root password:" "saved to ${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && echo "$root_user_pass"
__banner ""
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_config_etc() {
local copy="no"
local name="$(find "/etc/$SERVICE_NAME" -maxdepth 0 2>/dev/null | head -n1)"
local etc_dir="${ETC_DIR:-/etc/$name}"
local conf_dir="${CONF_DIR:-/config/$name}"
__is_dir_empty "$conf_dir" && copy=yes
if [ "$copy" = "yes" ]; then
if [ -d "$etc_dir" ]; then
mkdir -p "$conf_dir"
__copy_templates "$etc_dir/." "$conf_dir/"
elif [ -f "$etc_dir" ]; then
__copy_templates "$etc_dir" "$conf_dir"
fi
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
}
__create_ssl_cert() {
local SSL_DIR="${SSL_DIR:-/etc/ssl}"
if ! __certbot certonly; then
[ -f "/config/env/ssl.sh" ] && . "/config/env/ssl.sh"
if [ -z "$SSL_DIR" ]; then
echo "SSL_DIR is unset"
return 1
fi
[ -d "$SSL_DIR" ] || mkdir -p "$SSL_DIR"
if [ -n "$FORCE_SSL" ] || [ ! -f "$SSL_CERT" ] || [ ! -f "$SSL_KEY" ]; then
echo "Setting Country to $COUNTRY and Setting State/Province to $STATE and Setting City to $CITY"
echo "Setting OU to $UNIT and Setting ORG to $ORG and Setting server to $CN"
echo "All variables can be overwritten by creating a /config/.ssl.env and setting the variables there"
echo "Creating ssl key and certificate in $SSL_DIR and will be valid for $((VALID_FOR / 365)) year[s]"
#
openssl req \
-new \
-newkey rsa:$RSA \
-days $VALID_FOR \
-nodes \
-x509 \
-subj "/C=${COUNTRY// /\\ }/ST=${STATE// /\\ }/L=${CITY// /\\ }/O=${ORG// /\\ }/OU=${UNIT// /\\ }/CN=${CN// /\\ }" \
-keyout "$SSL_KEY" \
-out "$SSL_CERT"
fi
fi
if [ -f "$SSL_CERT" ] && [ -f "$SSL_KEY" ]; then
__update_ssl_certs
return 0
else
return 2
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_apache() {
local etc_dir="" conf_dir="" conf_dir="" www_dir="" apache_bin=""
etc_dir="/etc/${1:-apache2}"
conf_dir="/config/${1:-apache2}"
www_dir="${WWW_ROOT_DIR:-/data/htdocs}"
apache_bin="$(type -P 'httpd' || type -P 'apache2')"
#
return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_nginx() {
local etc_dir="/etc/${1:-nginx}"
local conf_dir="/config/${1:-nginx}"
local www_dir="${WWW_ROOT_DIR:-/data/htdocs}"
local nginx_bin="$(type -P 'nginx')"
return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_php() {
local etc_dir="/etc/${1:-php}"
local conf_dir="/config/${1:-php}"
local php_bin="${PHP_BIN_DIR:-$(__find_php_bin)}"
return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_mysql() {
local db_dir="/data/db/mysql"
local etc_dir="${home:-/etc/${1:-mysql}}"
local db_user="${SERVICE_USER:-mysql}"
local conf_dir="/config/${1:-mysql}"
local user_name="${MARIADB_USER:-root}"
local user_pass="${MARIADB_PASSWORD:-$MARIADB_ROOT_PASSWORD}"
local user_db="${MARIADB_DATABASE}"
local root_pass="$MARIADB_ROOT_PASSWORD"
local mysqld_bin="$(type -P 'mysqld')"
return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_mongodb() {
local home="${MONGODB_CONFIG_FILE:-$(__find_mongodb_conf)}"
local user_name="${INITDB_ROOT_USERNAME:-root}"
local user_pass="${MONGO_INITDB_ROOT_PASSWORD:-$_ROOT_PASSWORD}"
return
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_postgres() {
local home="${PGSQL_CONFIG_FILE:-$(__find_pgsql_conf)}"
local user_name="${POSTGRES_USER:-root}"
local user_pass="${POSTGRES_PASSWORD:-$POSTGRES_ROOT_PASSWORD}"
return
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__init_couchdb() {
local home="${COUCHDB_CONFIG_FILE:-$(__find_couchdb_conf)}"
local user_name="${COUCHDB_USER:-root}"
local user_pass="${COUCHDB_PASSWORD:-$SET_RANDOM_PASS}"
return
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Show available init functions
__init_help() {
echo '
__certbot
__update_ssl_certs
__create_ssl_cert
'
return
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__run_once() {
if [ "$CONFIG_DIR_INITIALIZED" = "false" ] || [ "$DATA_DIR_INITIALIZED" = "false" ] || [ ! -f "/config/.docker_has_run" ]; then
return 0
else
return 1
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# run program ever n minutes
__cron() {
trap 'retVal=$?;[ -f "/run/cron/$bin.run" ] && rm -Rf "/run/cron/$bin.run";[ -f "/run/cron/$bin.pid" ] && rm -Rf "/run/cron/$bin.pid";exit ${retVal:-0}' SIGINT ERR EXIT
if [ "$1" = "--pid" ]; then
pid="$2"
shift 2
else
pid="$$"
fi
if test -n "$1" && test -z "${1//[0-9]/}"; then
interval=$(($1 * 60))
shift 1
else
interval="300"
fi
[ $# -eq 0 ] && echo "Usage: cron [interval] [command]" && exit 1
local command="$*"
local bin="$(basename "${CRON_NAME:-$1}")"
[ -d "/run/cron" ] || mkdir -p "/run/cron"
echo "$pid" >"/run/cron/$bin.pid"
echo "$command" >"/run/cron/$bin.run"
echo "Log is saved to /data/logs/cron.log"
while :; do
eval "$command"
sleep $interval
[ -f "/run/cron/$bin.run" ] || break
done 2>/dev/stderr >>"/data/logs/cron.log"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__replace() {
local search="$1" replace="$2" file="${3:-$2}"
[ -e "$file" ] || return 1
__sed "$search" "$replace" "$file" || return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__find_replace() {
local search="$1" replace="$2" file="${3:-$2}"
[ -e "$file" ] || return 1
find "$file" -type f -not -path '.git*' -exec sed -i "s|$search|$replace|g" {} \; 2>/dev/null
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# /config > /etc
__copy_templates() {
local from="$1" to="$2"
is_link="$(ls -la "$dest" 2>/dev/null | awk '{print $NF}')"
[ "$from" != "$is_link" ] || return 0
if [ -e "$from" ] && __is_dir_empty "$to"; then
__file_copy "$from" "$to"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# /config/file > /etc/file
__symlink() {
local from="$1" to="$2"
if [ -e "$to" ]; then
[ -e "$from" ] && __rm "$from"
ln -sf "$to" "$from" && echo "Created symlink to $from > $to"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__file_copy() {
local from="$1"
local dest="$2"
is_link="$(ls -la "$dest" 2>/dev/null | awk '{print $NF}')"
if [ "$from" != "$is_link" ]; then
if [ -n "$from" ] && [ -e "$from" ] && [ -n "$dest" ]; then
if [ -d "$from" ]; then
if cp -Rf "$from/." "$dest/" &>/dev/null; then
printf '%s\n' "Copied: $from > $dest"
return 0
else
printf '%s\n' "Copy failed: $from < $dest" >&2
return 1
fi
else
if cp -Rf "$from" "$dest" &>/dev/null; then
printf '%s\n' "Copied: $from > $dest"
return 0
else
printf '%s\n' "Copy failed: $from < $dest" >&2
return 1
fi
fi
else
printf '%s\n' "$from does not exist" >&2
return 2
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__generate_random_uids() {
local set_random_uid="$(seq 100 999 | sort -R | head -n 1)"
while :; do
if grep -shq "x:.*:$set_random_uid:" "/etc/group" && ! grep -shq "x:$set_random_uid:.*:" "/etc/passwd"; then
set_random_uid=$((set_random_uid + 1))
else
echo "$set_random_uid"
break
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__setup_directories() {
APPLICATION_DIRS="${APPLICATION_DIRS//,/ }"
APPLICATION_FILES="${APPLICATION_FILES//,/ }"
ADD_APPLICATION_DIRS="${ADD_APPLICATION_DIRS//,/ }"
ADD_APPLICATION_FILES="${ADD_APPLICATION_FILES//,/ }"
[ -n "$ENV_WWW_ROOT_DIR" ] && export WWW_ROOT_DIR="$ENV_WWW_ROOT_DIR"
# Setup WWW_ROOT_DIR
if [ "$IS_WEB_SERVER" = "yes" ]; then
APPLICATION_DIRS="$APPLICATION_DIRS $WWW_ROOT_DIR"
__initialize_www_root
(echo "Creating directory $WWW_ROOT_DIR with permissions 777" && mkdir -p "$WWW_ROOT_DIR" && find "$WWW_ROOT_DIR" -type d -exec chmod -f 777 {} \;) 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
# Setup DATABASE_DIR
if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then
APPLICATION_DIRS="$APPLICATION_DIRS $DATABASE_DIR"
if __is_dir_empty "$DATABASE_DIR" || [ ! -d "$DATABASE_DIR" ]; then
(echo "Creating directory $DATABASE_DIR with permissions 777" && mkdir -p "$DATABASE_DIR" && chmod -f 777 "$DATABASE_DIR") 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
fi
# create default directories
for filedirs in $ADD_APPLICATION_DIRS $APPLICATION_DIRS; do
if [ -n "$filedirs" ] && [ ! -d "$filedirs" ]; then
(echo "Creating directory $filedirs with permissions 777" && mkdir -p "$filedirs" && chmod -f 777 "$filedirs") 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
done
# create default files
for application_files in $ADD_APPLICATION_FILES $APPLICATION_FILES; do
if [ -n "$application_files" ] && [ ! -e "$application_files" ]; then
(echo "Creating file $application_files with permissions 777" && touch "$application_files" && chmod -Rf 777 "$application_files") 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set user on files/folders
__fix_permissions() {
change_user="${1:-${SERVICE_USER:-root}}"
change_group="${2:-${SERVICE_GROUP:-$change_user}}"
[ -n "$RUNAS_USER" ] && [ "$RUNAS_USER" != "root" ] && change_user="$RUNAS_USER" && change_group="$change_user"
if [ -n "$change_user" ]; then
if grep -shq "^$change_user:" "/etc/passwd"; then
for permissions in $ADD_APPLICATION_DIRS $APPLICATION_DIRS; do
if [ -n "$permissions" ] && [ -e "$permissions" ]; then
(chown -Rf $change_user "$permissions" && echo "changed ownership on $permissions to user:$change_user") 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
done
fi
fi
if [ -n "$change_group" ]; then
if grep -shq "^$change_group:" "/etc/group"; then
for permissions in $ADD_APPLICATION_DIRS $APPLICATION_DIRS; do
if [ -n "$permissions" ] && [ -e "$permissions" ]; then
(chgrp -Rf $change_group "$permissions" && echo "changed group ownership on $permissions to group $change_group") 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
fi
done
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__get_gid() { grep "^$1:" /etc/group 2>/dev/null | awk -F ':' '{print $3}' || return 1; }
__get_uid() { grep "^$1:" /etc/passwd 2>/dev/null | awk -F ':' '{print $3}' || return 1; }
__check_for_uid() { cat "/etc/passwd" 2>/dev/null | awk -F ':' '{print $3}' | sort -u | grep -q "^$1$" 2>/dev/null || return 1; }
__check_for_guid() { cat "/etc/group" 2>/dev/null | awk -F ':' '{print $3}' | sort -u | grep -q "^$1$" 2>/dev/null || return 1; }
__check_for_user() { cat "/etc/passwd" 2>/dev/null | awk -F ':' '{print $1}' | sort -u | grep -q "^$1$" 2>/dev/null || return 1; }
__check_for_group() { cat "/etc/group" 2>/dev/null | awk -F ':' '{print $1}' | sort -u | grep -q "^$1$" 2>/dev/null || return 1; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
# check if process is already running
__proc_check() {
local cmd_bin cmd_name check_result
cmd_bin="$(type -P "${1:-$EXEC_CMD_BIN}" 2>/dev/null || echo "${1:-$EXEC_CMD_BIN}")"
cmd_name="$(basename "${cmd_bin:-${1:-$EXEC_CMD_NAME}}" 2>/dev/null)"
if [ -z "$cmd_name" ] || [ "$cmd_name" = "." ]; then
return 1
fi
check_result=1
if [ -n "$cmd_bin" ] && __pgrep "$cmd_bin" 2>/dev/null; then
check_result=0
elif [ -n "$cmd_name" ] && __pgrep "$cmd_name" 2>/dev/null; then
check_result=0
elif [ -f "$SERVICE_PID_FILE" ]; then
local pid_from_file
pid_from_file="$(cat "$SERVICE_PID_FILE" 2>/dev/null || echo "")"
if [ -n "$pid_from_file" ] && kill -0 "$pid_from_file" 2>/dev/null; then
check_result=0
fi
fi
if [ $check_result -eq 0 ]; then
SERVICE_IS_RUNNING="yes"
touch "$SERVICE_PID_FILE" 2>/dev/null || true
return 0
else
return 1
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__set_user_group_id() {
local exitStatus=0
local set_user="${1:-$SERVICE_USER}"
local set_uid="${2:-${SERVICE_UID:-1000}}"
local set_gid="${3:-${SERVICE_GID:-1000}}"
local random_id="$(__generate_random_uids)"
set_uid="$(__get_uid "$set_user" || echo "$set_uid")"
set_gid="$(__get_gid "$set_user" || echo "$set_gid")"
if ! grep -shq "^$set_user:" "/etc/passwd" "/etc/group"; then
return 0
fi
if [ -z "$set_user" ] || [ "$set_user" = "root" ]; then
return
fi
if grep -shq "^$set_user:" "/etc/passwd" "/etc/group"; then
if __check_for_guid "$set_gid"; then
groupmod -g "${set_gid}" $set_user 2>/dev/stderr | tee -p -a "/data/logs/init.txt" >/dev/null
fi
if __check_for_uid "$set_uid"; then
usermod -u "${set_uid}" -g "${set_gid}" $set_user 2>/dev/stderr | tee -p -a "/data/logs/init.txt" >/dev/null
fi
fi
export SERVICE_UID="$set_uid"
export SERVICE_GID="$set_gid"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__create_service_user() {
local exitStatus=0
local max_attempts=100
local attempt=0
local create_user="${1:-$SERVICE_USER}"
local create_group="${2:-${SERVICE_GROUP:-$create_user}}"
local create_home_dir="${3:-$WORK_DIR}"
local create_uid="${4:-${SERVICE_UID:-$USER_UID}}"
local create_gid="${5:-${SERVICE_GID:-$USER_GID}}"
local random_id="$(__generate_random_uids)"
local create_home_dir="${create_home_dir:-/home/$create_user}"
local log_file="/data/logs/init.txt"
# Ensure log directory exists
[ -d "$(dirname "$log_file")" ] || mkdir -p "$(dirname "$log_file")" 2>/dev/null
# Validate that we have at least a user or group to create
if [ -z "$create_user" ] && [ -z "$create_group" ]; then
echo "No user or group specified to create" >&2
return 0
fi
# Validate user/group name format (alphanumeric, underscore, hyphen; must start with letter or underscore)
if [ -n "$create_user" ] && ! echo "$create_user" | grep -qE '^[a-z_][a-z0-9_-]*$'; then
echo "Error: Invalid username format '$create_user' - must start with letter/underscore, contain only lowercase alphanumeric, underscore, or hyphen" >&2
return 1
fi
if [ -n "$create_group" ] && ! echo "$create_group" | grep -qE '^[a-z_][a-z0-9_-]*$'; then
echo "Error: Invalid group name format '$create_group' - must start with letter/underscore, contain only lowercase alphanumeric, underscore, or hyphen" >&2
return 1
fi
# Check if user and group already exist
if grep -shq "^$create_user:" "/etc/passwd" && grep -shq "^$create_group:" "/etc/group"; then
return 0
fi
# Root user/group - nothing to create
if [ "$create_user" = "root" ] && [ "$create_group" = "root" ]; then
return 0
fi
# Override with RUNAS_USER if specified and not root
if [ -n "$RUNAS_USER" ] && [ "$RUNAS_USER" != "root" ]; then
create_user="$RUNAS_USER"
create_group="$RUNAS_USER"
create_uid="${create_uid:-1000}"
create_gid="${create_gid:-1000}"
fi
# Get existing UID/GID or use provided values
create_uid="$(__get_uid "$create_user" 2>/dev/null || echo "$create_uid")"
create_gid="$(__get_gid "$create_user" 2>/dev/null || echo "$create_gid")"
# Ensure we have valid non-root UID/GID
if [ -z "$create_uid" ] || [ "$create_uid" = "0" ]; then
create_uid="$random_id"
fi
if [ -z "$create_gid" ] || [ "$create_gid" = "0" ]; then
create_gid="$random_id"
fi
# Validate UID/GID are numeric and within valid range
if ! echo "$create_uid" | grep -qE '^[0-9]+$' || [ "$create_uid" -lt 1 ] || [ "$create_uid" -gt 65534 ]; then
echo "Error: Invalid UID '$create_uid' - must be a number between 1 and 65534" >&2
return 1
fi
if ! echo "$create_gid" | grep -qE '^[0-9]+$' || [ "$create_gid" -lt 1 ] || [ "$create_gid" -gt 65534 ]; then
echo "Error: Invalid GID '$create_gid' - must be a number between 1 and 65534" >&2
return 1
fi
# Find available UID/GID if current ones are taken (with loop protection)
while __check_for_uid "$create_uid" || __check_for_guid "$create_gid"; do
attempt=$((attempt + 1))
if [ $attempt -ge $max_attempts ]; then
echo "Error: Could not find available UID/GID after $max_attempts attempts" >&2
return 1
fi
random_id=$((random_id + 1))
create_uid="$random_id"
create_gid="$random_id"
done
# Create group if needed
if [ -n "$create_group" ] && ! __check_for_group "$create_group"; then
echo "Creating system group '$create_group' with GID $create_gid"
if ! groupadd --force --system -g "$create_gid" "$create_group" 2>&1 | tee -a "$log_file"; then
echo "Error: Failed to create group '$create_group'" >&2
exitStatus=$((exitStatus + 1))
elif ! grep -shq "^$create_group:" "/etc/group"; then
echo "Error: Group '$create_group' not found in /etc/group after creation" >&2
exitStatus=$((exitStatus + 1))
fi
fi
# Create user if needed (only if group creation succeeded)
if [ $exitStatus -eq 0 ] && [ -n "$create_user" ] && ! __check_for_user "$create_user"; then
echo "Creating system user '$create_user' with UID $create_uid"
if ! useradd --system --uid "$create_uid" --gid "$create_group" --comment "Account for $create_user" --home-dir "$create_home_dir" --shell /bin/false "$create_user" 2>&1 | tee -a "$log_file"; then
echo "Error: Failed to create user '$create_user'" >&2
exitStatus=$((exitStatus + 1))
elif ! grep -shq "^$create_user:" "/etc/passwd"; then
echo "Error: User '$create_user' not found in /etc/passwd after creation" >&2
exitStatus=$((exitStatus + 1))
fi
fi
# Setup user environment if creation succeeded
if [ $exitStatus -eq 0 ] && [ -n "$create_group" ] && [ -n "$create_user" ]; then
export WORK_DIR="${create_home_dir:-}"
if [ -n "$WORK_DIR" ]; then
if [ ! -d "$WORK_DIR" ]; then
if ! mkdir -p "$WORK_DIR" 2>/dev/null; then
echo "Warning: Failed to create home directory '$WORK_DIR'" >&2
fi
fi
if [ -d "/etc/.skel" ] && [ -d "$WORK_DIR" ]; then
cp -Rf /etc/.skel/. "$WORK_DIR/" 2>/dev/null || echo "Warning: Failed to copy skeleton files to '$WORK_DIR'" >&2
fi
fi
# Setup sudo access
if [ -d "/etc/sudoers.d" ]; then
if [ ! -f "/etc/sudoers.d/$create_user" ]; then
echo "$create_user ALL=(ALL) NOPASSWD: ALL" >"/etc/sudoers.d/$create_user" 2>/dev/null || echo "Warning: Failed to create sudoers file for '$create_user'" >&2
chmod 0440 "/etc/sudoers.d/$create_user" 2>/dev/null
fi
elif [ -f "/etc/sudoers" ] && ! grep -qs "^$create_user " "/etc/sudoers"; then
echo "$create_user ALL=(ALL) NOPASSWD: ALL" >>"/etc/sudoers" 2>/dev/null || echo "Warning: Failed to add '$create_user' to sudoers" >&2
fi
SERVICE_UID="$create_uid"
SERVICE_GID="$create_gid"
SERVICE_USER="$create_user"
SERVICE_GROUP="$create_group"
else
echo "Warning: Falling back to root user due to creation errors" >&2
SERVICE_UID=0
SERVICE_GID=0
SERVICE_USER=root
SERVICE_GROUP=root
exitStatus=2
fi
export SERVICE_UID SERVICE_GID SERVICE_USER SERVICE_GROUP
return $exitStatus
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__create_env_file() {
local dir=""
local envStatus=0
local envFile=("${@:-}")
local sample_file="/usr/local/etc/docker/env/default.sample"
[ -f "$sample_file" ] || return 0
for create_env in "/usr/local/etc/docker/env/default.sh" "${envFile[@]}"; do
dir="$(dirname "$create_env")"
[ -d "$dir" ] || mkdir -p "$dir"
if [ -n "$create_env" ] && [ ! -f "$create_env" ]; then
cat <<EOF | tee -p "$create_env" >/dev/null
$(<"$sample_file")
EOF
fi
[ -f "$create_env" ] || envStatus=$((1 + envStatus))
done
rm -f "$sample_file"
return $envStatus
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__exec_command() {
local bin=""
local arg=("$@")
local exitCode="0"
local cmdExec="${arg:-}"
local pre_exec="--login -c"
local shell="$(type -P bash 2>/dev/null || type -P dash 2>/dev/null || type -P ash 2>/dev/null || type -P sh 2>/dev/null)"
bin="$(echo "${arg[*]}" | tr ' ' '\n' | grep -v '^$' | head -n1 | sed 's| ||g' || echo 'bash')"
prog="$(type -P "$bin" 2>/dev/null || echo "$bin")"
if type -t $bin >/dev/null 2>&1; then
echo "${exec_message:-Executing command: $cmdExec}"
eval $shell $pre_exec "$cmdExec" || exitCode=1
exitCode=$?
elif [ -f "$prog" ]; then
echo "$prog is not executable"
exitCode=98
else
echo "$prog does not exist"
exitCode=99
fi
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Setup the server init scripts
__start_init_scripts() {
[ "$1" = " " ] && shift 1
if [ "$DEBUGGER" = "on" ]; then
echo "Enabling debugging"
set -o pipefail -x$DEBUGGER_OPTIONS
else
set -o pipefail
fi
local retPID=""
local basename=""
local init_pids=""
local retstatus="0"
local initStatus="0"
local critical_failures="0"
local pidFile="/run/__start_init_scripts.pid"
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 exit_on_failure="${EXIT_ON_SERVICE_FAILURE:-true}"
# Clean stale PID files from previous runs
if [ ! -f "/run/__start_init_scripts.pid" ]; then
echo "🧹 Cleaning stale PID files from previous container run"
rm -f /run/*.pid /run/init.d/*.pid 2>/dev/null || true
fi
touch "$pidFile"
if [ "$init_count" -eq 0 ] || [ ! -d "$init_dir" ]; then
mkdir -p "/data/logs/init"
while :; do echo "Running: $(date)" >"/data/logs/init/keep_alive" && sleep 3600; done &
else
if [ -d "$init_dir" ]; then
[ -f "$init_dir/service.sample" ] && __rm "$init_dir"/*.sample
chmod -Rf 755 "$init_dir"/*.sh
echo "🚀 Starting container services initialization"
echo "📂 Init directory: $init_dir"
echo "📊 Services to start: $init_count"
echo "📋 Found $init_count service scripts to execute"
echo ""
for init in "$init_dir"/*.sh; do
if [ -x "$init" ]; then
touch "$pidFile"
name="$(basename "$init")"
service="$(printf '%s' "$name" | sed 's/^[^-]*-//;s|.sh$||g')"
__service_banner "🔧" "Executing service script:" "$(basename "$init")"
# Execute the init script and capture the exit code
if source "$init"; then
# Check if service was disabled first
if [ -n "$SERVICE_DISABLED" ]; then
initStatus="0"
__service_banner "🚫" "Service $service is disabled -" "skipping"
unset SERVICE_DISABLED
# Continue to next service
elif [ "$CONTAINER_INIT" = "yes" ]; then
initStatus="0"
__service_banner "✅" "Service $service completed successfully -" "configuration service"
else
# Allow some time for service to initialize
sleep 2
# Check for service success indicators
local expected_pid_file="/run/init.d/$service.pid"
set +e
if [ "$SERVICE_USES_PID" = "no" ]; then
# Service doesn't use PID files - assume success unless explicitly failed
initStatus="0"
__service_banner "✅" "Service $service completed successfully -" "no PID tracking required"
else
# Service uses PID tracking - verify actual running processes
retPID=""
local found_process=""
# Try multiple name variants to find the process
for name_variant in "$service" "${service}84" "${service}d" "$(echo "$service" | sed 's/-//g')" "$(echo "$service" | tr -d '-')"; do
if [ -z "$retPID" ]; then
retPID=$(__get_pid "$name_variant" 2>/dev/null || echo "")
if [ -n "$retPID" ] && [ "$retPID" != "0" ]; then
found_process="$name_variant"
break
fi
fi
done
if [ -n "$retPID" ] && [ "$retPID" != "0" ]; then
# Found actual running process
initStatus="0"
__service_banner "✅" "Service $service started successfully -" "PID: ${retPID} ($found_process)"
elif [ -f "$expected_pid_file" ]; then
# No running process but PID file exists - verify PID is valid
file_pid="$(cat "$expected_pid_file" 2>/dev/null || echo "")"
if [ -n "$file_pid" ] && kill -0 "$file_pid" 2>/dev/null; then
initStatus="0"
__service_banner "✅" "Service $service started successfully -" "PID: $file_pid (from file)"
else
# PID file exists but process isn't running - treat as warning, not failure
initStatus="0"
__service_banner "⚠️" "Service $service may not be running -" "no process found (non-critical)"
fi
else
# No process and no PID file - likely a configuration-only service
initStatus="0"
__service_banner "✅" "Service $service completed successfully -" "configuration service"
fi
fi
set -e
fi
else
initStatus="1"
critical_failures=$((critical_failures + 1))
__service_banner "❌" "Service $service failed to start -" "check logs"
fi
echo ""
fi
retstatus=$((retstatus + initStatus))
done
# Summary
echo ""
if [ $critical_failures -gt 0 ]; then
echo "⚠️ Warning: $critical_failures critical service(s) reported failures"
if [ "$exit_on_failure" = "true" ] && [ $critical_failures -ge 2 ]; then
echo "❌ Exiting due to multiple critical service failures (threshold: 2)"
return 1
else
echo " Continuing with $critical_failures failure(s) - container may still be functional"
fi
else
echo "✅ All service initializations completed successfully"
fi
echo ""
fi
fi
printf '%s\n' "$SERVICE_NAME started on $(date)" >"/data/logs/start.log"
return $retstatus
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__setup_mta() {
[ -d "/etc/ssmtp" ] || [ -d "/etc/postfix" ] || return
if [ ! -d "/config/ssmtp" ] || [ ! -d "/config/postfix" ]; then
echo "Configuring smtp server"
fi
local exitCode=0
local relay_port="${EMAIL_RELAY//*:/}"
local relay_server="${EMAIL_RELAY//:*/}"
local local_hostname="${FULL_DOMAIN_NAME:-}"
local account_user="${SERVER_ADMIN//@*/}"
local account_domain="${EMAIL_DOMAIN//*@/}"
echo "$EMAIL_RELAY" | grep '[0-9][0-9]' || relay_port="465"
################# sSMTP relay setup
if [ -n "$(type -P 'ssmtp')" ]; then
[ -d "/config/ssmtp" ] || mkdir -p "/config/ssmtp"
[ -f "/etc/ssmtp/ssmtp.conf" ] && __rm "/etc/ssmtp/ssmtp.conf"
symlink_files="$(__find_file_relative "/config/ssmtp")"
if [ ! -f "/config/ssmtp/ssmtp.conf" ]; then
cat <<EOF | tee -p "/config/ssmtp/ssmtp.conf" >/dev/null
# ssmtp configuration.
root=${account_user:-root}@${account_domain:-$HOSTNAME}
mailhub=${relay_server:-172.17.0.1}:$relay_port
rewriteDomain=$local_hostname
hostname=$local_hostname
TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt
UseTLS=Yes
UseSTARTTLS=No
AuthMethod=LOGIN
FromLineOverride=yes
#AuthUser=username
#AuthPass=password
EOF
fi
if [ -f "/config/ssmtp/ssmtp.conf" ]; then
for file in $symlink_files; do
__symlink "/config/ssmtp/$file" "/etc/ssmtp/$file"
__initialize_replace_variables "/etc/ssmtp/$file"
done
if [ -f "/etc/ssmtp/revaliases" ] && [ ! -f "/config/ssmtp/revaliases" ]; then
mv -f "/etc/ssmtp/revaliases" "/config/ssmtp/revaliases"
__symlink "/config/ssmtp/revaliases" "/etc/ssmtp/revaliases"
__initialize_replace_variables "/etc/ssmtp/revaliases"
else
touch "/config/ssmtp/revaliases"
__symlink "/config/ssmtp/revaliases" "/etc/ssmtp/revaliases"
__initialize_replace_variables "/etc/ssmtp/revaliases"
fi
echo "Done setting up ssmtp"
fi
################# postfix relay setup
elif [ -n "$(type -P 'postfix')" ]; then
[ -d "/etc/postfix" ] || mkdir -p "/etc/postfix"
[ -d "/config/postfix" ] || mkdir -p "/config/postfix"
[ -f "/etc/postfix/main.cf" ] && __rm "/etc/postfix/main.cf"
symlink_files="$(__find_file_relative "/config/postfix")"
if [ ! -f "/config/postfix/main.cf" ]; then
cat <<EOF | tee -p "/config/postfix/main.cf" >/dev/null
# postfix configuration.
smtpd_banner = \$myhostname ESMTP email server
compatibility_level = 2
inet_protocols = ipv4
inet_interfaces = all
mydestination =
local_transport=error: local delivery disabled
mynetworks = /etc/postfix/mynetworks
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
transport_maps = hash:/etc/postfix/transport
virtual_alias_maps = hash:/etc/postfix/virtual
relay_domains = hash:/etc/postfix/mydomains, regexp:/etc/postfix/mydomains.pcre
tls_random_source = dev:/dev/urandom
smtp_use_tls = yes
smtpd_use_tls = yes
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, KRB5-DES, CBC3-SHA
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
append_dot_mydomain = yes
myorigin = $local_hostname
myhostname = $local_hostname
relayhost = [$relay_server]:$relay_port
EOF
fi
if [ -d "/config/postfix" ]; then
for f in $symlink_files; do
__symlink "/config/postfix/$f" "/etc/postfix/$f"
done
__initialize_replace_variables "/etc/postfix"
touch "/config/postfix/aliases" "/config/postfix/mynetworks" "/config/postfix/transport"
touch "/config/postfix/mydomains.pcre" "/config/postfix/mydomains" "/config/postfix/virtual"
postmap "/config/aliases" "/config/mynetworks" "/config/transport" &>/dev/null
postmap "/config/mydomains.pcre" "/config/mydomains" "/config/virtual" &>/dev/null
fi
if [ -f "/etc/postfix/main.cf" ] && [ ! -f "/run/init.d/postfix.pid" ]; then
SERVICES_LIST+="postfix "
if [ ! -f "/run/init.d/postfix.pid" ]; then
__exec_service postfix start
fi
echo "Done setting up postfix"
fi
fi
[ -f "/root/dead.letter" ] && __rm "/root/dead.letter"
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_web_health() {
local www_dir="${1:-${WWW_ROOT_DIR:-/usr/local/share/httpd/default}}"
if [ -d "$www_dir" ]; then
__find_replace "REPLACE_CONTAINER_IP4" "${REPLACE_CONTAINER_IP4:-127.0.0.1}" "/usr/local/share/httpd"
__find_replace "REPLACE_COPYRIGHT_FOOTER" "${COPYRIGHT_FOOTER:-Copyright 1999 - $(date +'%Y')}" "/usr/local/share/httpd"
__find_replace "REPLACE_LAST_UPDATED_ON_MESSAGE" "${LAST_UPDATED_ON_MESSAGE:-$(date +'Last updated on: %Y-%m-%d at %H:%M:%S')}" "/usr/local/share/httpd"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# file_dir
__initialize_replace_variables() {
local set_dir="" get_dir="$*"
[ $# -ne 0 ] || return 1
for set_dir in $get_dir; do
__find_replace "REPLACE_SSL_DIR" "${SSL_DIR:-/etc/ssl}" "$set_dir"
__find_replace "REPLACE_RANDOM_ID" "$(__random_password 8)" "$set_dir"
__find_replace "REPLACE_TZ" "${TZ:-${TIMEZONE:-America/New_York}}" "$set_dir"
__find_replace "REPLACE_SERVER_PROTO" "${SERVICE_PROTOCOL:-http}" "$set_dir"
__find_replace "REPLACE_SERVER_SITE_TITLE" "${SERVER_SITE_TITLE:-CasjaysDev - Docker Container}" "$set_dir"
__find_replace "REPLACE_TMP_DIR" "${TMP_DIR:-/tmp/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_RUN_DIR" "${RUN_DIR:-/run/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_LOG_DIR" "${LOG_DIR:-/data/logs/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_ETC_DIR" "${ETC_DIR:-/etc/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_DATA_DIR" "${DATA_DIR:-/data/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_CONFIG_DIR" "${CONF_DIR:-/config/$SERVICE_NAME}" "$set_dir"
__find_replace "REPLACE_EMAIL_RELAY" "${EMAIL_RELAY:-172.17.0.1}" "$set_dir"
__find_replace "REPLACE_SERVER_ADMIN" "${SERVER_ADMIN:-root@${EMAIL_DOMAIN:-${FULL_DOMAIN_NAME:-$HOSTNAME}}}" "$set_dir"
__find_replace "REPLACE_APP_USER" "${SERVICE_USER:-${RUNAS_USER:-root}}" "$set_dir"
__find_replace "REPLACE_WWW_USER" "${SERVICE_USER:-${RUNAS_USER:-root}}" "$set_dir"
__find_replace "REPLACE_APP_GROUP" "${SERVICE_GROUP:-${SERVICE_USER:-${RUNAS_USER:-root}}}" "$set_dir"
__find_replace "REPLACE_WWW_GROUP" "${SERVICE_GROUP:-${SERVICE_USER:-${RUNAS_USER:-root}}}" "$set_dir"
__find_replace "REPLACE_SERVICE_USER" "${SERVICE_USER:-${RUNAS_USER:-root}}" "$set_dir"
__find_replace "REPLACE_SERVICE_GROUP" "${SERVICE_GROUP:-${RUNAS_USER:-root}}" "$set_dir"
__find_replace "REPLACE_SERVER_ADMIN_URL" "$SERVER_ADMIN_URL" "$set_dir"
if [ -n "$VAR_DIR" ]; then
mkdir -p "$VAR_DIR"
__find_replace "REPLACE_VAR_DIR" "$VAR_DIR" "$set_dir"
fi
[ -n "$SERVICE_PORT" ] && __find_replace "REPLACE_SERVER_PORT" "${SERVICE_PORT:-80}" "$set_dir"
[ -n "$HOSTNAME" ] && __find_replace "REPLACE_SERVER_NAME" "${FULL_DOMAIN_NAME:-$HOSTNAME}" "$set_dir"
[ -n "$CONTAINER_NAME" ] && __find_replace "REPLACE_SERVER_SOFTWARE" "${CONTAINER_NAME:-docker}" "$set_dir"
[ -n "$WWW_ROOT_DIR" ] && __find_replace "REPLACE_SERVER_WWW_DIR" "${WWW_ROOT_DIR:-/usr/local/share/httpd/default}" "$set_dir"
done
if [ -n "$WWW_ROOT_DIR" ] && [ "$set_dir" != "$WWW_ROOT_DIR" ] && [ -d "$WWW_ROOT_DIR" ]; then
__find_replace "REPLACE_CONTAINER_IP4" "${REPLACE_CONTAINER_IP4:-127.0.0.1}" "$WWW_ROOT_DIR"
__find_replace "REPLACE_COPYRIGHT_FOOTER" "${COPYRIGHT_FOOTER:-Copyright 1999 - $(date +'%Y')}" "$WWW_ROOT_DIR"
__find_replace "REPLACE_LAST_UPDATED_ON_MESSAGE" "${LAST_UPDATED_ON_MESSAGE:-$(date +'Last updated on: %Y-%m-%d at %H:%M:%S')}" "$WWW_ROOT_DIR"
fi
mkdir -p "${TMP_DIR:-/tmp/$SERVICE_NAME}" "${RUN_DIR:-/run/$SERVICE_NAME}" "${LOG_DIR:-/data/logs/$SERVICE_NAME}"
chmod -f 777 "${TMP_DIR:-/tmp/$SERVICE_NAME}" "${RUN_DIR:-/run/$SERVICE_NAME}" "${LOG_DIR:-/data/logs/$SERVICE_NAME}"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_database() {
[ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ] || return 0
local dir="${1:-$ETC_DIR}"
local db_normal_user="${DATABASE_USER_NORMAL:-$user_name}"
local db_normal_pass="${DATABASE_PASS_NORMAL:-$user_pass}"
local db_admin_user="${DATABASE_USER_ROOT:-$root_user_name}"
local db_admin_pass="${DATABASE_PASS_ROOT:-$root_user_pass}"
__find_replace "REPLACE_USER_NAME" "$db_normal_user" "$dir"
__find_replace "REPLACE_USER_PASS" "$db_normal_pass" "$dir"
__find_replace "REPLACE_DATABASE_USER" "$db_normal_user" "$dir"
__find_replace "REPLACE_DATABASE_PASS" "$db_normal_pass" "$dir"
__find_replace "REPLACE_ROOT_ADMIN" "$db_admin_user" "$dir"
__find_replace "REPLACE_ROOT_PASS" "$db_admin_pass" "$dir"
__find_replace "REPLACE_DATABASE_ROOT_USER" "$db_admin_user" "$dir"
__find_replace "REPLACE_DATABASE_ROOT_PASS" "$db_admin_pass" "$dir"
__find_replace "REPLACE_DATABASE_NAME" "$DATABASE_NAME" "$dir"
__find_replace "REPLACE_DATABASE_DIR" "$DATABASE_DIR" "$dir"
if echo "$dir" | grep -q '^/etc'; then
__find_replace "REPLACE_USER_NAME" "$db_normal_user" "/etc"
__find_replace "REPLACE_USER_PASS" "$db_normal_pass" "/etc"
__find_replace "REPLACE_DATABASE_USER" "$db_normal_user" "/etc"
__find_replace "REPLACE_DATABASE_PASS" "$db_normal_pass" "/etc"
__find_replace "REPLACE_ROOT_ADMIN" "$db_admin_user" "/etc"
__find_replace "REPLACE_ROOT_PASS" "$db_admin_pass" "/etc"
__find_replace "REPLACE_DATABASE_ROOT_USER" "$db_admin_user" "/etc"
__find_replace "REPLACE_DATABASE_ROOT_PASS" "$db_admin_pass" "/etc"
__find_replace "REPLACE_DATABASE_NAME" "$DATABASE_NAME" "/etc"
__find_replace "REPLACE_DATABASE_DIR" "$DATABASE_DIR" "/etc"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_db_users() {
[ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ] || return 0
db_normal_user="${DATABASE_USER_NORMAL:-$user_name}"
db_normal_pass="${DATABASE_PASS_NORMAL:-$user_pass}"
db_admin_user="${DATABASE_USER_ROOT:-$root_user_name}"
db_admin_pass="${DATABASE_PASS_ROOT:-$root_user_pass}"
export DATABASE_USER_NORMAL="$db_normal_user"
export DATABASE_PASS_NORMAL="$db_normal_pass"
export DATABASE_USER_ROOT="$db_admin_user"
export DATABASE_PASS_ROOT="$db_admin_pass"
export db_normal_user db_normal_pass db_admin_user db_admin_pass
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_system_etc() {
local conf_dir="$1"
local dir=""
local file=()
local directories=""
if [ -n "$conf_dir" ] && [ -e "$conf_dir" ]; then
files="$(find "$conf_dir"/* -not -path '*/env/*' -type f 2>/dev/null | sed 's|'/config/'||g' | sort -u | grep -v '^$' | grep '.' || false)"
directories="$(find "$conf_dir"/* -not -path '*/env/*' -type d 2>/dev/null | sed 's|'/config/'||g' | sort -u | grep -v '^$' | grep '.' || false)"
echo "Copying config files to system: $conf_dir > /etc/${conf_dir//\/config\//}"
if [ -n "$directories" ]; then
for d in $directories; do
dir="/etc/$d"
echo "Creating directory: $dir"
mkdir -p "$dir"
done
fi
for f in $files; do
etc_file="/etc/$f"
conf_file="/config/$f"
[ -f "$etc_file" ] && __rm "$etc_file"
__symlink "$etc_file" "$conf_file"
__initialize_replace_variables "$conf_file" "$etc_file"
[ -e "/data/$f" ] && __initialize_replace_variables "/data/$f"
done
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_custom_bin_dir() {
local SET_USR_BIN=""
[ -d "/data/bin" ] && SET_USR_BIN+="$(__find /data/bin f) "
[ -d "/config/bin" ] && SET_USR_BIN+="$(__find /config/bin f) "
if [ -n "$SET_USR_BIN" ]; then
echo "Setting up bin $SET_USR_BIN > $LOCAL_BIN_DIR"
for create_bin_template in $SET_USR_BIN; do
if [ -n "$create_bin_template" ]; then
create_bin_name="$(basename "$create_bin_template")"
if [ -e "$create_bin_template" ]; then
ln -sf "$create_bin_template" "$LOCAL_BIN_DIR/$create_bin_name"
fi
fi
done
unset create_bin_template create_bin_name SET_USR_BIN
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_default_templates() {
if [ -n "$DEFAULT_TEMPLATE_DIR" ]; then
if [ "$CONFIG_DIR_INITIALIZED" = "false" ] && [ -d "/config" ]; then
echo "Copying default config files $DEFAULT_TEMPLATE_DIR > /config"
for create_config_template in "$DEFAULT_TEMPLATE_DIR"/*; do
if [ -n "$create_config_template" ]; then
create_template_name="$(basename "$create_config_template")"
if [ -d "$create_config_template" ]; then
mkdir -p "/config/$create_template_name/"
__is_dir_empty "/config/$create_template_name" && cp -Rf "$create_config_template/." "/config/$create_template_name/" 2>/dev/null
elif [ -e "$create_config_template" ]; then
[ -e "/config/$create_template_name" ] || cp -Rf "$create_config_template" "/config/$create_template_name" 2>/dev/null
fi
fi
done
unset create_config_template create_template_name
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_config_dir() {
if [ -n "$DEFAULT_CONF_DIR" ]; then
if [ "$CONFIG_DIR_INITIALIZED" = "false" ] && [ -d "/config" ]; then
echo "Copying custom config files: $DEFAULT_CONF_DIR > /config"
for create_config_template in "$DEFAULT_CONF_DIR"/*; do
create_config_name="$(basename "$create_config_template")"
if [ -n "$create_config_template" ]; then
if [ -d "$create_config_template" ]; then
mkdir -p "/config/$create_config_name"
__is_dir_empty "/config/$create_config_name" && cp -Rf "$create_config_template/." "/config/$create_config_name/" 2>/dev/null
elif [ -e "$create_config_template" ]; then
[ -e "/config/$create_config_name" ] || cp -Rf "$create_config_template" "/config/$create_config_name" 2>/dev/null
fi
fi
done
unset create_config_template create_config_name
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_data_dir() {
if [ -d "/data" ]; then
if [ "$DATA_DIR_INITIALIZED" = "false" ] && [ -n "$DEFAULT_DATA_DIR" ]; then
echo "Copying data files $DEFAULT_DATA_DIR > /data"
for create_data_template in "$DEFAULT_DATA_DIR"/*; do
create_data_name="$(basename "$create_data_template")"
if [ -n "$create_data_template" ]; then
if [ -d "$create_data_template" ]; then
mkdir -p "/data/$create_data_name"
__is_dir_empty "/data/$create_data_name" && cp -Rf "$create_data_template/." "/data/$create_data_name/" 2>/dev/null
elif [ -e "$create_data_template" ]; then
[ -e "/data/$create_data_name" ] || cp -Rf "$create_data_template" "/data/$create_data_name" 2>/dev/null
fi
fi
done
unset create_template
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_www_root() {
local WWW_INIT=""
local WWW_TEMPLATE=""
[ -d "/usr/local/share/httpd/default" ] && WWW_TEMPLATE="/usr/local/share/httpd/default"
[ "$WWW_ROOT_DIR" = "/app" ] && WWW_INIT="${WWW_INIT:-true}"
[ "$WWW_ROOT_DIR" = "/data/htdocs" ] && WWW_INIT="${WWW_INIT:-true}"
if __is_dir_empty "$WWW_ROOT_DIR/"; then
WWW_INIT="true"
else
WWW_INIT="false"
fi
if [ "$WWW_INIT" = "true" ] && [ -d "$WWW_TEMPLATE" ]; then
cp -Rf "$DEFAULT_DATA_DIR/data/htdocs/." "$WWW_ROOT_DIR/" 2>/dev/null
fi
__initialize_web_health "$WWW_ROOT_DIR"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__is_htdocs_mounted() {
WWW_ROOT_DIR="${WWW_ROOT_DIR:-/data/htdocs}"
[ -n "$ENV_WWW_ROOT_DIR" ] && WWW_ROOT_DIR="$ENV_WWW_ROOT_DIR"
if [ -n "$IMPORT_FROM_GIT" ]; then
if ! echo "$IMPORT_FROM_GIT" | grep -qE 'https://|http://|git://|ssh://'; then
unset IMPORT_FROM_GIT
fi
fi
if [ -n "$IMPORT_FROM_GIT" ] && [ "$(command -v "git" 2>/dev/null)" ]; then
if __is_dir_empty "$WWW_ROOT_DIR"; then
echo "Importing project from $IMPORT_FROM_GIT to $WWW_ROOT_DIR"
git clone -q "$IMPORT_FROM_GIT" "$WWW_ROOT_DIR"
elif [ -d "$WWW_ROOT_DIR" ]; then
echo "Updating the project in $WWW_ROOT_DIR"
git -C pull -q "$WWW_ROOT_DIR"
fi
elif [ -d "/app" ]; then
WWW_ROOT_DIR="/app"
elif [ -d "/data/htdocs/www" ]; then
WWW_ROOT_DIR="/data/htdocs/www"
elif [ -d "/data/htdocs/root" ]; then
WWW_ROOT_DIR="/data/htdocs/root"
elif [ -d "/data/htdocs" ]; then
WWW_ROOT_DIR="/data/htdocs"
elif [ -d "/data/wwwroot" ]; then
WWW_ROOT_DIR="/data/wwwroot"
fi
[ -d "$WWW_ROOT_DIR" ] || mkdir -p "$WWW_ROOT_DIR"
export WWW_ROOT_DIR="${WWW_ROOT_DIR:-/usr/local/share/httpd/default}"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__initialize_ssl_certs() {
[ "$SSL_ENABLED" = "yes" ] && __certbot
if [ -d "/config/letsencrypt" ]; then
mkdir -p "/etc/letsencrypt"
__file_copy "/config/letsencrypt" "/etc/letsencrypt/"
elif [ -d "/etc/letsencrypt" ] && [ ! -d "/config/letsencrypt" ]; then
mkdir -p "/config/letsencrypt"
__file_copy "/etc/letsencrypt" "/config/letsencrypt/"
else
[ -d "$SSL_DIR" ] || mkdir -p "$SSL_DIR"
if [ "$SSL_ENABLED" = "true" ] || [ "$SSL_ENABLED" = "yes" ]; then
if [ -f "$SSL_CERT" ] && [ -f "$SSL_KEY" ]; then
SSL_ENABLED="true"
if [ -n "$SSL_CA" ] && [ -f "$SSL_CA" ]; then
mkdir -p "$SSL_DIR/certs"
cat "$SSL_CA" >>"/etc/ssl/certs/ca-certificates.crt"
cp -Rf "/." "$SSL_DIR/"
fi
else
[ -d "$SSL_DIR" ] || mkdir -p "$SSL_DIR"
__create_ssl_cert
fi
fi
fi
type update-ca-certificates &>/dev/null && update-ca-certificates &>/dev/null
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__start_php_dev_server() {
if [ "$2" = "yes" ]; then
if [ -d "/usr/local/share/httpd" ]; then
find "/usr/local/share/httpd" -type f -not -path '.git*' -iname '*.php' -exec sed -i 's|[<].*SERVER_ADDR.*[>]|'${CONTAINER_IP4_ADDRESS:-127.0.0.1}'|g' {} \; 2>/dev/null
php -S 0.0.0.0:$PHP_DEV_SERVER_PORT -t "/usr/local/share/httpd"
fi
if ! echo "$1" | grep -q "^/usr/local/share/httpd"; then
find "$1" -type f -not -path '.git*' -iname '*.php' -exec sed -i 's|[<].*SERVER_ADDR.*[>]|'${CONTAINER_IP4_ADDRESS:-127.0.0.1}'|g' {} \; 2>/dev/null
php -S 0.0.0.0:$PHP_DEV_SERVER_PORT -t "$1"
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__check_service() {
if [ "$1" = "check" ]; then
shift $#
__proc_check "$EXEC_CMD_NAME" || __proc_check "$EXEC_CMD_BIN"
exit $?
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__switch_to_user() {
# Use SERVICE_USER if set, otherwise fall back to RUNAS_USER
local switch_user="${SERVICE_USER:-$RUNAS_USER}"
if [ "$switch_user" = "root" ]; then
su_exec=""
su_cmd() { eval "$@" || return 1; }
elif [ "$(builtin type -P gosu)" ]; then
su_exec="gosu $switch_user"
su_cmd() { $su_exec "$@" || return 1; }
elif [ "$(builtin type -P runuser)" ]; then
su_exec="runuser -u $switch_user"
su_cmd() { $su_exec "$@" || return 1; }
elif [ "$(builtin type -P sudo)" ]; then
su_exec="sudo -u $switch_user"
su_cmd() { $su_exec "$@" || return 1; }
elif [ "$(builtin type -P su)" ]; then
su_exec="su -s /bin/sh - $switch_user"
su_cmd() { $su_exec -c "$@" || return 1; }
else
su_exec=""
su_cmd() {
echo "Can not switch to $switch_user: attempting to run as root"
if ! eval "$@"; then
return 1
fi
}
fi
export su_exec
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# usage backup "days" "hours"
__backup() {
local dirs="" backup_dir backup_name backup_exclude runTime cronTime maxDays
if test -n "$1" && test -z "${1//[0-9]/}"; then
maxDays="$1"
shift 1
else
maxDays="7"
fi
if test -n "$1" && test -z "${1//[0-9]/}"; then
cronTime="$1"
shift 1
else
cronTime=""
fi
local exitCodeP=0
local exitStatus=0
local pidFile="/run/backup.pid"
local logDir="/data/log/backups"
maxDays="${BACKUP_MAX_DAYS:-$maxDays}"
cronTime="${BACKUP_RUN_CRON:-$cronTime}"
backup_dir="$BACKUP_DIR/$(date +'%y/%m')"
backup_name="$(date +'%d_%H-%M').tar.gz"
backup_exclude="/data/logs $BACKUP_DIR $BACK_EXCLUDE_DIR"
[ -d "/data" ] && dirs+="/data "
[ -d "/config" ] && dirs+="/config "
[ -d "$logDir" ] || mkdir -p "$logDir"
[ -d "$backup_dir" ] || mkdir -p "$backup_dir"
[ -z "$dirs" ] && echo "BACKUP_DIR is unset" >&2 && return 1
[ -f "$pidFile" ] && echo "A backup job is already running" >&2 && return 1
echo "$$" >"$pidFile"
echo "Starting backup in $(date)" >>"$logDir/$CONTAINER_NAME"
tar --exclude $backup_exclude cfvz "$backup_dir/$backup_name" $dirs 2>/dev/stderr >>"$logDir/$CONTAINER_NAME" || exitCodeP=1
if [ $exitCodeP -eq 0 ]; then
echo "Backup has completed and saved to: $backup_dir/$backup_name"
printf '%s\n\n' "Backup has completed on $(date)" >>"$logDir/$CONTAINER_NAME"
else
__rm "${backup_dir:?}/$backup_name"
echo "Backup has failed - log file saved to: $logDir/$CONTAINER_NAME" >&2
printf '%s\n\n' "Backup has completed on $(date)" >>"$logDir/$CONTAINER_NAME"
exitStatus=1
fi
[ -f "$pidFile" ] && __rm "$pidFile"
[ -n "$maxDays" ] && find "$BACKUP_DIR"* -mtime +$maxDays -exec rm -Rf {} \; >/dev/null 2>&1
if [ -n "$cronTime" ]; then
runTime=$((cronTime * 3600))
else
return $exitStatus
fi
sleep $runTime && __backup "$maxDays" "$cronTime"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set variables from function calls
export INIT_DATE="${INIT_DATE:-$(date)}"
export START_SERVICES="${START_SERVICES:-yes}"
export ENTRYPOINT_MESSAGE="${ENTRYPOINT_MESSAGE:-yes}"
export ENTRYPOINT_FIRST_RUN="${ENTRYPOINT_FIRST_RUN:-yes}"
export DATA_DIR_INITIALIZED="${DATA_DIR_INITIALIZED:-false}"
export CONFIG_DIR_INITIALIZED="${CONFIG_DIR_INITIALIZED:-false}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# System
export LANG="${LANG:-C.UTF-8}"
export LC_ALL="${LANG:-C.UTF-8}"
export TZ="${TZ:-${TIMEZONE:-America/New_York}}"
export HOSTNAME="${FULL_DOMAIN_NAME:-${SERVER_HOSTNAME:-$HOSTNAME}}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Default directories
export SSL_DIR="${SSL_DIR:-/config/ssl}"
export SSL_CA="${SSL_CERT:-/config/ssl/ca.crt}"
export SSL_KEY="${SSL_KEY:-/config/ssl/localhost.pem}"
export SSL_CERT="${SSL_CERT:-/config/ssl/localhost.crt}"
export LOCAL_BIN_DIR="${LOCAL_BIN_DIR:-/usr/local/bin}"
export DEFAULT_DATA_DIR="${DEFAULT_DATA_DIR:-/usr/local/share/template-files/data}"
export DEFAULT_CONF_DIR="${DEFAULT_CONF_DIR:-/usr/local/share/template-files/config}"
export DEFAULT_TEMPLATE_DIR="${DEFAULT_TEMPLATE_DIR:-/usr/local/share/template-files/defaults}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Backup settings
export BACKUP_MAX_DAYS="${BACKUP_MAX_DAYS:-}"
export BACKUP_RUN_CRON="${BACKUP_RUN_CRON:-}"
export BACKUP_DIR="${BACKUP_DIR:-/data/backups}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
CONTAINER_IP4_ADDRESS="${CONTAINER_IP4_ADDRESS:-$(__get_ip4)}"
CONTAINER_IP6_ADDRESS="${CONTAINER_IP6_ADDRESS:-$(__get_ip6)}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Additional
export WORK_DIR="${ENV_WORK_DIR:-$WORK_DIR}"
export SET_RANDOM_PASS="${SET_RANDOM_PASS:-$(__random_password 16)}"
export PHP_INI_DIR="${PHP_INI_DIR:-$(__find_php_ini)}"
export PHP_BIN_DIR="${PHP_BIN_DIR:-$(__find_php_bin)}"
export HTTPD_CONFIG_FILE="${HTTPD_CONFIG_FILE:-$(__find_httpd_conf)}"
export NGINX_CONFIG_FILE="${NGINX_CONFIG_FILE:-$(__find_nginx_conf)}"
export MYSQL_CONFIG_FILE="${MYSQL_CONFIG_FILE:-$(__find_mysql_conf)}"
export PGSQL_CONFIG_FILE="${PGSQL_CONFIG_FILE:-$(__find_pgsql_conf)}"
export LIGHTTPD_CONFIG_FILE="${LIGHTTPD_CONFIG_FILE:-$(__find_lighttpd_conf)}"
export MARIADB_CONFIG_FILE="${MARIADB_CONFIG_FILE:-$(__find_mysql_conf)}"
export POSTGRES_CONFIG_FILE="${POSTGRES_CONFIG_FILE:-$(__find_pgsql_conf)}"
export MONGODB_CONFIG_FILE="${MONGODB_CONFIG_FILE:-$(__find_mongodb_conf)}"
export ENTRYPOINT_PID_FILE="${ENTRYPOINT_PID_FILE:-/run/init.d/entrypoint.pid}"
export ENTRYPOINT_INIT_FILE="${ENTRYPOINT_INIT_FILE:-/config/.entrypoint.done}"
export ENTRYPOINT_DATA_INIT_FILE="${ENTRYPOINT_DATA_INIT_FILE:-/data/.docker_has_run}"
export ENTRYPOINT_CONFIG_INIT_FILE="${ENTRYPOINT_CONFIG_INIT_FILE:-/config/.docker_has_run}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# is already Initialized
if [ -z "$DATA_DIR_INITIALIZED" ]; then
if [ -f "$ENTRYPOINT_DATA_INIT_FILE" ]; then
DATA_DIR_INITIALIZED="true"
else
DATA_DIR_INITIALIZED="false"
fi
fi
if [ -z "$CONFIG_DIR_INITIALIZED" ]; then
if [ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ]; then
CONFIG_DIR_INITIALIZED="true"
else
CONFIG_DIR_INITIALIZED="false"
fi
fi
if [ -z "$ENTRYPOINT_FIRST_RUN" ]; then
if [ -f "$ENTRYPOINT_PID_FILE" ] || [ -f "$ENTRYPOINT_INIT_FILE" ]; then
ENTRYPOINT_FIRST_RUN="no"
else
ENTRYPOINT_FIRST_RUN="true"
fi
fi
export ENTRYPOINT_DATA_INIT_FILE DATA_DIR_INITIALIZED ENTRYPOINT_CONFIG_INIT_FILE CONFIG_DIR_INITIALIZED
export ENTRYPOINT_PID_FILE ENTRYPOINT_INIT_FILE ENTRYPOINT_FIRST_RUN
# - - - - - - - - - - - - - - - - - - - - - - - - -
# export the functions
export -f __get_pid __start_init_scripts __is_running __certbot __update_ssl_certs __create_ssl_cert
# - - - - - - - - - - - - - - - - - - - - - - - - -
# end of functions