Blame Raw
Cohee · 51ad27fb · · 99 lines (3.4 KB)
1 contributor
1#!/bin/sh
2
3# Function to handle startup logic (Config check + init + Start)
4start_sillytavern() {
5 local PREFIX="$1"
6 shift # Remove the first argument (PREFIX) so $@ contains the rest
7
8 # Config Check
9 if [ ! -e "config/config.yaml" ]; then
10 echo "Resource not found, copying from defaults: config.yaml"
11 $PREFIX cp "default/config.yaml" "config/config.yaml"
12 fi
13
14 # Execute init script to auto-populate config.yaml with missing values
15 $PREFIX npm run init
16
17 # Start the server
18 exec $PREFIX node server.js --listen "$@"
19}
20
21# Dirs that MUST be present at this point (e.g for volumeless docker runs).
22# Please update list, if in the future a related perm issue appear.
23CORE_DIRS="config data plugins public/scripts/extensions/third-party backups"
24
25# Mounted Volumes (External)
26# Parse mounts, handling files vs directories
27RAW_MOUNTS=$(awk -v app_path="/home/node/app" '$2 ~ "^" app_path {print $2}' /proc/mounts)
28MOUNTED_DIRS=""
29
30for mount in $RAW_MOUNTS; do
31 if [ -f "$mount" ]; then
32 # If it is a mounted file (e.g. cert.pem), we want to check its PARENT directory
33 # so that the app can write adjacent files (e.g. key.pem).
34 PARENT_DIR=$(dirname "$mount")
35
36 # Performance Safety: If the file is in the root of the app,
37 # we do NOT add the parent (App Root), or we will recursively scan the whole app.
38 [ "$PARENT_DIR" != "/home/node/app" ] && MOUNTED_DIRS="$MOUNTED_DIRS $PARENT_DIR" || MOUNTED_DIRS="$MOUNTED_DIRS $mount"
39 else
40 # It is a directory, add it directly
41 MOUNTED_DIRS="$MOUNTED_DIRS $mount"
42 fi
43done
44
45# Combine dirs for checks
46CHECK_DIRS=$(echo "$CORE_DIRS $MOUNTED_DIRS" | tr ' ' '\n' | sort -u)
47
48# Ensure the needed directories exist
49for dir in $CHECK_DIRS; do
50 if [ ! -e "$dir" ]; then
51 echo "Creating missing directory: $dir"
52 mkdir -p "$dir" 2>/dev/null || echo "Warning: Could not create $dir" >&2
53 fi
54done
55
56# Mode Selection
57if [ "$(id -u)" = "0" ]; then
58 # Check if PUID/PGID variables are provided
59 if [ -n "$PUID" ] && [ -n "$PGID" ]; then
60 echo "Mode: PUID/PGID (UID:$PUID GID:$PGID)"
61
62 # Update the internal 'node' user to match requested IDs
63 groupmod -o -g "$PGID" node
64 usermod -o -u "$PUID" -g "$PGID" node
65
66 for dir in $CHECK_DIRS; do
67 if [ -d "$dir" ]; then
68 # Runs chown only if there is an mismatch
69 DIR_UID=$(stat -c '%u' "$dir")
70 DIR_GID=$(stat -c '%g' "$dir")
71
72 if [ "$DIR_UID" != "$PUID" ] || [ "$DIR_GID" != "$PGID" ]; then
73 echo "(Detected mismatch) Adjusting permissions for: $dir."
74 chown -R node:node "$dir" || echo "Warning: Failed to update permissions for '$dir'." >&2
75 fi
76 fi
77 done
78
79 # Fix config file specifically
80 chown node:node "config/config.yaml" 2>/dev/null
81
82 # Set execution prefix to run as 'node' user
83 EXEC_PREFIX="su-exec node:node"
84 else
85 # Default: Run as Root (original behavior)
86 echo "Mode: Default (Root)"
87 EXEC_PREFIX=""
88 fi
89
90else
91 # Non-Root Mode (Docker CLI --user flag)
92 echo "Mode: Strict Non-Root (UID: $(id -u))"
93 # We CANNOT auto-fix permissions in this mode because we lack privileges.
94 # Relying solely on the user configuring their host permissions correctly.
95 EXEC_PREFIX=""
96fi
97
98# Calling function with the determined prefix
99start_sillytavern "$EXEC_PREFIX" "$@"