diff --git a/README.md b/README.md index 4142b7a..1ac8016 100644 --- a/README.md +++ b/README.md @@ -12,39 +12,47 @@ you can opt in per build. ## ๐Ÿ“ฆ Pull ```shell -docker pull casjaysdevdocker/go:latest +docker pull casjaysdev/go:latest ``` --- ## ๐Ÿณ Docker -### Quick one-shot commands +### Default workflow โ€” no args needed + +Mount your project at `/app` and run with no arguments. The container will +automatically run the full Go workflow: + +``` +go mod tidy โ†’ gofmt -w . โ†’ go vet ./... โ†’ go test ./... โ†’ go build ./... +``` ```shell -# build a project (mount source at /app) -docker run --rm -it \ - -v "$PWD:/app" -w /app \ - casjaysdevdocker/go:latest \ - go build ./... +docker run --rm -v "$PWD:/app" casjaysdev/go:latest +``` -# run tests -docker run --rm -it \ - -v "$PWD:/app" -w /app \ - casjaysdevdocker/go:latest \ - gotestsum ./... +### One-shot commands -# lint -docker run --rm -it \ - -v "$PWD:/app" -w /app \ - casjaysdevdocker/go:latest \ - golangci-lint run +Pass any command and it runs directly instead of the default workflow: + +```shell +# run tests only +docker run --rm -v "$PWD:/app" casjaysdev/go:latest go test -v ./... + +# lint (add --timeout for cold caches) +docker run --rm -v "$PWD:/app" casjaysdev/go:latest golangci-lint run --timeout=5m ./... + +# cross-compile for arm64 +docker run --rm -v "$PWD:/app" \ + -e GOOS=linux -e GOARCH=arm64 \ + casjaysdev/go:latest go build -o app-arm64 ./... # interactive shell -docker run --rm -it \ - -v "$PWD:/app" -w /app \ - casjaysdevdocker/go:latest \ - bash -l +docker run --rm -it -v "$PWD:/app" casjaysdev/go:latest bash + +# sh -c for compound commands +docker run --rm -v "$PWD:/app" casjaysdev/go:latest sh -c 'go vet ./... && staticcheck ./...' ``` ### Long-running container @@ -52,18 +60,19 @@ docker run --rm -it \ ```shell docker run -d \ --restart always \ - --name casjaysdevdocker-go \ + --name casjaysdev-go \ --hostname go \ -e TZ=${TIMEZONE:-America/New_York} \ -v go-state:/usr/local/share/go \ - -v "$PWD:/app" -w /app \ - casjaysdevdocker/go:latest + -v "$PWD:/app" \ + casjaysdev/go:latest \ + tail null # exec into it -docker exec -it casjaysdevdocker-go bash -l -docker exec casjaysdevdocker-go go test ./... -docker exec casjaysdevdocker-go golangci-lint run -docker exec casjaysdevdocker-go goreleaser release --snapshot --clean +docker exec -it casjaysdev-go bash +docker exec casjaysdev-go go test ./... +docker exec casjaysdev-go golangci-lint run --timeout=5m +docker exec casjaysdev-go goreleaser release --snapshot --clean ``` ### docker-compose @@ -71,8 +80,8 @@ docker exec casjaysdevdocker-go goreleaser release --snapshot --clean ```yaml services: go: - image: casjaysdevdocker/go:latest - container_name: casjaysdevdocker-go + image: casjaysdev/go:latest + container_name: casjaysdev-go hostname: go environment: - TZ=America/New_York @@ -181,7 +190,7 @@ Opt into CGO per build without changing the image: ```shell docker run --rm -v "$PWD:/app" -w /app \ -e CGO_ENABLED=1 \ - casjaysdevdocker/go:latest \ + casjaysdev/go:latest \ go build ./... ``` @@ -252,26 +261,26 @@ pre-installed to orchestrate multi-platform release builds. ### Build the image locally ```shell -git clone https://github.com/casjaysdevdocker/go "$HOME/Projects/github/casjaysdevdocker/go" -cd "$HOME/Projects/github/casjaysdevdocker/go" -docker build --tag casjaysdevdocker/go:test . +git clone https://github.com/casjaysdev/go "$HOME/Projects/github/casjaysdev/go" +cd "$HOME/Projects/github/casjaysdev/go" +docker build --tag casjaysdev/go:test . ``` ### Get source files ```shell -git clone "https://github.com/casjaysdevdocker/go" \ - "$HOME/Projects/github/casjaysdevdocker/go" +git clone "https://github.com/casjaysdev/go" \ + "$HOME/Projects/github/casjaysdev/go" ``` --- ## ๐Ÿ“„ License -MIT โ€” see [LICENSE.md](LICENSE.md) +MIT --- -๐Ÿค– [casjay](https://github.com/casjay) ยท -โ›ต [casjaysdevdocker](https://github.com/casjaysdevdocker) ยท -๐Ÿณ [Docker Hub](https://hub.docker.com/u/casjaysdevdocker) +๐Ÿค– [casjay](https://github.com/casjay) +โ›ต [casjaysdev](https://github.com/casjaysdev) +๐Ÿณ [Docker Hub](https://hub.docker.com/u/casjaysdev) diff --git a/rootfs/usr/local/bin/entrypoint.sh b/rootfs/usr/local/bin/entrypoint.sh index 2da550d..7dcce31 100755 --- a/rootfs/usr/local/bin/entrypoint.sh +++ b/rootfs/usr/local/bin/entrypoint.sh @@ -506,9 +506,9 @@ if [ "$START_SERVICES" = "yes" ] || [ -z "$1" ]; then echo "$$" >"$ENTRYPOINT_PID_FILE" __start_init_scripts "/usr/local/etc/docker/init.d" CONTAINER_INIT="${CONTAINER_INIT:-no}" - # Only block in monitoring mode when no user command was given + # No user command: run default Go workflow instead of blocking if [ $# -eq 0 ]; then - __no_exit + __exec_command go-workflow exit $? fi fi @@ -643,8 +643,13 @@ procs) ;; # Launch shell */bin/sh | */bin/bash | bash | sh | shell) + shell_bin="$(type -P "${1}" 2>/dev/null || echo "/bin/bash")" shift 1 - __exec_command "${@:-/bin/bash -l}" + if [ $# -gt 0 ]; then + __exec_command "$shell_bin" "$@" + else + __exec_command "$shell_bin" -l + fi exit $? ;; # execute commands @@ -676,11 +681,8 @@ start) # Execute primary command *) if [ $# -eq 0 ]; then - if [ ! -f "$ENTRYPOINT_PID_FILE" ]; then - echo "$$" >"$ENTRYPOINT_PID_FILE" - [ "$START_SERVICES" = "no" ] && [ "$CONTAINER_INIT" = "yes" ] || __start_init_scripts "/usr/local/etc/docker/init.d" - fi - __no_exit + # No args: run the default Go workflow (tidy โ†’ fmt โ†’ vet โ†’ test โ†’ build) + __exec_command go-workflow else __exec_command "$@" fi diff --git a/rootfs/usr/local/bin/go-workflow b/rootfs/usr/local/bin/go-workflow new file mode 100755 index 0000000..4068ece --- /dev/null +++ b/rootfs/usr/local/bin/go-workflow @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# Default Go workflow: tidy โ†’ fmt โ†’ vet โ†’ test โ†’ build +# Runs automatically when `docker run casjaysdev/go` is called with no args. +# Working directory is expected to be a Go module root (go.mod must exist). +set -euo pipefail + +# Resolve the working directory โ€” prefer /app if mounted, else cwd +WORK_DIR="${GOWORKDIR:-${PWD}}" +cd "$WORK_DIR" + +# Require a go.mod so we fail fast with a clear message instead of cryptic go errors +if [ ! -f "go.mod" ]; then + echo "Error: no go.mod found in ${WORK_DIR}" >&2 + echo "Mount your project with: docker run --rm -v \"\$(pwd)\":/app casjaysdev/go" >&2 + exit 1 +fi + +MODULE="$(awk '/^module /{print $2}' go.mod)" +echo "" +echo "โ–ถ Go workflow: ${MODULE}" +echo " Working dir: ${WORK_DIR}" +echo "" + +run_step() { + local label="$1"; shift + echo "โ”€โ”€ ${label}" + "$@" + echo "" +} + +# 1. Sync module graph and go.sum before anything reads them +run_step "go mod tidy" go mod tidy + +# 2. Format all Go source files in place +run_step "gofmt -w ." gofmt -w . + +# 3. Catch suspicious constructs +run_step "go vet ./..." go vet ./... + +# 4. Run tests โ€” fail fast before wasting time on a build +run_step "go test ./..." go test ./... + +# 5. Build all main packages; output lands alongside source in each package dir +run_step "go build ./..." go build ./... + +echo "โœ… Done." diff --git a/rootfs/usr/local/etc/docker/init.d/00-go.sh b/rootfs/usr/local/etc/docker/init.d/00-go.sh index 5e8d563..b3c36ef 100755 --- a/rootfs/usr/local/etc/docker/init.d/00-go.sh +++ b/rootfs/usr/local/etc/docker/init.d/00-go.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # shellcheck shell=bash # - - - - - - - - - - - - - - - - - - - - - - - - - -##@Version : 202605260122-git +##@Version : 202605292219-git # @@Author : Jason Hempstead # @@Contact : jason@casjaysdev.pro # @@License : WTFPL @@ -9,976 +9,9 @@ # @@Copyright : Copyright: (c) 2026 Jason Hempstead, Casjays Developments # @@Created : Friday, May 29, 2026 22:22 EDT # @@File : 00-go.sh -# @@Description : -# @@Changelog : New script -# @@TODO : Better documentation -# @@Other : -# @@Resource : -# @@Terminal App : no -# @@sudo/root : no -# @@Template : other/start-service +# @@Description : Go toolchain โ€” configuration-only init (no daemon) # - - - - - - - - - - - - - - - - - - - - - - - - - -# 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="go" -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 "$GO_APPNAME_ENABLED" ]; then - if [ "$GO_APPNAME_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="/go/bin:/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="no" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Set webroot -WWW_ROOT_DIR="/usr/local/share/httpd/default" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Default predefined variables -# set data directory -# Empty to avoid clobbering the /data/go -> /usr/local/share/go symlink -# created in __run_precopy. This image is a build env, not a service -# with a per-instance data dir. -DATA_DIR="" -# set config directory -CONF_DIR="/config/go" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# set the containers etc directory -ETC_DIR="/etc/go" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# set the var dir -VAR_DIR="" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# set the temp dir -TMP_DIR="/tmp/go" -# set scripts pid dir -RUN_DIR="/run/go" -# set log directory -LOG_DIR="/data/logs/go" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# 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="go" -# Set the service group -#SERVICE_GROUP="go" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# 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 -# Go is a CLI, not a daemon. Leave EXEC_CMD_BIN empty so the init pipeline -# finishes after __post_execute and the container idles via tini+entrypoint. -EXEC_CMD_BIN='' -# command arguments -EXEC_CMD_ARGS='' -# 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 -# 0 because this is a build environment, not a service - the container -# idles after init and there's no daemon to wait for. -POST_EXECUTE_WAIT_TIME="0" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Update path var -PATH="$PATH:." -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Lets get containers ip address -IP4_ADDRESS="$(__get_ip4)" -IP6_ADDRESS="$(__get_ip6)" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# 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="${GO_ROOT_USER_NAME:-}" -# root user password -root_user_pass="${GO_ROOT_PASS_WORD:-}" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Normal user info [password/random] -# normal user name -user_name="${GO_USER_NAME:-}" -# normal user password -user_pass="${GO_USER_PASS_WORD:-}" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Load variables from config -# Generated by my dockermgr script -if [ -f "/config/env/go.script.sh" ]; then - . "/config/env/go.script.sh" -fi -# Overwrite the variables -if [ -f "/config/env/go.sh" ]; then - . "/config/env/go.sh" -fi -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Additional predefined variables - -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Additional variables - -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Specifiy custom directories to be created -ADD_APPLICATION_FILES="" -ADD_APPLICATION_DIRS="/data/build /app /work /root/app /root/project /usr/local/share/go /usr/local/share/go/bin /usr/local/share/go/cache /usr/local/share/go/pkg/mod" -# - - - - - - - - - - - - - - - - - - - - - - - - - -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 - -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Custom commands to run before copying to /config -__run_precopy() { - # Define environment - local hostname=${HOSTNAME} - if [ ! -d "/run/healthcheck" ]; then - mkdir -p "/run/healthcheck" - fi - # Point /data/go at the canonical persistent Go state dir. Done at - # runtime because /data is a volume mount and only exists once the - # container starts. Skip if /data/go is already a real, populated dir - # (legacy upgrade path - leave the user's data alone). - mkdir -p /usr/local/share/go - if [ ! -e /data/go ] || [ -L /data/go ]; then - mkdir -p /data - ln -sfn /usr/local/share/go /data/go - fi - # Define actions/commands - - # 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 - - # 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() { - # default exit code - local exitCode=0 - # set hostname - local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" - # - - - - - - - - - - - - - - - - - - - - - - - - - - # delete files - #__rm "" - - # - - - - - - - - - - - - - - - - - - - - - - - - - - # custom commands - - # - - - - - - - - - - - - - - - - - - - - - - - - - - # replace variables - # __replace "" "" "$CONF_DIR/go.conf" - # replace variables recursively - # __find_replace "" "" "$CONF_DIR" - - # - - - - - - - - - - - - - - - - - - - - - - - - - - # define actions - - # 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() { - # init pid var - local pid="" - # set default exit code - local retVal=0 - # how long to wait before executing - local ctime=${POST_EXECUTE_WAIT_TIME:-1} - # convert minutes to seconds - local waitTime=$((ctime * 60)) - # message to show at start - local postMessageST="Running post commands for $SERVICE_NAME" - # message to show at completion - local postMessageEnd="Finished post commands for $SERVICE_NAME" - # wait - sleep $waitTime - # execute commands after waiting - ( - # show message - __banner "$postMessageST" - # commands to execute - sleep 5 - # show exit message - __banner "$postMessageEnd: Status $retVal" - ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & - pid=$! - if ps ax | awk -v pid="$execPid" '$1 == pid {found=1} END {exit !found}'; then - retVal=0 - else - retVal=10 - fi - # 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 </dev/null -# - - - - - - - - - - - - - - - - - - - - - - - - - -# root/admin user info [password/random] -#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$GO_ROOT_USER_NAME}" # root user name -#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$GO_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:-$GO_USER_NAME}" # -#ENV_USER_PASS="${ENV_USER_PASS:-$GO_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='' - [ -n "$su_exec" ] && _q_su=$(printf '%q ' $su_exec) - _q_cmd=$(printf '%q' "$cmd") - _q_args='' - [ -n "$args" ] && _q_args=$(printf '%q ' $args) - _q_extra='' - [ -n "$extra_env" ] && _q_extra=$(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='' - [ -n "$su_exec" ] && _q_su=$(printf '%q ' $su_exec) - _q_cmd=$(printf '%q' "$cmd") - _q_args='' - [ -n "$args" ] && _q_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 - SERVICE_EXIT_CODE=0 -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 +# Tell the init framework this is a configuration service, not a daemon. +# This prevents __start_init_scripts from waiting for a PID or keep-alive loop. +export CONTAINER_INIT="yes" +export SERVICE_USES_PID="no"