feat(docker): Add PUID/PGID support for volume permissions

Introduces a robust entrypoint script and 'gosu' to allow users to specify
Process User ID (PUID) and Process Group ID (PGID) via environment variables.

This resolves permission errors encountered when binding host volumes into
the container, as the entrypoint script now runs 'chown' on /config and
/metadata as root before dropping privileges and running the application.

- Adds 'gosu' dependency to the runtime stage.
- Implements 'docker-entrypoint.sh' to handle user switching and permission fixing.
- Updates ENTRYPOINT to use the wrapper script, passing CMD as arguments.
This commit is contained in:
Vylyne 2025-09-25 18:05:09 -04:00
parent e040396b20
commit a20158254f
2 changed files with 60 additions and 2 deletions

View file

@ -50,7 +50,8 @@ ARG NUSQLITE3_PATH
RUN apk add --no-cache --update \
tzdata \
ffmpeg \
tini
tini \
gosu
WORKDIR /app
@ -59,6 +60,10 @@ COPY --from=build-client /client/dist /app/client/dist
COPY --from=build-server /server /app
COPY --from=build-server ${NUSQLITE3_PATH} ${NUSQLITE3_PATH}
# Copy Entry script and add execute permissions.
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE 80
ENV PORT=80
@ -69,5 +74,7 @@ ENV SOURCE="docker"
ENV NUSQLITE3_DIR=${NUSQLITE3_DIR}
ENV NUSQLITE3_PATH=${NUSQLITE3_PATH}
ENTRYPOINT ["tini", "--"]
# Call entrypoint script instead of just tini.
ENTRYPOINT ["tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
# This becomes the argument ($@) for the entrypoint script
CMD ["node", "index.js"]

51
docker-entrypoint.sh Normal file
View file

@ -0,0 +1,51 @@
#!/bin/sh
set -e
# --- PUID/PGID Check and Defaults ---
# Set default PUID/PGID to 1000 if not provided
PUID=${PUID:-1000}
PGID=${PGID:-1000}
echo "Starting with PUID: $PUID, PGID: $PGID"
# --- User/Group Setup ---
# Create or modify the 'appuser' group to match the PGID
if [ -z "$(getent group "${PGID}")" ]; then
addgroup -g "${PGID}" appgroup
else
# Group exists, ensure the name is correct for the PUID/PGID
group_name=$(getent group "${PGID}" | cut -d: -f1)
if [ "$group_name" != "appgroup" ]; then
echo "WARNING: PGID ${PGID} already exists with name ${group_name}. Using existing group."
app_group_name="${group_name}"
else
app_group_name="appgroup"
fi
fi
# Create or modify the 'appuser' user to match the PUID and assign to the PGID
if [ -z "$(getent passwd "${PUID}")" ]; then
adduser -u "${PUID}" -G "${app_group_name:-appgroup}" -D -s /bin/sh appuser
else
# User exists, ensure the name is correct for the PUID/PGID
user_name=$(getent passwd "${PUID}" | cut -d: -f1)
if [ "$user_name" != "appuser" ]; then
echo "WARNING: PUID ${PUID} already exists with name ${user_name}. Using existing user."
app_user_name="${user_name}"
else
app_user_name="appuser"
fi
fi
# --- Permission Fix (Crucial Step) ---
# This fixes permissions on directories meant for bind mounts (volumes)
# CONFIG_PATH and METADATA_PATH are the likely mount points
echo "Fixing permissions on volume paths (${CONFIG_PATH} and ${METADATA_PATH})..."
chown -R "${PUID}":"${PGID}" "${CONFIG_PATH}" || true
chown -R "${PUID}":"${PGID}" "${METADATA_PATH}" || true
# --- Execute Main Command ---
# Use 'gosu' to securely drop privileges and run the main command
# Pass all arguments ($@) to the final application command
echo "Executing CMD as user ${PUID}..."
exec gosu "${PUID}":"${PGID}" "$@"