mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 15:21:08 +00:00
7faf771f9c
The ownership check still read every inode of the volumes on each start. It now looks at the dirs and what sits directly in them, hands a volume over once when it is not node's, and logs a warning instead of walking a volume that refuses chown (NFS with root_squash).
57 lines
2.9 KiB
Bash
57 lines
2.9 KiB
Bash
#!/bin/sh
|
|
# Container start-up: check the image layout, correct ownership of the mounted
|
|
# data dirs while still root, then drop to the node user.
|
|
#
|
|
# This has to stay a file rather than an inline `sh -c` string in CMD. Container
|
|
# management UIs render Config.Cmd back into a text field and re-split it with a
|
|
# quote-aware tokenizer when you edit a container in place; a command carrying
|
|
# embedded quotes comes back mangled and the container dies with a shell syntax
|
|
# error before Node starts. A CMD of one bare token survives that round-trip.
|
|
set -e
|
|
|
|
# If the app code is missing, a volume was almost certainly mounted over /app
|
|
# (it hides the image's node_modules + dist). Fail with actionable guidance
|
|
# instead of a cryptic "Cannot find module 'tsconfig-paths/register'".
|
|
if [ ! -f /app/server/dist/index.js ] || [ ! -d /app/node_modules/tsconfig-paths ]; then
|
|
echo 'FATAL: TREK application files are missing from the image.'
|
|
echo 'A volume is likely mounted over /app, which hides the app code.'
|
|
echo 'Mount ONLY your data and uploads dirs: -v ./data:/app/data -v ./uploads:/app/uploads'
|
|
echo 'Do NOT mount a volume at /app. See https://github.com/liketrek/TREK/wiki/Troubleshooting'
|
|
exit 1
|
|
fi
|
|
|
|
# cd into server/ so tsconfig-paths/register finds tsconfig.json and
|
|
# ../node_modules resolves correctly.
|
|
cd /app/server
|
|
|
|
# Already started as a non-root user (Kubernetes runAsUser, docker --user): there
|
|
# is nothing to chown and no privilege to drop, and gosu would only fail to switch
|
|
# users. Run Node as whoever we are; the volumes are that user's to provide.
|
|
if [ "$(id -u)" != "0" ]; then
|
|
exec node --require tsconfig-paths/register dist/index.js
|
|
fi
|
|
|
|
# Hand the mounted data dirs to node. A blanket `chown -R` on every start
|
|
# rewrote, and even a search for strays still read, every inode of the volume,
|
|
# which on a large or network-backed one (NFS, CephFS, Longhorn) kept the
|
|
# container busy for minutes before Node printed its first line (#2918). So only
|
|
# the dir and what sits directly in it are looked at: a volume that is not
|
|
# node's yet (a fresh one, or one copied in as root) shows there, and is handed
|
|
# over once. A volume that refuses chown altogether (NFS with root_squash) is
|
|
# said once per start instead of being walked file by file; such a pod belongs
|
|
# under runAsUser 1000, see the Helm page of the wiki. Best effort either way: a
|
|
# read-only host filesystem or a locked-down bind mount must keep booting.
|
|
for dir in /app/data /app/uploads; do
|
|
[ -d "$dir" ] || continue
|
|
if [ -n "$(find "$dir" -maxdepth 1 \( ! -user node -o ! -group node \) -print -quit 2>/dev/null)" ]; then
|
|
if chown node:node "$dir" 2>/dev/null; then
|
|
echo "Correcting ownership of $dir for the node user..."
|
|
chown -R -h node:node "$dir" 2>/dev/null || true
|
|
else
|
|
echo "WARNING: $dir cannot be handed to the node user (chown refused); run the container as uid 1000 instead."
|
|
fi
|
|
fi
|
|
done
|
|
|
|
exec gosu node node --require tsconfig-paths/register dist/index.js
|