Files
tor/rootfs/usr/local/etc/docker/init.d/03-tor-relay.sh
T

1023 lines
39 KiB
Bash
Raw Normal View History

2025-11-23 08:38:05 -05:00
#!/usr/bin/env bash
# shellcheck shell=bash
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
##@Version : 202605241142-git
2025-11-23 08:38:05 -05:00
# @@Author : Jason Hempstead
# @@Contact : jason@casjaysdev.pro
2026-05-26 17:35:40 -04:00
# @@License : WTFPL
2025-11-23 08:38:05 -05:00
# @@ReadME : tor.sh --help
2026-05-26 17:35:40 -04:00
# @@Copyright : Copyright: (c) 2026 Jason Hempstead, Casjays Developments
2025-11-23 08:38:05 -05:00
# @@Created : Monday, Jan 06, 2025 09:02 EST
# @@File : tor.sh
# @@Description :
# @@Changelog : New script
# @@TODO : Better documentation
# @@Other :
# @@Resource :
# @@Terminal App : no
# @@sudo/root : no
# @@Template : other/start-service
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
# shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329
# - - - - - - - - - - - - - - - - - - - - - - - - -
set -e
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# run trap command on exit
2026-05-26 17:35:40 -04:00
trap '__trap_err_handler' ERR
trap 'retVal=$?;if [ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ]; then rm -Rf "$SERVICE_PID_FILE"; fi;exit $retVal' SIGINT SIGTERM
trap 'retVal=$?;if [ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ]; then rm -Rf "$SERVICE_PID_FILE"; fi;exit $retVal' SIGPWR 2>/dev/null || true
# - - - - - - - - - - - - - - - - - - - - - - - - -
# ERR trap handler - smart about critical vs non-critical errors
__trap_err_handler() {
local retVal=$?
local command="$BASH_COMMAND"
# Ignore SIGPIPE and user interrupts
[ $retVal -eq 130 ] || [ $retVal -eq 141 ] && return $retVal
# Non-critical: file operations, text processing, user/group operations
if [[ "$command" =~ (mkdir|touch|chmod|chown|chgrp|ln|cp|mv|rm|echo|printf|cat|tee|sed|awk|grep|find|sort|uniq|adduser|addgroup|usermod|groupmod|id|getent) ]]; then
return 0
fi
# Non-critical: conditional checks that might fail
if [[ "$command" =~ (test|\[|\[\[|kill -0|pgrep|pidof|ps) ]]; then
return 0
fi
# Critical error - but only fail if service hasn't started yet
if [ "$SERVICE_IS_RUNNING" != "yes" ]; then
echo "❌ Critical error (exit $retVal): $command" >&2
kill -TERM 1 2>/dev/null || exit $retVal
fi
return 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
SCRIPT_FILE="$0"
SERVICE_NAME="tor-relay"
2026-05-26 17:35:40 -04:00
SCRIPT_NAME="${SCRIPT_FILE##*/}"
2025-11-23 08:38:05 -05:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Function to exit appropriately based on context
__script_exit() {
2026-05-26 17:35:40 -04:00
local exit_code="${1:-0}"
if [ "${BASH_SOURCE[0]}" != "${0}" ]; then
# Script is being sourced - use return
return "$exit_code"
else
# Script is being executed - use exit
exit "$exit_code"
fi
2025-11-23 08:38:05 -05:00
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Exit if service is disabled
2026-05-26 17:35:40 -04:00
if [ -n "$TOR_RELAY_ENABLED" ]; then
if [ "$TOR_RELAY_ENABLED" != "yes" ]; then
export SERVICE_DISABLED="$SERVICE_NAME"
__script_exit 0
fi
fi
2025-11-23 08:38:05 -05:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}"
2026-05-26 17:35:40 -04:00
if [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; then
echo "Enabling debugging"
set -o pipefail
[ -n "$DEBUGGER_OPTIONS" ] && set -"$DEBUGGER_OPTIONS"
export DEBUGGER="on"
else
set -o pipefail
fi
2025-11-23 08:38:05 -05:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# import the functions file
if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then
2026-05-26 17:35:40 -04:00
. "/usr/local/etc/docker/functions/entrypoint.sh"
2025-11-23 08:38:05 -05:00
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# import variables
for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do
2026-05-26 17:35:40 -04:00
if [ -f "$set_env" ]; then
. "$set_env"
fi
2025-11-23 08:38:05 -05:00
done
# - - - - - - - - - - - - - - - - - - - - - - - - -
# exit if __start_init_scripts function hasn't been Initialized
if [ ! -f "/run/.start_init_scripts.pid" ]; then
2026-05-26 17:35:40 -04:00
echo "__start_init_scripts function hasn't been Initialized" >&2
SERVICE_IS_RUNNING="no"
__script_exit 1
2025-11-23 08:38:05 -05:00
fi
# Clean up any stale PID file for this service on startup
if [ -n "$SERVICE_NAME" ] && [ -f "/run/init.d/$SERVICE_NAME.pid" ]; then
2026-05-26 17:35:40 -04:00
old_pid=$(<"/run/init.d/$SERVICE_NAME.pid") 2>/dev/null
if [ -n "$old_pid" ] && ! kill -0 "$old_pid" 2>/dev/null; then
echo "🧹 Removing stale PID file for $SERVICE_NAME"
rm -f "/run/init.d/$SERVICE_NAME.pid"
fi
2025-11-23 08:38:05 -05:00
fi
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Custom functions
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Script to execute
START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Reset environment before executing service
RESET_ENV="yes"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set webroot
WWW_ROOT_DIR="/usr/local/share/httpd/default"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Default predefined variables
2026-05-26 17:35:40 -04:00
# set data directory
DATA_DIR="/data/tor/relay"
# set config directory
CONF_DIR="/config/tor/relay"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# set the containers etc directory
ETC_DIR="/etc/tor/relay"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# set the var dir
VAR_DIR=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set the temp dir
TMP_DIR="/tmp/tor"
# set scripts pid dir
RUN_DIR="/run/tor/relay"
# set log directory
LOG_DIR="/data/logs/tor"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set the working dir
WORK_DIR=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# port which service is listening on
SERVICE_PORT=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# User to use to launch service - IE: postgres
2026-05-26 17:35:40 -04:00
# normally root
RUNAS_USER="root"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# User and group in which the service switches to - IE: nginx,apache,mysql,postgres
2026-05-26 17:35:40 -04:00
# execute command as another user
SERVICE_USER="root"
# Set the service group
SERVICE_GROUP="root"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set password length
RANDOM_PASS_USER=""
RANDOM_PASS_ROOT=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set user and group ID
2026-05-26 17:35:40 -04:00
# set the user id
SERVICE_UID="0"
# set the group id
SERVICE_GID="0"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# execute command variables - keep single quotes variables will be expanded later
2026-05-26 17:35:40 -04:00
# command to execute
EXEC_CMD_BIN='tor-relay'
# command arguments
EXEC_CMD_ARGS='-f $CONF_DIR/relay.conf'
# execute script before
EXEC_PRE_SCRIPT=''
# Set to 'no' for configuration services (no daemon process), leave blank for actual services
SERVICE_USES_PID=''
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Is this service a web server
IS_WEB_SERVER="no"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Is this service a database server
IS_DATABASE_SERVICE="no"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Does this service use a database server
USES_DATABASE_SERVICE="no"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase]
DATABASE_SERVICE_TYPE="sqlite"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Show message before execute
PRE_EXEC_MESSAGE=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set the wait time to execute __post_execute function - minutes
POST_EXECUTE_WAIT_TIME="1"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Update path var
PATH="$PATH:."
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Where to save passwords to
2026-05-26 17:35:40 -04:00
# directory to save username/password for root user
ROOT_FILE_PREFIX="/config/secure/auth/root"
# directory to save username/password for normal user
USER_FILE_PREFIX="/config/secure/auth/user"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# root/admin user info password/random]
2026-05-26 17:35:40 -04:00
# root user name
root_user_name="${TOR_ROOT_USER_NAME:-}"
# root user password
root_user_pass="${TOR_ROOT_PASS_WORD:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Normal user info [password/random]
2026-05-26 17:35:40 -04:00
# normal user name
user_name="${TOR_USER_NAME:-}"
# normal user password
user_pass="${TOR_USER_PASS_WORD:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Load variables from config
2026-05-26 17:35:40 -04:00
# Generated by my dockermgr script
if [ -f "/config/env/tor.script.sh" ]; then
. "/config/env/tor.script.sh"
fi
# Overwrite the variables
if [ -f "/config/env/tor.sh" ]; then
. "/config/env/tor.sh"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Additional predefined variables
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Additional variables
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Specifiy custom directories to be created
ADD_APPLICATION_FILES=""
ADD_APPLICATION_DIRS=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log"
2025-11-23 08:38:05 -05:00
APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR $DATA_DIR"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Additional config dirs - will be Copied to /etc/$name
ADDITIONAL_CONFIG_DIRS=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\"
CMD_ENV=""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Overwrite based on file/directory
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Per Application Variables or imports
TOR_DNS_ENABLED="${TOR_DNS_ENABLED:-yes}"
TOR_RELAY_ENABLED="${TOR_RELAY_ENABLED:-yes}"
TOR_BRIDGE_ENABLED="${TOR_BRIDGE_ENABLED:-yes}"
TOR_HIDDEN_ENABLED="${TOR_HIDDEN_ENABLED:-yes}"
TOR_RELAY_PORT="${TOR_RELAY_PORT:-57000}"
TOR_RELAY_OR_PORT="${TOR_RELAY_OR_PORT:-57001}"
TOR_RELAY_DIR_PORT="${TOR_RELAY_DIR_PORT:-57002}"
TOR_RELAY_NICK_NAME="${TOR_RELAY_NICK_NAME:-}"
TOR_RELAY_ADMIN="${TOR_RELAY_ADMIN:-}"
TOR_RELAY_TOTAL_BANDWIDTH="${TOR_RELAY_TOTAL_BANDWIDTH:-250 GBytes}"
RANDOM_NICK="$(head -n50 '/dev/random' | tr -dc 'a-zA-Z' | tr -d '[:space:]\042\047\134' | fold -w "18" | sed 's| ||g' | head -n 1)"
HAS_IPV6="$([ -n "$(type -P ifconfig 2>/dev/null)" ] && ifconfig "eth0" | grep 'inet6' | grep 'global')"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Custom commands to run before copying to /config
__run_precopy() {
# Define environment
local hostname=${HOSTNAME}
local tor_bin="$(type -P "tor" 2>/dev/null)"
local server_bin="$(type -P "tor-relay" 2>/dev/null)"
2026-05-26 17:35:40 -04:00
if [ ! -d "/run/healthcheck" ]; then
mkdir -p "/run/healthcheck"
fi
2025-11-23 08:38:05 -05:00
# Define actions/commands
[ -d "$DATA_DIR" ] || mkdir -p "$DATA_DIR"
[ -n "$tor_bin" ] && [ -z "$server_bin" ] && cp -Rf "$tor_bin" "/usr/local/bin/tor-relay"
chmod +x "/usr/local/bin/tor-relay"
# allow custom functions
2026-05-26 17:35:40 -04:00
if builtin type -t __run_precopy_local | grep -q 'function'; then
__run_precopy_local
fi
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Custom prerun functions - IE setup WWW_ROOT_DIR
__execute_prerun() {
# Define environment
local hostname=${HOSTNAME}
# Define actions/commands
# allow custom functions
2026-05-26 17:35:40 -04:00
if builtin type -t __execute_prerun_local | grep -q 'function'; then
__execute_prerun_local
fi
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Run any pre-execution checks
__run_pre_execute_checks() {
2026-05-26 17:35:40 -04:00
# Set variables
local exitStatus=0
# message to show at start
local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME"
# message to show at completion
local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME"
__banner "$pre_execute_checks_MessageST"
# Put command to execute in parentheses
{
true
}
exitStatus=$?
__banner "$pre_execute_checks_MessageEnd: Status $exitStatus"
2025-11-23 08:38:05 -05:00
2026-05-26 17:35:40 -04:00
# show exit message
if [ $exitStatus -ne 0 ]; then
echo "The pre-execution check has failed" >&2
if [ -f "$SERVICE_PID_FILE" ]; then
rm -Rf "$SERVICE_PID_FILE"
fi
__script_exit 1
fi
# allow custom functions
if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then
__run_pre_execute_checks_local
fi
# exit function
return $exitStatus
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# use this function to update config files - IE: change port
__update_conf_files() {
2026-05-26 17:35:40 -04:00
local exitCode=0
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# delete files
#__rm ""
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# custom commands
chmod 600 $RUN_DIR
chown -Rf ${SERVICE_USER:-$RUNAS_USER}:${SERVICE_GROUP:-$RUNAS_USER} $RUN_DIR
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# replace variables
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# define actions
mkdir -p "$CONF_DIR/conf.d"
cat <<EOF >"$CONF_DIR/relay.conf"
##### Relay
RunAsDaemon 0
HardwareAccel 1
AddressDisableIPv6 0
#### control settings
ControlSocketsGroupWritable 1
CookieAuthentication 1
CookieAuthFileGroupReadable 1
HashedControlPassword 16:C30604D1D90F341360A14D9A1048C1DF4A3CA2411444E52EE5B954C01F
##### directiories and files
DataDirectory $DATA_DIR
ControlSocket $RUN_DIR/relay.sock
CookieAuthFile $RUN_DIR/relay.authcookie
##### socks option
SOCKSPort 0
SafeSocks ${TOR_SOCKS_SAFE:-0}
SocksTimeout ${TOR_SOCKS_TIMEOUT:-10}
##### logging
LogMessageDomains 1
Log notice file $LOG_DIR/$SERVICE_NAME.log
#Log debug file $LOG_DIR/$SERVICE_NAME.debug
##### Relay Settings
ExitRelay 0
PublishServerDescriptor 1
ServerTransportPlugin obfs4 exec /usr/bin/lyrebird
ServerTransportListenAddr obfs4 0.0.0.0:${TOR_RELAY_PORT:-57000}
ORPort ${TOR_RELAY_OR_PORT:-57001}
DirPort ${TOR_RELAY_DIR_PORT:-57002}
Nickname ${TOR_RELAY_NICK_NAME:-$RANDOM_NICK}
ContactInfo ${TOR_RELAY_ADMIN:-tor-admin@$HOSTNAME}
AccountingMax 250 GBytes
RelayBandwidthRate 96 KB
RelayBandwidthBurst 192 KB
AccountingStart month 1 00:00
DirPortFrontPage /usr/share/tor/html/exit.html
# Not an exit node
ExitPolicy reject *:*
# Reduce rejected circuits
DirReqStatistics 0
ExtraInfoStatistics 1
%include $CONF_DIR/conf.d/*.conf
EOF
[ -f "$CONF_DIR/conf.d/default.conf" ] || touch "$CONF_DIR/conf.d/default.conf"
if [ "$TOR_DEBUG" = "yes" ]; then
sed -i 's|#Log debug|Log debug|g' "$CONF_DIR/relay.conf"
fi
if [ -z "$HAS_IPV6" ]; then
sed -i 's|AddressDisableIPv6 0|AddressDisableIPv6 1|g' "$CONF_DIR/relay.conf"
fi
# allow custom functions
2026-05-26 17:35:40 -04:00
if builtin type -t __update_conf_files_local | grep -q 'function'; then
__update_conf_files_local
fi
2025-11-23 08:38:05 -05:00
# exit function
return $exitCode
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# function to run before executing
__pre_execute() {
2026-05-26 17:35:40 -04:00
local exitCode=0
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# execute if directories is empty
# __is_dir_empty "$CONF_DIR" && true
# - - - - - - - - - - - - - - - - - - - - - - - - -
# define actions to run after copying to /config
2025-11-23 08:38:05 -05:00
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
# unset unneeded variables
unset sysname
# Lets wait a few seconds before continuing
sleep 2
# allow custom functions
if builtin type -t __pre_execute_local | grep -q 'function'; then
__pre_execute_local
fi
# exit function
return $exitCode
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# function to run after executing
__post_execute() {
2026-05-26 17:35:40 -04:00
local pid=""
local retVal=0
local ctime=${POST_EXECUTE_WAIT_TIME:-1}
local waitTime=$((ctime * 60))
local postMessageST="Running post commands for $SERVICE_NAME"
local postMessageEnd="Finished post commands for $SERVICE_NAME"
2025-11-23 08:38:05 -05:00
# wait
sleep $waitTime
# execute commands after waiting
(
# show message
__banner "$postMessageST"
# commands to execute
sleep 5
if [ -f "/data/tor/relay/fingerprint" ]; then
cat "/data/tor/relay/fingerprint"
fi
# show exit message
__banner "$postMessageEnd: Status $retVal"
) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" &
2026-05-26 17:35:40 -04:00
# fire-and-forget: backgrounded subshell always succeeds at launch
retVal=0
2025-11-23 08:38:05 -05:00
# allow custom functions
2026-05-26 17:35:40 -04:00
if builtin type -t __post_execute_local | grep -q 'function'; then
__post_execute_local
fi
2025-11-23 08:38:05 -05:00
# exit function
return $retVal
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# use this function to update config files - IE: change port
__pre_message() {
2026-05-26 17:35:40 -04:00
local exitCode=0
if [ -n "$PRE_EXEC_MESSAGE" ]; then
eval echo "$PRE_EXEC_MESSAGE"
fi
# execute commands
2025-11-23 08:38:05 -05:00
2026-05-26 17:35:40 -04:00
# allow custom functions
if builtin type -t __pre_message_local | grep -q 'function'; then
__pre_message_local
fi
# exit function
return $exitCode
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# use this function to setup ssl support
__update_ssl_conf() {
2026-05-26 17:35:40 -04:00
local exitCode=0
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# execute commands
2025-11-23 08:38:05 -05:00
2026-05-26 17:35:40 -04:00
# allow custom functions
if builtin type -t __update_ssl_conf_local | grep -q 'function'; then
__update_ssl_conf_local
fi
# set exitCode
return $exitCode
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
__create_service_env() {
2026-05-26 17:35:40 -04:00
local exitCode=0
if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then
cat <<EOF | tee -p "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" &>/dev/null
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# root/admin user info [password/random]
#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$TOR_ROOT_USER_NAME}" # root user name
#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$TOR_ROOT_PASS_WORD}" # root user password
#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" #
#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" #
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
#Normal user info [password/random]
#ENV_USER_NAME="${ENV_USER_NAME:-$TOR_USER_NAME}" #
#ENV_USER_PASS="${ENV_USER_PASS:-$TOR_USER_PASS_WORD}" #
#user_name="${ENV_USER_NAME:-$user_name}" # normal user name
#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password
EOF
2026-05-26 17:35:40 -04:00
fi
if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then
# - - - - - - - - - - - - - - - - - - - - - - - - -
__run_precopy_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__execute_prerun_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__run_pre_execute_checks_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__update_conf_files_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__pre_execute_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__post_execute_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__pre_message_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
__update_ssl_conf_local() { true; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
fi
if ! __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh"; then
exitCode=$((exitCode + 1))
fi
if ! __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh"; then
exitCode=$((exitCode + 1))
fi
return $exitCode
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# script to start server
__run_start_script() {
2026-05-26 17:35:40 -04:00
local runExitCode=0
# expand variables
local workdir="$(eval echo "${WORK_DIR:-}")"
# expand variables
local cmd="$(eval echo "${EXEC_CMD_BIN:-}")"
# expand variables
local args="$(eval echo "${EXEC_CMD_ARGS:-}")"
# expand variables
local name="$(eval echo "${EXEC_CMD_NAME:-}")"
# expand variables
local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")"
# expand variables
local extra_env="$(eval echo "${CMD_ENV//,/ }")"
# expand variables
local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")"
# expand variables
local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")"
# expand variables
local path="$(eval echo "$PATH")"
# expand variables
local message="$(eval echo "")"
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
if [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ]; then
. "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh"
fi
#
if [ -z "$cmd" ]; then
__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt"
retVal=$?
__log_info "Initialization of $SCRIPT_NAME has completed"
__script_exit $retVal
else
# ensure the command exists
if [ ! -x "$cmd" ]; then
__log_error "$name is not a valid executable"
return 2
fi
# check and exit if already running (respects SERVICE_USES_PID in __proc_check)
if __proc_check "$name" || __proc_check "$cmd"; then
__log_debug "Service $name is already running"
return 0
else
# - - - - - - - - - - - - - - - - - - - - - - - - -
# show message if env exists
if [ -n "$cmd" ]; then
if [ -n "$SERVICE_USER" ]; then
__log_info "Setting up $cmd to run as $SERVICE_USER"
else
SERVICE_USER="root"
fi
if [ -n "$SERVICE_PORT" ]; then
__log_info "$name will be running on port $SERVICE_PORT"
else
SERVICE_PORT=""
fi
fi
if [ -n "$pre" ] && command -v "$pre" &>/dev/null; then
export cmd_exec="$pre $cmd $args"
message="Starting service: $name $args through $pre"
else
export cmd_exec="$cmd $args"
message="Starting service: $name $args"
fi
if [ -n "$su_exec" ]; then
__log_debug "Using $su_exec" | tee -a -p "/data/logs/init.txt"
fi
__log_info "$message" | tee -a -p "/data/logs/init.txt"
su_cmd touch "$SERVICE_PID_FILE"
# W14: invalidate cached START_SCRIPT if key variables changed
local _script_hash_src="$cmd $args $SERVICE_USER $RESET_ENV $su_exec"
local _script_hash
_script_hash=$(printf '%s' "$_script_hash_src" | md5sum 2>/dev/null | cut -c1-8 || true)
if [ -f "${START_SCRIPT}.hash" ] && [ -f "$START_SCRIPT" ]; then
if [ "$(cat "${START_SCRIPT}.hash" 2>/dev/null)" != "$_script_hash" ]; then
rm -f "$START_SCRIPT" "${START_SCRIPT}.hash"
fi
fi
if [ "$RESET_ENV" = "yes" ]; then
# RESET_ENV=yes intentionally strips all inherited vars; only explicit vars are passed
if [ ! -f "$START_SCRIPT" ]; then
# Use printf %q to safely quote each env component for embedding in the script
local _q_home _q_lc _q_path _q_sysname _q_svcuser _q_su _q_cmd _q_args _q_extra
_q_home=$(printf '%q' "$home")
_q_lc=$(printf '%q' "$lc_type")
_q_path=$(printf '%q' "$path")
_q_sysname=$(printf '%q' "$sysname")
_q_svcuser=$(printf '%q' "${SERVICE_USER:-$RUNAS_USER}")
_q_su=${su_exec:+$(printf '%q ' $su_exec)}
2026-05-26 17:35:40 -04:00
_q_cmd=$(printf '%q' "$cmd")
_q_args=${args:+$(printf '%q ' $args)}
_q_extra=${extra_env:+$(printf '%q ' $extra_env)}
2026-05-26 17:35:40 -04:00
{
printf '#!/usr/bin/env bash\n'
printf "trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f \"\$SERVICE_PID_FILE\" ] && rm -Rf \"\$SERVICE_PID_FILE\";exit \$exitCode' EXIT\n"
printf 'set -Eeo pipefail\n'
printf '# Setting up %s to run as %s with env\n' "$cmd" "${SERVICE_USER:-root}"
printf 'retVal=10\n'
printf 'SERVICE_NAME=%q\n' "$SERVICE_NAME"
printf 'SERVICE_PID_FILE=%q\n' "$SERVICE_PID_FILE"
printf 'LOG_DIR=%q\n' "$LOG_DIR"
printf '%s env -i HOME=%s LC_CTYPE=%s PATH=%s HOSTNAME=%s USER=%s %s %s %s 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" &\n' \
"$_q_su" "$_q_home" "$_q_lc" "$_q_path" "$_q_sysname" "$_q_svcuser" "$_q_extra" "$_q_cmd" "$_q_args"
printf 'execPid=$!\n'
printf 'sleep 1\n'
printf 'if [ -n "$execPid" ] && kill -0 "$execPid" 2>/dev/null; then\n'
printf ' echo "$execPid" >"$SERVICE_PID_FILE"\n'
printf ' retVal=0\n'
printf ' printf '"'"'%%s\n'"'"' "$SERVICE_NAME: $execPid" >"/run/healthcheck/$SERVICE_NAME"\n'
printf 'else\n'
printf ' retVal=10\n'
printf ' echo "Failed to start service %s" >&2\n' "$cmd"
printf 'fi\n'
printf 'exit $retVal\n'
} >"$START_SCRIPT"
printf '%s' "$_script_hash" >"${START_SCRIPT}.hash"
fi
else
if [ ! -f "$START_SCRIPT" ]; then
local _q_su _q_cmd _q_args
_q_su=${su_exec:+$(printf '%q ' $su_exec)}
2026-05-26 17:35:40 -04:00
_q_cmd=$(printf '%q' "$cmd")
_q_args=${args:+$(printf '%q ' $args)}
2026-05-26 17:35:40 -04:00
{
printf '#!/usr/bin/env bash\n'
printf "trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f \"\$SERVICE_PID_FILE\" ] && rm -Rf \"\$SERVICE_PID_FILE\";exit \$exitCode' EXIT\n"
printf 'set -Eeo pipefail\n'
printf '# Setting up %s to run as %s\n' "$cmd" "${SERVICE_USER:-root}"
printf 'retVal=10\n'
printf 'SERVICE_NAME=%q\n' "$SERVICE_NAME"
printf 'SERVICE_PID_FILE=%q\n' "$SERVICE_PID_FILE"
printf 'LOG_DIR=%q\n' "$LOG_DIR"
printf '%s %s %s 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" &\n' \
"$_q_su" "$_q_cmd" "$_q_args"
printf 'execPid=$!\n'
printf 'sleep 1\n'
printf 'if [ -n "$execPid" ] && kill -0 "$execPid" 2>/dev/null; then\n'
printf ' echo "$execPid" >"$SERVICE_PID_FILE"\n'
printf ' retVal=0\n'
printf 'else\n'
printf ' retVal=10\n'
printf ' echo "Failed to start service %s" >&2\n' "$cmd"
printf 'fi\n'
printf 'exit $retVal\n'
} >"$START_SCRIPT"
printf '%s' "$_script_hash" >"${START_SCRIPT}.hash"
fi
fi
fi
if [ ! -x "$START_SCRIPT" ]; then
chmod 755 -Rf "$START_SCRIPT"
fi
if [ "$CONTAINER_INIT" != "yes" ]; then
# W15: launch as bash, not sh, since the generated script uses bash-specific features
bash "$START_SCRIPT"
runExitCode=$?
fi
fi
return $runExitCode
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# username and password actions
__run_secure_function() {
2026-05-26 17:35:40 -04:00
local filesperms
if [ -n "$user_name" ] || [ -n "$user_pass" ]; then
for filesperms in "${USER_FILE_PREFIX}"/*; do
if [ -e "$filesperms" ]; then
chmod -Rf 600 "$filesperms"
[ -n "$SERVICE_USER" ] && chown -Rf "$SERVICE_USER:$SERVICE_USER" "$filesperms" 2>/dev/null
fi
done 2>/dev/null | tee -p -a "/data/logs/init.txt"
fi
if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then
for filesperms in "${ROOT_FILE_PREFIX}"/*; do
if [ -e "$filesperms" ]; then
chmod -Rf 600 "$filesperms"
[ -n "$SERVICE_USER" ] && chown -Rf "$SERVICE_USER:$SERVICE_USER" "$filesperms" 2>/dev/null
fi
done 2>/dev/null | tee -p -a "/data/logs/init.txt"
fi
unset filesperms
2025-11-23 08:38:05 -05:00
}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Allow ENV_ variable - Import env file
2026-05-26 17:35:40 -04:00
if __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh"; then
. "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh"
fi
if __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh"; then
. "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# default exit code
SERVICE_EXIT_CODE=0
2025-11-23 08:38:05 -05:00
# application specific
2026-05-26 17:35:40 -04:00
EXEC_CMD_NAME="${EXEC_CMD_BIN##*/}"
SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid"
_resolved="$(type -P "$EXEC_CMD_BIN" 2>/dev/null)"
[ -n "$_resolved" ] && EXEC_CMD_BIN="$_resolved"
_resolved="$(type -P "$EXEC_PRE_SCRIPT" 2>/dev/null)"
[ -n "$_resolved" ] && EXEC_PRE_SCRIPT="$_resolved"
unset _resolved
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Only run check when explicitly requested
if [ "$1" = "check" ] && __check_service "$1"; then
SERVICE_IS_RUNNING=yes
elif [ "$1" = "check" ]; then
SERVICE_IS_RUNNING="no"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# ensure needed directories exists
2026-05-26 17:35:40 -04:00
if [ ! -d "$LOG_DIR" ]; then
mkdir -p "$LOG_DIR"
fi
if [ ! -d "$RUN_DIR" ]; then
mkdir -p "$RUN_DIR"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# create auth directories
2026-05-26 17:35:40 -04:00
if [ -n "$USER_FILE_PREFIX" ]; then
if [ ! -d "$USER_FILE_PREFIX" ]; then
mkdir -p "$USER_FILE_PREFIX"
fi
fi
if [ -n "$ROOT_FILE_PREFIX" ]; then
if [ ! -d "$ROOT_FILE_PREFIX" ]; then
mkdir -p "$ROOT_FILE_PREFIX"
fi
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
if [ -z "$RUNAS_USER" ]; then
RUNAS_USER="root"
fi
if [ -z "$SERVICE_USER" ]; then
SERVICE_USER="$RUNAS_USER"
fi
if [ -z "$SERVICE_GROUP" ]; then
SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}"
fi
if [ "$IS_WEB_SERVER" = "yes" ]; then
RESET_ENV="yes"
__is_htdocs_mounted
fi
if [ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ]; then
SERVICE_PORT="80"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Database env
if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then
2026-05-26 17:35:40 -04:00
RESET_ENV="no"
DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}"
DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}"
DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}"
DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}"
DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}"
if [ -n "$DATABASE_PASS_NORMAL" ]; then
if [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then
echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user"
fi
fi
if [ -n "$DATABASE_PASS_ROOT" ]; then
if [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then
echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root"
fi
fi
2025-11-23 08:38:05 -05:00
fi
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]]
if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}"
DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}"
DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}"
DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}"
DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}"
DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}"
DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}"
DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}"
DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}"
fi
2025-11-23 08:38:05 -05:00
elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then
2026-05-26 17:35:40 -04:00
DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME"
DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME"
DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}"
if [ -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}"
fi
if [ ! -d "$DATABASE_DIR" ]; then
mkdir -p "$DATABASE_DIR"
fi
chmod 777 "$DATABASE_DIR"
fi
if [ -n "$DATABASE_ADMIN_WWW_ROOT" ]; then
if [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ]; then
mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"
fi
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Allow variables via imports - Overwrite existing
2026-05-26 17:35:40 -04:00
if [ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then
. "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# set password to random if variable is random
2026-05-26 17:35:40 -04:00
if [ "$user_pass" = "random" ]; then
user_pass="$(__random_password ${RANDOM_PASS_USER:-16})"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
if [ "$root_user_pass" = "random" ]; then
root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Allow setting initial users and passwords via environment and save to file
2026-05-26 17:35:40 -04:00
if [ -n "$user_name" ]; then
echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name"
fi
if [ -n "$user_pass" ]; then
echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass"
fi
if [ -n "$root_user_name" ]; then
echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name"
fi
if [ -n "$root_user_pass" ]; then
echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Allow per init script usernames and passwords
2026-05-26 17:35:40 -04:00
if __file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name"; then
user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")"
fi
if __file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass"; then
user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")"
fi
if __file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name"; then
root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")"
fi
if __file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass"; then
root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")"
fi
if __file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user"; then
DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")"
fi
if __file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root"; then
DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# set hostname for script
sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
__create_service_env
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Setup /config directories
__init_config_etc
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# pre-run function
__execute_prerun
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# create user if needed
__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Modify user if needed
__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-}
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Create base directories
__setup_directories
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# set switch user command
__switch_to_user
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Initialize the home/working dir
__init_working_dir
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# show init message
__pre_message
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
#
__initialize_db_users
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Initialize ssl
__update_ssl_conf
__update_ssl_certs
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX}
__run_secure_function
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
__run_precopy
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Copy /config to /etc
for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do
2026-05-26 17:35:40 -04:00
__initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
2025-11-23 08:38:05 -05:00
done
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Replace variables
__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
#
__initialize_database
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Updating config files
__update_conf_files
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# run the pre execute commands
__pre_execute
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# Set permissions
__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP"
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
#
__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log"
2026-05-26 17:35:40 -04:00
errorCode=${PIPESTATUS[0]}
2025-11-23 08:38:05 -05:00
if [ -n "$EXEC_CMD_BIN" ]; then
2026-05-26 17:35:40 -04:00
if [ "$errorCode" -eq 0 ]; then
SERVICE_EXIT_CODE=0
SERVICE_IS_RUNNING="yes"
else
SERVICE_EXIT_CODE=$errorCode
SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}"
if [ ! -s "$SERVICE_PID_FILE" ]; then
rm -Rf "$SERVICE_PID_FILE"
fi
fi
2025-11-23 08:38:05 -05:00
fi
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
# start the post execute function in background
__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" &
2026-05-26 17:35:40 -04:00
# - - - - - - - - - - - - - - - - - - - - - - - - -
2025-11-23 08:38:05 -05:00
__script_exit $SERVICE_EXIT_CODE