9e381ebe32
Named Docker volumes are created as root on first use, causing permission denied errors for the developer user. The entrypoint now fixes ownership of all known volume mount points after UID/GID adjustment.
69 lines
3.3 KiB
Bash
69 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
USER_NAME="developer"
|
|
CURRENT_UID=$(id -u "$USER_NAME")
|
|
CURRENT_GID=$(id -g "$USER_NAME")
|
|
|
|
# ── UID/GID adjustment ───────────────────────────────────────────────
|
|
# Priority: env vars > auto-detect from /workspace > default (1000)
|
|
TARGET_UID="${USER_UID:-}"
|
|
TARGET_GID="${USER_GID:-}"
|
|
|
|
# Auto-detect from /workspace owner if env vars not set
|
|
if [ -z "$TARGET_UID" ] && [ -d /workspace ]; then
|
|
WORKSPACE_UID=$(stat -c '%u' /workspace 2>/dev/null || stat -f '%u' /workspace 2>/dev/null)
|
|
WORKSPACE_GID=$(stat -c '%g' /workspace 2>/dev/null || stat -f '%g' /workspace 2>/dev/null)
|
|
# Only adjust if workspace is owned by a non-root user
|
|
if [ "$WORKSPACE_UID" != "0" ] && [ "$WORKSPACE_UID" != "$CURRENT_UID" ]; then
|
|
TARGET_UID="$WORKSPACE_UID"
|
|
TARGET_GID="${TARGET_GID:-$WORKSPACE_GID}"
|
|
fi
|
|
fi
|
|
|
|
# Apply UID/GID changes if needed
|
|
if [ -n "$TARGET_GID" ] && [ "$TARGET_GID" != "$CURRENT_GID" ]; then
|
|
groupmod -g "$TARGET_GID" "$USER_NAME" 2>/dev/null || true
|
|
find /home/"$USER_NAME" -not -path "/home/$USER_NAME/.ssh/*" -group "$CURRENT_GID" -exec chgrp "$TARGET_GID" {} + 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -n "$TARGET_UID" ] && [ "$TARGET_UID" != "$CURRENT_UID" ]; then
|
|
usermod -u "$TARGET_UID" "$USER_NAME" 2>/dev/null || true
|
|
find /home/"$USER_NAME" -not -path "/home/$USER_NAME/.ssh/*" -user "$CURRENT_UID" -exec chown "$TARGET_UID" {} + 2>/dev/null || true
|
|
echo "Adjusted developer UID:GID to $TARGET_UID:${TARGET_GID:-$CURRENT_GID}"
|
|
fi
|
|
|
|
# ── SSH key permissions ──────────────────────────────────────────────
|
|
# If SSH keys are mounted, fix permissions (skip if read-only mount)
|
|
if [ -d "/home/$USER_NAME/.ssh" ] && [ "$(ls -A "/home/$USER_NAME/.ssh" 2>/dev/null)" ]; then
|
|
if touch "/home/$USER_NAME/.ssh/.perm_test" 2>/dev/null; then
|
|
rm -f "/home/$USER_NAME/.ssh/.perm_test"
|
|
chmod 700 "/home/$USER_NAME/.ssh"
|
|
find "/home/$USER_NAME/.ssh" -type f -name "id_*" ! -name "*.pub" -exec chmod 600 {} \; 2>/dev/null || true
|
|
find "/home/$USER_NAME/.ssh" -type f -name "*.pub" -exec chmod 644 {} \; 2>/dev/null || true
|
|
[ -f "/home/$USER_NAME/.ssh/known_hosts" ] && chmod 644 "/home/$USER_NAME/.ssh/known_hosts"
|
|
[ -f "/home/$USER_NAME/.ssh/config" ] && chmod 600 "/home/$USER_NAME/.ssh/config"
|
|
fi
|
|
fi
|
|
|
|
# ── Fix ownership of named volume mount points ──────────────────────
|
|
# Named volumes are created as root on first use. Fix ownership so the
|
|
# developer user can write to them.
|
|
FINAL_UID="${TARGET_UID:-$CURRENT_UID}"
|
|
FINAL_GID="${TARGET_GID:-$CURRENT_GID}"
|
|
for dir in \
|
|
/home/"$USER_NAME"/.local/share/opencode \
|
|
/home/"$USER_NAME"/.local/share/uv \
|
|
/home/"$USER_NAME"/.rustup \
|
|
/home/"$USER_NAME"/.cargo \
|
|
/home/"$USER_NAME"/.vscode-server \
|
|
/home/"$USER_NAME"/.config/opencode \
|
|
/home/"$USER_NAME"/.config/nvim; do
|
|
if [ -d "$dir" ] && [ "$(stat -c '%u' "$dir" 2>/dev/null)" != "$FINAL_UID" ]; then
|
|
chown -R "$FINAL_UID":"$FINAL_GID" "$dir" 2>/dev/null || true
|
|
fi
|
|
done
|
|
|
|
# ── Drop to developer user for remaining setup ──────────────────────
|
|
exec gosu "$USER_NAME" /usr/local/bin/entrypoint-user.sh "$@"
|