mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-05 08:27:42 +00:00
fix(docker): repair broken entrypoint from bad merge conflict resolution
The merge of PR58 into PR59's branch produced a corrupt docker-entrypoint.sh (97 lines) where PR59's if block was cut off mid-way (missing exec su-exec and closing fi) and then PR58's entire if block was appended. This caused: /usr/local/bin/docker-entrypoint.sh: line 98: syntax error: unexpected end of file (expecting "fi") Fix: overwrite with the clean 71-line version and add a defensive `sed -i 's/\r//'` step in the Dockerfile to strip Windows CRLF line endings at build time, preventing this class of error even if CRLF slips past .gitattributes in future.
This commit is contained in:
+5
-1
@@ -75,7 +75,11 @@ RUN addgroup -S sencho && adduser -S -G sencho sencho \
|
||||
# security scanners (Trivy, Clair) may flag "running as root" — this is a known
|
||||
# and accepted trade-off for self-hosted apps with user-supplied volume mounts.
|
||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
# Strip Windows CRLF line endings that can sneak in on Windows dev machines
|
||||
# even with .gitattributes eol=lf, then make executable. A shell script with
|
||||
# \r in tokens like "fi\r" will fail with "unexpected end of file" in Alpine.
|
||||
RUN sed -i 's/\r//' /usr/local/bin/docker-entrypoint.sh \
|
||||
&& chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
+8
-42
@@ -17,7 +17,7 @@ DATA_DIR="${DATA_DIR:-/app/data}"
|
||||
# exec's directly without crashing.
|
||||
if [ "$(id -u)" = '0' ]; then
|
||||
|
||||
# ── 1. Fix data volume ownership ────────────────────────────────────────
|
||||
# 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).
|
||||
@@ -26,25 +26,17 @@ if [ "$(id -u)" = '0' ]; then
|
||||
-exec chown sencho:sencho '{}' +
|
||||
echo "[entrypoint] Data directory ownership ensured: $DATA_DIR"
|
||||
|
||||
# ── 2. Fix Docker socket group access ───────────────────────────────────
|
||||
# 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"
|
||||
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
|
||||
@@ -56,41 +48,15 @@ if [ "$(id -u)" = '0' ]; then
|
||||
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"
|
||||
echo "[entrypoint] WARNING: /var/run/docker.sock not found -- Docker features 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.
|
||||
# 3. Drop privileges.
|
||||
# Replace this shell with su-exec so Node becomes PID 1 and receives
|
||||
# SIGTERM/SIGINT directly. su-exec calls getgrouplist() for named users,
|
||||
# so all supplementary groups added above are inherited by the process.
|
||||
exec su-exec sencho "$@"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user