Files
SillyTavern/docker/docker-entrypoint.sh
T
Cohee e2d8c0200f Use custom init script instead of postinstall (#5384)
* Use custom init script instead of postinstall

* Revert changes to start scripts in src\electron

* feat: add --ignore-scripts flag to npm install commands in batch and shell scripts

* feat: add --ignore-scripts flag to npm ci in Dockerfile
2026-04-01 23:34:00 +03:00

100 lines
3.4 KiB
Bash

#!/bin/sh
# Function to handle startup logic (Config check + init + Start)
start_sillytavern() {
local PREFIX="$1"
shift # Remove the first argument (PREFIX) so $@ contains the rest
# Config Check
if [ ! -e "config/config.yaml" ]; then
echo "Resource not found, copying from defaults: config.yaml"
$PREFIX cp "default/config.yaml" "config/config.yaml"
fi
# Execute init script to auto-populate config.yaml with missing values
$PREFIX npm run init
# Start the server
exec $PREFIX node server.js --listen "$@"
}
# Dirs that MUST be present at this point (e.g for volumeless docker runs).
# Please update list, if in the future a related perm issue appear.
CORE_DIRS="config data plugins public/scripts/extensions/third-party backups"
# Mounted Volumes (External)
# Parse mounts, handling files vs directories
RAW_MOUNTS=$(awk -v app_path="/home/node/app" '$2 ~ "^" app_path {print $2}' /proc/mounts)
MOUNTED_DIRS=""
for mount in $RAW_MOUNTS; do
if [ -f "$mount" ]; then
# If it is a mounted file (e.g. cert.pem), we want to check its PARENT directory
# so that the app can write adjacent files (e.g. key.pem).
PARENT_DIR=$(dirname "$mount")
# Performance Safety: If the file is in the root of the app,
# we do NOT add the parent (App Root), or we will recursively scan the whole app.
[ "$PARENT_DIR" != "/home/node/app" ] && MOUNTED_DIRS="$MOUNTED_DIRS $PARENT_DIR" || MOUNTED_DIRS="$MOUNTED_DIRS $mount"
else
# It is a directory, add it directly
MOUNTED_DIRS="$MOUNTED_DIRS $mount"
fi
done
# Combine dirs for checks
CHECK_DIRS=$(echo "$CORE_DIRS $MOUNTED_DIRS" | tr ' ' '\n' | sort -u)
# Ensure the needed directories exist
for dir in $CHECK_DIRS; do
if [ ! -e "$dir" ]; then
echo "Creating missing directory: $dir"
mkdir -p "$dir" 2>/dev/null || echo "Warning: Could not create $dir" >&2
fi
done
# Mode Selection
if [ "$(id -u)" = "0" ]; then
# Check if PUID/PGID variables are provided
if [ -n "$PUID" ] && [ -n "$PGID" ]; then
echo "Mode: PUID/PGID (UID:$PUID GID:$PGID)"
# Update the internal 'node' user to match requested IDs
groupmod -o -g "$PGID" node
usermod -o -u "$PUID" -g "$PGID" node
for dir in $CHECK_DIRS; do
if [ -d "$dir" ]; then
# Runs chown only if there is an mismatch
DIR_UID=$(stat -c '%u' "$dir")
DIR_GID=$(stat -c '%g' "$dir")
if [ "$DIR_UID" != "$PUID" ] || [ "$DIR_GID" != "$PGID" ]; then
echo "(Detected mismatch) Adjusting permissions for: $dir."
chown -R node:node "$dir" || echo "Warning: Failed to update permissions for '$dir'." >&2
fi
fi
done
# Fix config file specifically
chown node:node "config/config.yaml" 2>/dev/null
# Set execution prefix to run as 'node' user
EXEC_PREFIX="su-exec node:node"
else
# Default: Run as Root (original behavior)
echo "Mode: Default (Root)"
EXEC_PREFIX=""
fi
else
# Non-Root Mode (Docker CLI --user flag)
echo "Mode: Strict Non-Root (UID: $(id -u))"
# We CANNOT auto-fix permissions in this mode because we lack privileges.
# Relying solely on the user configuring their host permissions correctly.
EXEC_PREFIX=""
fi
# Calling function with the determined prefix
start_sillytavern "$EXEC_PREFIX" "$@"