mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-27 12:18:59 +00:00
98 lines
5.2 KiB
Bash
98 lines
5.2 KiB
Bash
#!/bin/sh
|
|
set -e
|
|
|
|
# Resolve the data directory, mirroring DatabaseService.ts logic.
|
|
DATA_DIR="${DATA_DIR:-/app/data}"
|
|
|
|
# If running as root (the default Docker container start), fix volume ownership,
|
|
# fix Docker socket group access, then drop privileges before executing the app.
|
|
#
|
|
# This is the industry-standard pattern used by the official PostgreSQL, Redis,
|
|
# and MariaDB Docker images, and by Docker management tools like Portainer and
|
|
# Dockge that also require access to /var/run/docker.sock as a non-root user.
|
|
#
|
|
# The UID guard also ensures compatibility with strict environments like
|
|
# Kubernetes (runAsNonRoot: true) or OpenShift, where the container is forced to
|
|
# run as a random high UID. In that case both blocks are skipped and the app
|
|
# exec's directly without crashing.
|
|
if [ "$(id -u)" = '0' ]; then
|
|
|
|
# ── 1. Fix data volume ownership ────────────────────────────────────────
|
|
# Handles host volumes previously created by root or a different UID, which
|
|
# would cause SQLITE_READONLY errors when the non-root sencho user starts.
|
|
# Only touches files with wrong user OR group (efficient on large dirs).
|
|
mkdir -p "$DATA_DIR"
|
|
find "$DATA_DIR" \( \! -user sencho -o \! -group sencho \) \
|
|
-exec chown sencho:sencho '{}' +
|
|
echo "[entrypoint] Data directory ownership ensured: $DATA_DIR"
|
|
|
|
# ── 2. Fix Docker socket group access ───────────────────────────────────
|
|
# The Docker socket on the host is owned by the host's docker group, whose
|
|
# GID varies by Linux distribution and does not match any group inside the
|
|
# container by default.
|
|
#
|
|
# Solution: detect the socket's GID at runtime, create a matching group
|
|
# inside the container if one doesn't already exist, then add sencho to it.
|
|
# su-exec calls getgrouplist() which reads /etc/group, so supplementary
|
|
# groups added here ARE inherited by the Node process.
|
|
if [ -S /var/run/docker.sock ]; then
|
|
DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock)
|
|
DOCKER_SOCK_MODE=$(stat -c '%a' /var/run/docker.sock)
|
|
echo "[entrypoint] Docker socket found: GID=$DOCKER_SOCK_GID mode=$DOCKER_SOCK_MODE"
|
|
|
|
if [ "$DOCKER_SOCK_GID" = "0" ]; then
|
|
# Socket is owned by root:root. The only way to access it without
|
|
# running as root is to make it group-readable and assign a shared
|
|
# group. We create a 'docker-sock' group with GID 0 for clarity.
|
|
echo "[entrypoint] WARNING: Docker socket is root:root — adding sencho to root group"
|
|
addgroup sencho root 2>/dev/null || true
|
|
else
|
|
if ! getent group "$DOCKER_SOCK_GID" > /dev/null 2>&1; then
|
|
addgroup -S -g "$DOCKER_SOCK_GID" docker-host
|
|
echo "[entrypoint] Created group docker-host with GID $DOCKER_SOCK_GID"
|
|
fi
|
|
DOCKER_GROUP=$(getent group "$DOCKER_SOCK_GID" | cut -d: -f1)
|
|
addgroup sencho "$DOCKER_GROUP" 2>/dev/null || true
|
|
echo "[entrypoint] Added sencho to group '$DOCKER_GROUP' (GID $DOCKER_SOCK_GID)"
|
|
fi
|
|
else
|
|
echo "[entrypoint] WARNING: /var/run/docker.sock not found — Docker features will be unavailable"
|
|
fi
|
|
|
|
echo "[entrypoint] Dropping privileges to sencho (uid=$(id -u sencho))"
|
|
|
|
# ── 3. Drop privileges ──────────────────────────────────────────────────
|
|
# Replace this shell process with su-exec so that Node becomes PID 1 and
|
|
# receives SIGTERM/SIGINT directly from Docker. su-exec calls getgrouplist()
|
|
# for named users, so all supplementary groups set above are inherited.
|
|
# If running as root (the default Docker container start), fix volume ownership
|
|
# then drop privileges before executing the application.
|
|
#
|
|
# This handles the common case where the host-mounted data volume was created by
|
|
# root (or a different UID) from a previous run or backup restore — causing
|
|
# SQLITE_READONLY errors when the non-root sencho user tries to write.
|
|
#
|
|
# This is the industry-standard pattern used by the official PostgreSQL, Redis,
|
|
# and MariaDB Docker images.
|
|
#
|
|
# The UID guard also ensures compatibility with strict environments like
|
|
# Kubernetes (runAsNonRoot: true) or OpenShift, where the container is forced to
|
|
# run as a random high UID. In that case the chown block is skipped entirely and
|
|
# the app exec's directly without crashing.
|
|
if [ "$(id -u)" = '0' ]; then
|
|
mkdir -p "$DATA_DIR"
|
|
|
|
# Fix files where user OR group is wrong — not just user. This covers the
|
|
# case where a file ends up as sencho:root after a partial previous fix.
|
|
# The -exec '{}' + form batches arguments for efficiency (like xargs).
|
|
find "$DATA_DIR" \( \! -user sencho -o \! -group sencho \) \
|
|
-exec chown sencho:sencho '{}' +
|
|
|
|
# Replace this shell process with su-exec so that Node becomes PID 1 and
|
|
# receives SIGTERM/SIGINT directly from Docker. Without exec the shell would
|
|
# intercept signals and the container would hang for 10s before SIGKILL.
|
|
exec su-exec sencho "$@"
|
|
fi
|
|
|
|
exec "$@"
|