From 45fdd8498f389272abfd394c84f452e3e6d1dac7 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 14:16:37 -0400 Subject: [PATCH 01/10] Dont use root --- Dockerfile | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 53290b4..25bc0f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,13 @@ ARG TARGETPLATFORM # We don't actually need to create a new user # Just set a reasonable home directory -WORKDIR /home/root -ENV HOME=/home/root +ARG UID=1000 +ARG GID=1000 +ENV USERNAME=rgpeach10 +RUN adduser -D -u ${UID} -g ${GID} ${USERNAME} +USER ${USERNAME} +WORKDIR /home/${USERNAME} +ENV HOME=/home/${USERNAME} # Stable repos first, edge as fallback for packages not yet in stable # Stable repos first @@ -96,7 +101,7 @@ RUN apk add --no-cache --repositories-file /etc/apk/repositories.edge \ && rm -rf /var/cache/apk/* # Cargo installs -ENV PATH="/home/root/.cargo/bin:$PATH" +ENV PATH="/home/${USERNAME}/.cargo/bin:$PATH" # uv installs ENV PATH="$HOME/.local/bin:$PATH" @@ -155,7 +160,7 @@ RUN curl -sS https://webi.sh/gh | sh # Install Oh My Zsh RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" -ENV ZSH_CUSTOM=/home/root/.oh-my-zsh/custom +ENV ZSH_CUSTOM=/home/${USERNAME}/.oh-my-zsh/custom RUN git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions RUN git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting RUN git clone --depth=1 https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k From f645c0fb4420206a691c384e8bef31e0e2e65f03 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 14:21:03 -0400 Subject: [PATCH 02/10] Move dropping root permissions to after apk adds --- Dockerfile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 25bc0f8..c3d8b4b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,6 @@ ARG UID=1000 ARG GID=1000 ENV USERNAME=rgpeach10 RUN adduser -D -u ${UID} -g ${GID} ${USERNAME} -USER ${USERNAME} -WORKDIR /home/${USERNAME} -ENV HOME=/home/${USERNAME} # Stable repos first, edge as fallback for packages not yet in stable # Stable repos first @@ -104,7 +101,7 @@ RUN apk add --no-cache --repositories-file /etc/apk/repositories.edge \ ENV PATH="/home/${USERNAME}/.cargo/bin:$PATH" # uv installs -ENV PATH="$HOME/.local/bin:$PATH" +ENV PATH="/home/root/.local/bin:$PATH" RUN curl -LsSf https://astral.sh/uv/install.sh | sh RUN apk --no-cache --virtual .build-deps add \ gcc \ @@ -142,6 +139,12 @@ RUN apk --no-cache --virtual .build-deps add \ uv tool install --verbose thefuck && \ uv tool install --verbose ansible +# Drop root permissions +USER ${USERNAME} +WORKDIR /home/${USERNAME} +ENV HOME=/home/${USERNAME} +ENV PATH="$HOME/.local/bin:$PATH" + # npm installs RUN npm install -g \ prettier \ From d291d49545999ede94275b3519205605a4aba883 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 14:44:14 -0400 Subject: [PATCH 03/10] Use this entrypoint hack the AI told me about --- Dockerfile | 33 +++++++++++++++++++-------------- entrypoint.sh | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index c3d8b4b..e091c31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -97,12 +97,7 @@ RUN apk add --no-cache --repositories-file /etc/apk/repositories.edge \ helmfile \ && rm -rf /var/cache/apk/* -# Cargo installs -ENV PATH="/home/${USERNAME}/.cargo/bin:$PATH" - -# uv installs -ENV PATH="/home/root/.local/bin:$PATH" -RUN curl -LsSf https://astral.sh/uv/install.sh | sh +# Build dependencies needed for uv tool compilation (requires root) RUN apk --no-cache --virtual .build-deps add \ gcc \ g++ \ @@ -126,9 +121,18 @@ RUN apk --no-cache --virtual .build-deps add \ sshpass \ patch \ build-base \ - gcc-doc && \ + gcc-doc + +# Drop root — all remaining commands run as the non-root user +USER ${USERNAME} +WORKDIR /home/${USERNAME} +ENV HOME=/home/${USERNAME} + +# uv installs (as user) +ENV PATH="$HOME/.local/bin:$PATH" +RUN curl -LsSf https://astral.sh/uv/install.sh | sh +RUN uv tool install --verbose pre-commit && \ # uv tool install aider-chat && \ TODO: Fix this, something to do with scipy - uv tool install --verbose pre-commit && \ uv tool install --verbose ruff && \ uv tool install --verbose ipython && \ uv tool install --verbose ipdb && \ @@ -139,12 +143,6 @@ RUN apk --no-cache --virtual .build-deps add \ uv tool install --verbose thefuck && \ uv tool install --verbose ansible -# Drop root permissions -USER ${USERNAME} -WORKDIR /home/${USERNAME} -ENV HOME=/home/${USERNAME} -ENV PATH="$HOME/.local/bin:$PATH" - # npm installs RUN npm install -g \ prettier \ @@ -154,6 +152,9 @@ RUN npm install -g \ RUN git clone --depth=1 https://github.com/tfutils/tfenv.git $HOME/.tfenv RUN .tfenv/bin/tfenv install latest +# Rust installs +ENV PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" + # Go installs ENV PATH="$HOME/go/bin:$PATH" @@ -194,4 +195,8 @@ RUN find $SHELL_DIR/home/bin -type f -exec chmod +x {} \; # terminal colors with xterm ENV TERM=xterm-256color +# Entrypoint must run as root to modify the user +COPY entrypoint.sh /entrypoint.sh +USER root +ENTRYPOINT ["/entrypoint.sh"] CMD ["/bin/zsh"] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..4b8986f --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +TARGET_UID=${TARGET_UID:-1000} +TARGET_GID=${TARGET_GID:-1000} +USERNAME=rgpeach10 + +CURRENT_UID=$(id -u "$USERNAME") +CURRENT_GID=$(id -g "$USERNAME") + +# Rewrite the user/group IDs if they differ from build time +if [ "$CURRENT_UID" != "$TARGET_UID" ] || [ "$CURRENT_GID" != "$TARGET_GID" ]; then + sed -i "s/^$USERNAME:x:$CURRENT_UID:$CURRENT_GID:/$USERNAME:x:$TARGET_UID:$TARGET_GID:/" /etc/passwd + sed -i "s/^$USERNAME:x:$CURRENT_GID:/$USERNAME:x:$TARGET_GID:/" /etc/group + chown -R "$TARGET_UID:$TARGET_GID" "/home/$USERNAME" +fi + +exec su - "$USERNAME" -s /bin/zsh -c "$*" From 20bcb897a05e7dfa7354092d57908929b2ecbfbd Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 14:44:14 -0400 Subject: [PATCH 04/10] Use this entrypoint hack the AI told me about --- Dockerfile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index e091c31..d599f56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -143,10 +143,13 @@ RUN uv tool install --verbose pre-commit && \ uv tool install --verbose thefuck && \ uv tool install --verbose ansible -# npm installs -RUN npm install -g \ +# npm installs (user-local prefix to avoid root) +RUN mkdir -p "$HOME/.npm-global" && \ + npm config set prefix "$HOME/.npm-global" && \ + npm install -g \ prettier \ pyright +ENV PATH="$HOME/.npm-global/bin:$PATH" # Install tfenv RUN git clone --depth=1 https://github.com/tfutils/tfenv.git $HOME/.tfenv @@ -174,11 +177,11 @@ RUN git clone --depth=1 https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM # REF: https://github.com/eth-p/bat-extras/issues/126 RUN git clone https://github.com/eth-p/bat-extras.git \ && cd bat-extras \ - && ./build.sh --install --no-verify + && ./build.sh --install --prefix="$HOME/.local" --no-verify # Copies ENV SHELL_DIR=$HOME/shell -COPY . $SHELL_DIR +COPY --chown=${USERNAME}:${USERNAME} . $SHELL_DIR RUN set -e \ && cd $SHELL_DIR \ && if [ -z "$(git status --porcelain)" ]; then echo "No changes"; else git status --porcelain; exit 1; fi From 02d3c224acf947c6a8f61024f3ba6af73e1b4c98 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 23:42:03 -0400 Subject: [PATCH 05/10] Make this a bit simpler and document it --- Dockerfile | 2 ++ Justfile | 2 +- README.md | 5 +---- entrypoint.sh | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) mode change 100644 => 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index d599f56..8ba1635 100644 --- a/Dockerfile +++ b/Dockerfile @@ -201,5 +201,7 @@ ENV TERM=xterm-256color # Entrypoint must run as root to modify the user COPY entrypoint.sh /entrypoint.sh USER root +WORKDIR /home/${USERNAME}/mnt +ENV MNT=/home/${USERNAME}/mnt ENTRYPOINT ["/entrypoint.sh"] CMD ["/bin/zsh"] diff --git a/Justfile b/Justfile index 9e63b4a..6bad71c 100644 --- a/Justfile +++ b/Justfile @@ -1,5 +1,5 @@ build: - docker buildx build --progress=plain -t rgpeach10/shell:local . --load + docker buildx build --progress=plain -t rgpeach10/shell:local --no-cache . --load run-local: docker run -it --rm \ diff --git a/README.md b/README.md index 9e97662..e25d8da 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,9 @@ Create a `~/.docker-shell.sh` file with the following contents: #!/usr/bin/env bash docker run -it --rm \ - -v $HOME/.ssh:/home/root/.ssh \ - -v $HOME:/home/root/mnt \ + -v $HOME:/home/rgpeach10/mnt \ -v /var/run/docker.sock:/var/run/docker.sock \ - -w /home/root/mnt \ -e GITHUB_TOKEN=$(gh auth token) \ - -e MNT=/home/rgpeach10/mnt \ --pull=always \ rgpeach10/shell:main ``` diff --git a/entrypoint.sh b/entrypoint.sh old mode 100644 new mode 100755 index 4b8986f..1c33b67 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -3,7 +3,7 @@ set -e TARGET_UID=${TARGET_UID:-1000} TARGET_GID=${TARGET_GID:-1000} -USERNAME=rgpeach10 +USERNAME=${USERNAME:-rgpeach10} CURRENT_UID=$(id -u "$USERNAME") CURRENT_GID=$(id -g "$USERNAME") From 5775d1db71794216af13b769b15cdc1baeb1809e Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 23:46:27 -0400 Subject: [PATCH 06/10] Don't change the stuff in mnt --- entrypoint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index 1c33b67..a036d1a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -12,7 +12,9 @@ CURRENT_GID=$(id -g "$USERNAME") if [ "$CURRENT_UID" != "$TARGET_UID" ] || [ "$CURRENT_GID" != "$TARGET_GID" ]; then sed -i "s/^$USERNAME:x:$CURRENT_UID:$CURRENT_GID:/$USERNAME:x:$TARGET_UID:$TARGET_GID:/" /etc/passwd sed -i "s/^$USERNAME:x:$CURRENT_GID:/$USERNAME:x:$TARGET_GID:/" /etc/group - chown -R "$TARGET_UID:$TARGET_GID" "/home/$USERNAME" + chown "$TARGET_UID:$TARGET_GID" "/home/$USERNAME" + find "/home/$USERNAME" -mindepth 1 -maxdepth 1 ! -name mnt \ + -exec chown -R "$TARGET_UID:$TARGET_GID" {} + fi exec su - "$USERNAME" -s /bin/zsh -c "$*" From fe90ec9ce02b30880bd8b496f2b6d87ec32641dd Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Wed, 1 Apr 2026 23:57:39 -0400 Subject: [PATCH 07/10] Progress bar --- entrypoint.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index a036d1a..45b7fda 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -13,8 +13,15 @@ if [ "$CURRENT_UID" != "$TARGET_UID" ] || [ "$CURRENT_GID" != "$TARGET_GID" ]; t sed -i "s/^$USERNAME:x:$CURRENT_UID:$CURRENT_GID:/$USERNAME:x:$TARGET_UID:$TARGET_GID:/" /etc/passwd sed -i "s/^$USERNAME:x:$CURRENT_GID:/$USERNAME:x:$TARGET_GID:/" /etc/group chown "$TARGET_UID:$TARGET_GID" "/home/$USERNAME" - find "/home/$USERNAME" -mindepth 1 -maxdepth 1 ! -name mnt \ - -exec chown -R "$TARGET_UID:$TARGET_GID" {} + + ITEMS=$(find "/home/$USERNAME" -mindepth 1 -maxdepth 1 ! -name mnt) + TOTAL=$(printf '%s\n' "$ITEMS" | wc -l) + I=0 + printf '%s\n' "$ITEMS" | while read -r item; do + I=$((I + 1)) + printf '\r\033[Kchown [%d/%d] %s' "$I" "$TOTAL" "${item##*/}" + chown -R "$TARGET_UID:$TARGET_GID" "$item" + done + printf '\r\033[Kchown complete (%d items)\n' "$TOTAL" fi exec su - "$USERNAME" -s /bin/zsh -c "$*" From c5de12119dc5542a481cea70bca0183a8f6d1523 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Thu, 2 Apr 2026 00:02:56 -0400 Subject: [PATCH 08/10] Get rid of entrypoint --- Dockerfile | 2 -- README.md | 3 +++ entrypoint.sh | 27 --------------------------- 3 files changed, 3 insertions(+), 29 deletions(-) delete mode 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 8ba1635..9570db3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -199,9 +199,7 @@ RUN find $SHELL_DIR/home/bin -type f -exec chmod +x {} \; ENV TERM=xterm-256color # Entrypoint must run as root to modify the user -COPY entrypoint.sh /entrypoint.sh USER root WORKDIR /home/${USERNAME}/mnt ENV MNT=/home/${USERNAME}/mnt -ENTRYPOINT ["/entrypoint.sh"] CMD ["/bin/zsh"] diff --git a/README.md b/README.md index e25d8da..c580a72 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ Create a `~/.docker-shell.sh` file with the following contents: #!/usr/bin/env bash docker run -it --rm \ + --user $(id -u) \ + -e TARGET_USER=$(id -u) \ + -e GLOBAL_USER=$(id -g) \ -v $HOME:/home/rgpeach10/mnt \ -v /var/run/docker.sock:/var/run/docker.sock \ -e GITHUB_TOKEN=$(gh auth token) \ diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100755 index 45b7fda..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -set -e - -TARGET_UID=${TARGET_UID:-1000} -TARGET_GID=${TARGET_GID:-1000} -USERNAME=${USERNAME:-rgpeach10} - -CURRENT_UID=$(id -u "$USERNAME") -CURRENT_GID=$(id -g "$USERNAME") - -# Rewrite the user/group IDs if they differ from build time -if [ "$CURRENT_UID" != "$TARGET_UID" ] || [ "$CURRENT_GID" != "$TARGET_GID" ]; then - sed -i "s/^$USERNAME:x:$CURRENT_UID:$CURRENT_GID:/$USERNAME:x:$TARGET_UID:$TARGET_GID:/" /etc/passwd - sed -i "s/^$USERNAME:x:$CURRENT_GID:/$USERNAME:x:$TARGET_GID:/" /etc/group - chown "$TARGET_UID:$TARGET_GID" "/home/$USERNAME" - ITEMS=$(find "/home/$USERNAME" -mindepth 1 -maxdepth 1 ! -name mnt) - TOTAL=$(printf '%s\n' "$ITEMS" | wc -l) - I=0 - printf '%s\n' "$ITEMS" | while read -r item; do - I=$((I + 1)) - printf '\r\033[Kchown [%d/%d] %s' "$I" "$TOTAL" "${item##*/}" - chown -R "$TARGET_UID:$TARGET_GID" "$item" - done - printf '\r\033[Kchown complete (%d items)\n' "$TOTAL" -fi - -exec su - "$USERNAME" -s /bin/zsh -c "$*" From 1449aee8a6bc64c756eac0654a10fed2d1551066 Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Thu, 2 Apr 2026 00:07:41 -0400 Subject: [PATCH 09/10] Handle id out of range error --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9570db3..e138214 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,10 @@ ARG TARGETPLATFORM ARG UID=1000 ARG GID=1000 ENV USERNAME=rgpeach10 -RUN adduser -D -u ${UID} -g ${GID} ${USERNAME} +RUN addgroup -g ${GID} ${USERNAME} 2>/dev/null || addgroup ${USERNAME}; \ + adduser -D -H -u ${UID} -G ${USERNAME} ${USERNAME} 2>/dev/null || \ + (echo "${USERNAME}:x:${UID}:${GID}::/home/${USERNAME}:/bin/sh" >> /etc/passwd && \ + mkdir -p /home/${USERNAME} && chown ${UID}:${GID} /home/${USERNAME}) # Stable repos first, edge as fallback for packages not yet in stable # Stable repos first From 2e637738715768ceb20f1813ae139e5f2d2727fb Mon Sep 17 00:00:00 2001 From: Ryan Peach Date: Thu, 2 Apr 2026 00:23:37 -0400 Subject: [PATCH 10/10] Run instructions --- Justfile | 35 ++++++++++++++++++++++++----------- README.md | 4 ++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Justfile b/Justfile index 6bad71c..024c467 100644 --- a/Justfile +++ b/Justfile @@ -1,28 +1,41 @@ build: - docker buildx build --progress=plain -t rgpeach10/shell:local --no-cache . --load + docker buildx build \ + --progress=plain \ + --build-arg UID=$(id -u) \ + --build-arg GID=$(id -g) \ + --build-arg USERNAME=$(whoami) \ + -t rgpeach10/shell:local \ + . \ + --load run-local: docker run -it --rm \ - -v $HOME/.ssh:/home/root/.ssh \ - -v $HOME:/home/root/mnt \ - -w /home/root/mnt \ + --user $(id -u) \ + -v $HOME:/home/$(whoami)/mnt \ + -v /var/run/docker.sock:/var/run/docker.sock \ -e GITHUB_TOKEN=$(gh auth token) \ - -e MNT=/home/root/mnt \ - -e DEBUG=1 \ + --pull=always \ rgpeach10/shell:local run-remote tag="local": docker run -it --rm \ - -v $HOME/.ssh:/home/root/.ssh \ - -v $HOME:/home/root/mnt \ - -w /home/root/mnt \ + --user $(id -u) \ + -v $HOME:/home/$(whoami)/mnt \ + -v /var/run/docker.sock:/var/run/docker.sock \ -e GITHUB_TOKEN=$(gh auth token) \ - -e MNT=/home/root/mnt \ --pull=always \ rgpeach10/shell:{{tag}} build-all tag="local": - docker buildx build --progress=plain -t rgpeach10/shell:{{tag}} --platform linux/amd64,linux/arm64 . --push + docker buildx build \ + --progress=plain \ + --build-arg UID=$(id -u) \ + --build-arg GID=$(id -g) \ + --build-arg USERNAME=$(whoami) \ + -t rgpeach10/shell:{{tag}} \ + --platform linux/amd64,linux/arm64 \ + . \ + --push test: just build diff --git a/README.md b/README.md index c580a72..8eeaaf0 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,6 @@ Create a `~/.docker-shell.sh` file with the following contents: docker run -it --rm \ --user $(id -u) \ - -e TARGET_USER=$(id -u) \ - -e GLOBAL_USER=$(id -g) \ -v $HOME:/home/rgpeach10/mnt \ -v /var/run/docker.sock:/var/run/docker.sock \ -e GITHUB_TOKEN=$(gh auth token) \ @@ -47,6 +45,8 @@ docker run -it --rm \ rgpeach10/shell:main ``` +NOTE: User must match the $UID and $(id -g) must match $GID build args. Othwerwise, please build this locally then run it. + Then set your terminal to launch this script when you open it. Or you could put it in your `~/.bash_profile`, `~/.bashrc`, or `~/.zshrc` file.