mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-10 06:11:02 +00:00
402a02a302
The entrypoint comment, the Helm chart README, the wiki and the ssrfGuard note now describe what the shipped check does.
69 lines
3.6 KiB
Bash
69 lines
3.6 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 whose top level was copied in as root) shows
|
|
# there, and is handed over once. Files copied in as root further down, into a
|
|
# subdirectory node already owns, do not show and are left alone; the
|
|
# Troubleshooting page of the wiki has the one-off chown for that.
|
|
#
|
|
# Only the owning user has to be node, because that is what Node runs as and
|
|
# what gosu leaves it with. The group is left to whoever set it: a Kubernetes
|
|
# fsGroup other than 1000 gives every file its own gid, and taking that back
|
|
# here would make the kubelet's OnRootMismatch walk the volume again on the
|
|
# next start, and this script after it, every time. Only a root group (a fresh
|
|
# volume under plain docker) is handed to node as well.
|
|
#
|
|
# 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 0 \) -print -quit 2>/dev/null)" ]; then
|
|
if chown node "$dir" 2>/dev/null; then
|
|
echo "Correcting ownership of $dir for the node user..."
|
|
chown -R -h node "$dir" 2>/dev/null || true
|
|
find "$dir" -group 0 -exec chgrp -h node {} + 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
|