fokemal / docker-entrypoint.sh
automindy's picture
Sync to upstream v0.13.7, keep HF Space adaptations
dcedb25
Raw History Blame Contribute Delete
1.77 kB
#!/bin/sh
set -e
# PaaS runtimes (Railway, Render, ...) bind-mount the persistent volume at
# /app/server/data with root ownership, while the image runs as USER node.
# Chown the data dir before starting so better-sqlite3 can create the DB
# there, then drop back to the unprivileged user.
# Best effort by design: chown fails legitimately under --cap-drop=CHOWN and on
# CIFS/NFS mounts that pin ownership. Startup must not abort over it — the app
# may still be able to write, and if it cannot it says so itself.
ensure_owned() {
dir="$1"
[ -n "$dir" ] || return 0
if ! mkdir -p "$dir" 2>/dev/null; then
echo "docker-entrypoint: could not create $dir; continuing" >&2
fi
[ -d "$dir" ] || return 0
# Skip the recursive walk when the tree is already node-owned: on a large
# data dir that is the whole boot cost of this entrypoint.
if [ "$(stat -c %u "$dir" 2>/dev/null)" = "$NODE_UID" ]; then
return 0
fi
if ! chown -R "$NODE_UID:$NODE_GID" "$dir" 2>/dev/null; then
echo "docker-entrypoint: could not chown $dir; continuing" >&2
fi
}
if [ "$(id -u)" = "0" ]; then
NODE_UID="$(id -u node)"
NODE_GID="$(id -g node)"
ensure_owned /app/server/data
# docker/README.md tells single-mount PaaS operators to point these at their
# one persistent directory, which may sit outside /app/server/data.
if [ -n "$FREEAPI_DB_PATH" ]; then
ensure_owned "$(dirname "$FREEAPI_DB_PATH")"
fi
if [ -n "$FREEAPI_DB_BACKUP_PATH" ]; then
ensure_owned "$(dirname "$FREEAPI_DB_BACKUP_PATH")"
fi
# setpriv ships in util-linux on node:20-bookworm-slim, so it is always
# present; exec'ing it keeps node as PID 1 so signals reach the server.
exec setpriv --reuid=node --regid=node --init-groups -- "$@"
fi
exec "$@"