Files
rustfs/entrypoint.sh
T
安正超 e9c9a2d1f2 fix: simplify Docker entrypoint following efficient user switching pattern (#421)
* fix: simplify Docker entrypoint following efficient user switching pattern

- Remove ALL file permission modifications (no chown at all)
- Use chroot --userspec or gosu to switch user context
- Extremely simple and fast implementation
- Zero filesystem modifications for permissions

Fixes #388

* Update entrypoint.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update entrypoint.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update entrypoint.sh

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* wip

* wip

* wip

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-19 22:58:54 +08:00

82 lines
2.8 KiB
Bash
Executable File

#!/bin/sh
set -e
# 1) Normalize command:
# - No arguments: default to execute rustfs
# - First argument starts with '-': treat as rustfs arguments, auto-prefix rustfs
# - First argument is 'rustfs': replace with absolute path to avoid PATH interference
if [ $# -eq 0 ] || [ "${1#-}" != "$1" ]; then
set -- /usr/bin/rustfs "$@"
elif [ "$1" = "rustfs" ]; then
shift
set -- /usr/bin/rustfs "$@"
fi
# 2) Parse and create local mount directories (ignore http/https), ensure /logs is included
VOLUME_RAW="${RUSTFS_VOLUMES:-/data}"
# Convert comma/tab to space
VOLUME_LIST=$(echo "$VOLUME_RAW" | tr ',\t' ' ')
LOCAL_VOLUMES=""
for vol in $VOLUME_LIST; do
case "$vol" in
/*)
case "$vol" in
http://*|https://*) : ;;
*) LOCAL_VOLUMES="$LOCAL_VOLUMES $vol" ;;
esac
;;
*)
: # skip non-local paths
;;
esac
done
# Ensure /logs is included
case " $LOCAL_VOLUMES " in
*" /logs "*) : ;;
*) LOCAL_VOLUMES="$LOCAL_VOLUMES /logs" ;;
esac
echo "Initializing mount directories:$LOCAL_VOLUMES"
for vol in $LOCAL_VOLUMES; do
if [ ! -d "$vol" ]; then
echo " mkdir -p $vol"
mkdir -p "$vol"
# If target user is specified, try to set directory owner to that user (non-recursive to avoid large disk overhead)
if [ -n "$RUSTFS_UID" ] && [ -n "$RUSTFS_GID" ]; then
chown "$RUSTFS_UID:$RUSTFS_GID" "$vol" 2>/dev/null || true
elif [ -n "$RUSTFS_USERNAME" ] && [ -n "$RUSTFS_GROUPNAME" ]; then
chown "$RUSTFS_USERNAME:$RUSTFS_GROUPNAME" "$vol" 2>/dev/null || true
fi
fi
done
# 3) Default credentials warning
if [ "${RUSTFS_ACCESS_KEY}" = "rustfsadmin" ] || [ "${RUSTFS_SECRET_KEY}" = "rustfsadmin" ]; then
echo "!!!WARNING: Using default RUSTFS_ACCESS_KEY or RUSTFS_SECRET_KEY. Override them in production!"
fi
# 4) Start with specified user
docker_switch_user() {
if [ -n "${RUSTFS_USERNAME}" ] && [ -n "${RUSTFS_GROUPNAME}" ]; then
if [ -n "${RUSTFS_UID}" ] && [ -n "${RUSTFS_GID}" ]; then
# Execute with numeric UID:GID directly (doesn't depend on user existing in system)
exec chroot --userspec="${RUSTFS_UID}:${RUSTFS_GID}" / "$@"
else
# When only names are provided, create minimal passwd/group entries with 1000:1000; deduplicate before writing
if ! grep -q "^${RUSTFS_USERNAME}:" /etc/passwd 2>/dev/null; then
echo "${RUSTFS_USERNAME}:x:1000:1000:${RUSTFS_USERNAME}:/nonexistent:/sbin/nologin" >> /etc/passwd
fi
if ! grep -q "^${RUSTFS_GROUPNAME}:" /etc/group 2>/dev/null; then
echo "${RUSTFS_GROUPNAME}:x:1000:" >> /etc/group
fi
exec chroot --userspec="${RUSTFS_USERNAME}:${RUSTFS_GROUPNAME}" / "$@"
fi
else
# If no user is specified, keep as root (container has minimal privilege practices that can be configured separately)
exec "$@"
fi
}
echo "Starting: $*"
docker_switch_user "$@"