Files
tor/rootfs/usr/local/etc/docker/init.d/01-tor-server.sh
T
jason f4df3572d5 🐛 Fix printf %q empty-var bug; sync Dockerfile; update README 🐛
Three fixes in this commit:
1. printf '%q' empty-variable bug — all 7 init.d service scripts:
printf '%q ' $su_exec/\$args/\$extra_env with an unset/empty variable
calls printf with no vararg, causing bash to format the empty string
as '' (two single-quotes), which gets written into the generated exec
script and makes the container fail to start. Fixed with ${var:+...}
parameter expansion so an empty variable produces an empty string.
2. Dockerfile — sync to template 202605261603 (structural changes:
blank line after $SHELL_OPTS in apk-repos block, un-indented echo ""
in Custom Settings and Custom Applications stubs); preserve all
tor-specific values (IMAGE_NAME, PHP_SERVER, BUILD_DATE, SERVICE_PORT,
EXPOSE_PORTS, PHP_VERSION, IMAGE_REPO, CONTAINER_VERSION, PULL_URL,
PACK_LIST, HOSTNAME, OCI labels).
3. README.md — add the full EXPOSE_PORTS list to the docker run command
and docker-compose ports section (privoxy 8118, SOCKS5 9050, DNS 9053
TCP+UDP, web 9080, bridge range 57000-57007).
- Dockerfile: sync structural template changes; update BUILD_DATE to 202605261603
- README.md: add -p 8118:8118 9050:9050 9053:9053 9053/udp 9080:9080 57000-57007 ports
- rootfs/usr/local/etc/docker/init.d/01-tor-server.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/02-tor-bridge.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/03-tor-relay.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/04-tor-exit.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/09-unbound.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/98-privoxy.sh: fix _q_su/_q_args/_q_extra printf %q guard
- rootfs/usr/local/etc/docker/init.d/zz-nginx.sh: fix _q_su/_q_args/_q_extra printf %q guard

Dockerfile
README.md
rootfs/usr/local/etc/docker/init.d/01-tor-server.sh
rootfs/usr/local/etc/docker/init.d/02-tor-bridge.sh
rootfs/usr/local/etc/docker/init.d/03-tor-relay.sh
rootfs/usr/local/etc/docker/init.d/04-tor-exit.sh
rootfs/usr/local/etc/docker/init.d/09-unbound.sh
rootfs/usr/local/etc/docker/init.d/98-privoxy.sh
rootfs/usr/local/etc/docker/init.d/zz-nginx.sh
2026-05-26 18:25:35 -04:00

1091 lines
41 KiB
Bash
Executable File

#!/usr/bin/env bash
# shellcheck shell=bash
# - - - - - - - - - - - - - - - - - - - - - - - - -
##@Version : 202501060902-git
# @@Author : Jason Hempstead
# @@Contact : jason@casjaysdev.pro
# @@License : WTFPL
# @@ReadME : tor.sh --help
# @@Copyright : Copyright: (c) 2026 Jason Hempstead, Casjays Developments
# @@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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329
# - - - - - - - - - - - - - - - - - - - - - - - - -
set -e
# - - - - - - - - - - - - - - - - - - - - - - - - -
# run trap command on exit
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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
SCRIPT_FILE="$0"
SERVICE_NAME="tor-server"
SCRIPT_NAME="${SCRIPT_FILE##*/}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Function to exit appropriately based on context
__script_exit() {
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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Exit if service is disabled
if [ -n "$TOR_SERVER_ENABLED" ]; then
if [ "$TOR_SERVER_ENABLED" != "yes" ]; then
export SERVICE_DISABLED="$SERVICE_NAME"
__script_exit 0
fi
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# 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:-}"
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
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
. "/usr/local/etc/docker/functions/entrypoint.sh"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# import variables
for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do
if [ -f "$set_env" ]; then
. "$set_env"
fi
done
# - - - - - - - - - - - - - - - - - - - - - - - - -
# exit if __start_init_scripts function hasn't been Initialized
if [ ! -f "/run/.start_init_scripts.pid" ]; then
echo "__start_init_scripts function hasn't been Initialized" >&2
SERVICE_IS_RUNNING="no"
__script_exit 1
fi
# Clean up any stale PID file for this service on startup
if [ -n "$SERVICE_NAME" ] && [ -f "/run/init.d/$SERVICE_NAME.pid" ]; then
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
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Custom functions
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Script to execute
START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Reset environment before executing service
RESET_ENV="yes"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set webroot
WWW_ROOT_DIR="/usr/local/share/httpd/default"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Default predefined variables
# set data directory
DATA_DIR="/data/tor/server"
# set config directory
CONF_DIR="/config/tor/server"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set the containers etc directory
ETC_DIR="/etc/tor/server"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set the var dir
VAR_DIR=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set the temp dir
TMP_DIR="/tmp/tor/server"
# set scripts pid dir
RUN_DIR="/run/tor/server"
# set log directory
LOG_DIR="/data/logs/tor"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set the working dir
WORK_DIR=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# port which service is listening on
SERVICE_PORT=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# User to use to launch service - IE: postgres
# normally root
RUNAS_USER="root"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# User and group in which the service switches to - IE: nginx,apache,mysql,postgres
# execute command as another user
SERVICE_USER="root"
# Set the service group
SERVICE_GROUP="root"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set password length
RANDOM_PASS_USER=""
RANDOM_PASS_ROOT=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set user and group ID
# set the user id
SERVICE_UID="0"
# set the group id
SERVICE_GID="0"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# execute command variables - keep single quotes variables will be expanded later
# command to execute
EXEC_CMD_BIN='tor-server'
# command arguments
EXEC_CMD_ARGS='-f $CONF_DIR/server.conf'
# execute script before
EXEC_PRE_SCRIPT=''
# Set to 'no' for configuration services (no daemon process), leave blank for actual services
SERVICE_USES_PID=''
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Is this service a web server
IS_WEB_SERVER="no"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Is this service a database server
IS_DATABASE_SERVICE="no"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Does this service use a database server
USES_DATABASE_SERVICE="no"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase]
DATABASE_SERVICE_TYPE="sqlite"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Show message before execute
PRE_EXEC_MESSAGE=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set the wait time to execute __post_execute function - minutes
POST_EXECUTE_WAIT_TIME="5"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Update path var
PATH="$PATH:."
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Where to save passwords to
# 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"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# root/admin user info password/random]
# root user name
root_user_name="${TOR_ROOT_USER_NAME:-}"
# root user password
root_user_pass="${TOR_ROOT_PASS_WORD:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Normal user info [password/random]
# normal user name
user_name="${TOR_USER_NAME:-}"
# normal user password
user_pass="${TOR_USER_PASS_WORD:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Load variables from config
# 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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Additional predefined variables
TOR_HIDDEN_SERVICE_DIR="${TOR_HIDDEN_SERVICE_DIR:-$DATA_DIR/hidden}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Additional variables
TOR_HIDDEN_SERVERS="${TOR_HIDDEN_SERVERS//,/ }"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Specifiy custom directories to be created
ADD_APPLICATION_FILES=""
ADD_APPLICATION_DIRS=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log"
APPLICATION_DIRS="$ETC_DIR $CONF_DIR $DATA_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Additional config dirs - will be Copied to /etc/$name
ADDITIONAL_CONFIG_DIRS=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\"
CMD_ENV=""
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Overwrite based on file/directory
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Per Application Variables or imports
TOR_DNS_ENABLED="${TOR_DNS_ENABLED:-yes}"
TOR_HIDDEN_IP="${TOR_HIDDEN_IP:-127.0.0.1}"
TOR_SERVER_ENABLED="${TOR_SERVER_ENABLED:-yes}"
TOR_RELAY_ENABLED="${TOR_RELAY_ENABLED:-yes}"
TOR_BRIDGE_ENABLED="${TOR_BRIDGE_ENABLED:-yes}"
TOR_HIDDEN_ENABLED="${TOR_HIDDEN_ENABLED:-yes}"
TOR_SERVER_NICK_NAME="${TOR_SERVER_NICK_NAME:-}"
TOR_SERVER_ADMIN="${TOR_SERVER_ADMIN:-}"
TOR_SERVER_TOTAL_BANDWIDTH="${TOR_SERVER_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')"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# 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-server" 2>/dev/null)"
if [ ! -d "/run/healthcheck" ]; then
mkdir -p "/run/healthcheck"
fi
# Define actions/commands
[ -d "$DATA_DIR" ] || mkdir -p "$DATA_DIR"
[ -n "$tor_bin" ] && [ -z "$server_bin" ] && cp -Rf "$tor_bin" "/usr/local/bin/tor-server"
chmod +x "/usr/local/bin/tor-server"
# allow custom functions
if builtin type -t __run_precopy_local | grep -q 'function'; then
__run_precopy_local
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Custom prerun functions - IE setup WWW_ROOT_DIR
__execute_prerun() {
# Define environment
local hostname=${HOSTNAME}
# Define actions/commands
touch "/tmp/init_tor_services"
# allow custom functions
if builtin type -t __execute_prerun_local | grep -q 'function'; then
__execute_prerun_local
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Run any pre-execution checks
__run_pre_execute_checks() {
# 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"
# 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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# use this function to update config files - IE: change port
__update_conf_files() {
local exitCode=0
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# delete files
__rm "$CONF_DIR/server.conf"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# custom commands
chmod 600 $RUN_DIR
mkdir -p "/run/tor/sites" && chmod 777 "/run/tor/sites"
chown -Rf ${SERVICE_USER:-$RUNAS_USER}:${SERVICE_GROUP:-$RUNAS_USER} $RUN_DIR
[ -d "$TOR_HIDDEN_SERVICE_DIR" ] || { mkdir -p "$TOR_HIDDEN_SERVICE_DIR" && chmod -f 700 "$TOR_HIDDEN_SERVICE_DIR" 2>/dev/null; }
# - - - - - - - - - - - - - - - - - - - - - - - - -
# replace variables
# - - - - - - - - - - - - - - - - - - - - - - - - -
cat <<EOF >>"$CONF_DIR/server.conf"
##### Server
RunAsDaemon 0
HardwareAccel 1
AddressDisableIPv6 0
#VirtualAddrNetwork 10.0.0.0/12
#### control settings
ControlPort 127.0.0.1:9051
ControlSocketsGroupWritable 1
CookieAuthentication 1
CookieAuthFileGroupReadable 1
HashedControlPassword 16:C30604D1D90F341360A14D9A1048C1DF4A3CA2411444E52EE5B954C01F
##### bandwidth and accounting
Nickname ${TOR_SERVER_NICK_NAME:-$RANDOM_NICK}
ContactInfo ${TOR_SERVER_ADMIN:-tor-admin@$HOSTNAME}
AccountingMax 250 GBytes
RelayBandwidthRate 96 KB
RelayBandwidthBurst 192 KB
AccountingStart month 1 00:00
##### directiories and files
DataDirectory $DATA_DIR
ControlSocket $RUN_DIR/server.sock
CookieAuthFile $RUN_DIR/server.authcookie
##### socks option
SOCKSPort 0.0.0.0:9050
SafeSocks ${TOR_SOCKS_SAFE:-0}
SocksTimeout ${TOR_SOCKS_TIMEOUT:-10}
##### logging
LogMessageDomains 1
Log warn file $LOG_DIR/warn.log
Log notice file $LOG_DIR/notice.log
#Log debug file $LOG_DIR/debug.log
##### port mappings
TransPort 0.0.0.0:9040
HTTPTunnelPort 0.0.0.0:9080
##### security
SafeLogging 1
UseEntryGuards 1
NumEntryGuards 3
DisableAllSwap 1
##### exit relay
ExitRelay 0
ExitPolicy reject *:*
ExcludeNodes {ru},{cn},{ir},{kp},{sy}
EOF
# define actions
if [ "$TOR_DNS_ENABLED" = "yes" ]; then
SHOW_HIDDEN_HOSTNAMES=yes
mkdir -p "$CONF_DIR/conf.d"
cat <<EOF >>"$CONF_DIR/server.conf"
#### dns forwarder
Log notice file $LOG_DIR/tor-dns.log
DNSPort 0.0.0.0:8053
DNSListenAddress 0.0.0.0,[::]
AutomapHostsOnResolve 1
AutomapHostsSuffixes .exit,.onion
EOF
fi
if [ "$TOR_HIDDEN_ENABLED" = "yes" ]; then
mkdir -p "$CONF_DIR/hidden.d"
mkdir -p "$TOR_HIDDEN_SERVICE_DIR/default"
chmod -f 700 "$TOR_HIDDEN_SERVICE_DIR/default"
if ! grep -shq "" ""; then
cat <<EOF >>"$CONF_DIR/server.conf"
%include $CONF_DIR/hidden.d/*.conf
EOF
fi
for HiddenService in $CONF_DIR/hidden.d/*.conf; do
HiddenServiceDir="$(grep -si '^HiddenServiceDir ' "$HiddenService" | awk '{print $2}' 2>/dev/null)"
if [ -n "$HiddenServiceDir" ]; then
mkdir -p "$HiddenServiceDir" 2>/dev/null
chmod 700 "$HiddenServiceDir" 2>/dev/null
fi
done
cat <<EOF >"$CONF_DIR/hidden.d/default.conf"
#### hidden services
HiddenServiceDir $TOR_HIDDEN_SERVICE_DIR/default
HiddenServicePort ${TOR_HIDDEN_SERVICE_PORT:-80 $TOR_HIDDEN_IP:80}
EOF
fi
cat <<EOF >>"$CONF_DIR/server.conf"
##### include configurations
%include $CONF_DIR/conf.d/*.conf
EOF
if [ "$TOR_DEBUG" = "yes" ]; then
sed -i 's|#Log debug|Log debug|g' "$CONF_DIR/server.conf"
fi
if [ -z "$HAS_IPV6" ]; then
sed -i 's|AddressDisableIPv6 0|AddressDisableIPv6 1|g' "$CONF_DIR/server.conf"
fi
# allow custom functions
if builtin type -t __update_conf_files_local | grep -q 'function'; then
__update_conf_files_local
fi
# exit function
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# function to run before executing
__pre_execute() {
# default exit code
local exitCode=0
# set hostname
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# 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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# function to run after executing
__post_execute() {
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"
# wait
sleep $waitTime
# execute commands after waiting
(
# commands to execute
while :; do
if __pgrep unbound >/dev/null 2>&1; then
get_hidden_service_hostnames=$(find "$TOR_HIDDEN_SERVICE_DIR" -iname 'hostname' 2>/dev/null | wc -l || echo "0")
break
else
sleep 10
fi
done
# show message
__banner "$postMessageST"
if [ -d "/data/htdocs/www" ]; then
WWW_ROOT_DIR="/data/htdocs/www"
fi
if [ -d "$TOR_HIDDEN_SERVICE_DIR" ] && [ "$get_hidden_service_hostnames" -gt 0 ]; then
echo "Begin current hidden services"
[ -f "$WWW_ROOT_DIR/hostnames.html" ] && rm -f "$WWW_ROOT_DIR/hostnames.html"
for host in "$TOR_HIDDEN_SERVICE_DIR"/*/hostname; do
d="$(dirname -- $host)"
name="$(basename "$d")"
url="$(<"$host")"
site="$(echo "$url" | sed 's|\.onion$||g')"
echo "$name: $url"
touch "/run/tor/sites/$site"
echo '<a href="http://'$url'">'$name'</a><br />' >>"$WWW_ROOT_DIR/hostnames.html"
if [ "$name" = "default" ]; then echo "$site" >"$WWW_ROOT_DIR/defaultOnion.txt"; fi
done
echo "End current hidden services"
fi
[ -f "/tmp/init_tor_services" ] && rm -Rf "/tmp/init_tor_services"
(while :; do sleep 10 && __pgrep $EXEC_CMD_BIN >/dev/null || eval $EXEC_CMD_BIN $EXEC_CMD_ARGS >/dev/null; done &)
# show exit message
__banner "$postMessageEnd: Status $retVal"
) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" &
# fire-and-forget: backgrounded subshell always succeeds at launch
retVal=0
# allow custom functions
if builtin type -t __post_execute_local | grep -q 'function'; then
__post_execute_local
fi
# exit function
return $retVal
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# use this function to update config files - IE: change port
__pre_message() {
local exitCode=0
if [ -n "$PRE_EXEC_MESSAGE" ]; then
eval echo "$PRE_EXEC_MESSAGE"
fi
# execute commands
# allow custom functions
if builtin type -t __pre_message_local | grep -q 'function'; then
__pre_message_local
fi
# exit function
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# use this function to setup ssl support
__update_ssl_conf() {
local exitCode=0
local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# execute commands
# allow custom functions
if builtin type -t __update_ssl_conf_local | grep -q 'function'; then
__update_ssl_conf_local
fi
# set exitCode
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
__create_service_env() {
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# 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}" #
# - - - - - - - - - - - - - - - - - - - - - - - - -
#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
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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# script to start server
__run_start_script() {
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)}
_q_cmd=$(printf '%q' "$cmd")
_q_args=${args:+$(printf '%q ' $args)}
_q_extra=${extra_env:+$(printf '%q ' $extra_env)}
{
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)}
_q_cmd=$(printf '%q' "$cmd")
_q_args=${args:+$(printf '%q ' $args)}
{
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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# username and password actions
__run_secure_function() {
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
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Allow ENV_ variable - Import env file
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
# application specific
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# ensure needed directories exists
if [ ! -d "$LOG_DIR" ]; then
mkdir -p "$LOG_DIR"
fi
if [ ! -d "$RUN_DIR" ]; then
mkdir -p "$RUN_DIR"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# create auth directories
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Database env
if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then
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
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]]
if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then
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
elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then
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
elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then
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
elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then
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
elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then
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
elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then
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
elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then
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
elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then
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
elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Allow variables via imports - Overwrite existing
if [ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then
. "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set password to random if variable is random
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Allow setting initial users and passwords via environment and save to file
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Allow per init script usernames and passwords
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
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set hostname for script
sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
__create_service_env
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Setup /config directories
__init_config_etc
# - - - - - - - - - - - - - - - - - - - - - - - - -
# pre-run function
__execute_prerun
# - - - - - - - - - - - - - - - - - - - - - - - - -
# create user if needed
__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Modify user if needed
__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Create base directories
__setup_directories
# - - - - - - - - - - - - - - - - - - - - - - - - -
# set switch user command
__switch_to_user
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Initialize the home/working dir
__init_working_dir
# - - - - - - - - - - - - - - - - - - - - - - - - -
# show init message
__pre_message
# - - - - - - - - - - - - - - - - - - - - - - - - -
#
__initialize_db_users
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Initialize ssl
__update_ssl_conf
__update_ssl_certs
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX}
__run_secure_function
# - - - - - - - - - - - - - - - - - - - - - - - - -
__run_precopy
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Copy /config to /etc
for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do
__initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt"
done
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Replace variables
__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR"
# - - - - - - - - - - - - - - - - - - - - - - - - -
#
__initialize_database
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Updating config files
__update_conf_files
# - - - - - - - - - - - - - - - - - - - - - - - - -
# run the pre execute commands
__pre_execute
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Set permissions
__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP"
# - - - - - - - - - - - - - - - - - - - - - - - - -
#
__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20
# - - - - - - - - - - - - - - - - - - - - - - - - -
__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log"
errorCode=${PIPESTATUS[0]}
if [ -n "$EXEC_CMD_BIN" ]; then
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
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# start the post execute function in background
__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" &
# - - - - - - - - - - - - - - - - - - - - - - - - -
__script_exit $SERVICE_EXIT_CODE