From 79908b3c6eb3673f3131d8c6b77ff789556ab327 Mon Sep 17 00:00:00 2001 From: Wing Lian Date: Thu, 12 Mar 2026 20:41:13 -0400 Subject: [PATCH] use ubuntu user instead of root for uv docker images (#3491) --- docker/Dockerfile-cloud-uv | 21 +++++++++++++-------- docker/Dockerfile-uv | 10 +++++++--- docker/Dockerfile-uv-base | 12 +++++++++--- scripts/cloud-entrypoint.sh | 23 +++++++++++++++++------ 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/docker/Dockerfile-cloud-uv b/docker/Dockerfile-cloud-uv index a53dd6135..c38b21e6f 100644 --- a/docker/Dockerfile-cloud-uv +++ b/docker/Dockerfile-cloud-uv @@ -1,6 +1,8 @@ ARG BASE_TAG=main FROM axolotlai/axolotl-uv:$BASE_TAG +USER root + ENV HF_DATASETS_CACHE="/workspace/data/huggingface-cache/datasets" ENV HF_HUB_CACHE="/workspace/data/huggingface-cache/hub" ENV HF_HOME="/workspace/data/huggingface-cache/hub" @@ -9,7 +11,7 @@ ENV HF_HUB_ENABLE_HF_TRANSFER="1" EXPOSE 8888 EXPOSE 22 -COPY scripts/cloud-entrypoint.sh /root/cloud-entrypoint.sh +COPY scripts/cloud-entrypoint.sh /home/ubuntu/cloud-entrypoint.sh COPY scripts/motd /etc/motd RUN uv pip install jupyterlab notebook ipywidgets && \ @@ -18,13 +20,16 @@ RUN apt update && \ apt install --yes --no-install-recommends openssh-server tmux iproute2 nvtop && \ rm -rf /var/cache/apt/archives && \ rm -rf /var/lib/apt/lists/* && \ - mkdir -p ~/.ssh && \ - chmod 700 ~/.ssh && \ - printf "\n[[ -z \"\$TMUX\" ]] && { tmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux; exit; }\n" >> ~/.bashrc && \ - printf "[ ! -z \"\$TERM\" -a -r /etc/motd ] && cat /etc/motd\n" >> ~/.bashrc && \ + mkdir -p /home/ubuntu/.ssh && \ + chmod 700 /home/ubuntu/.ssh && \ + printf "\n[[ -z \"\$TMUX\" ]] && { tmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux; exit; }\n" >> /home/ubuntu/.bashrc && \ + printf "[ ! -z \"\$TERM\" -a -r /etc/motd ] && cat /etc/motd\n" >> /home/ubuntu/.bashrc && \ chmod +x /workspace/axolotl/scripts/cloud-entrypoint.sh && \ - chmod +x /root/cloud-entrypoint.sh && \ - echo 'set-option -g history-limit 5000' >> ~/.tmux.conf + chmod +x /home/ubuntu/cloud-entrypoint.sh && \ + echo 'set-option -g history-limit 5000' >> /home/ubuntu/.tmux.conf && \ + chown -R ubuntu:ubuntu /home/ubuntu /workspace -ENTRYPOINT ["/root/cloud-entrypoint.sh"] +USER ubuntu + +ENTRYPOINT ["/home/ubuntu/cloud-entrypoint.sh"] CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile-uv b/docker/Dockerfile-uv index 0142c0d2d..f149d3410 100644 --- a/docker/Dockerfile-uv +++ b/docker/Dockerfile-uv @@ -43,6 +43,10 @@ RUN git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && \ git config --get remote.origin.fetch && \ git config --global credential.helper store -COPY .axolotl-complete.bash /root/.axolotl-complete.bash -RUN chmod +x /root/.axolotl-complete.bash && \ - echo 'source /root/.axolotl-complete.bash' >> ~/.bashrc +COPY .axolotl-complete.bash /home/ubuntu/.axolotl-complete.bash +RUN chmod +x /home/ubuntu/.axolotl-complete.bash && \ + echo 'source /home/ubuntu/.axolotl-complete.bash' >> /home/ubuntu/.bashrc + +RUN chown -R ubuntu:ubuntu /workspace /home/ubuntu + +USER ubuntu diff --git a/docker/Dockerfile-uv-base b/docker/Dockerfile-uv-base index 0e7acbe29..e6da9ac84 100644 --- a/docker/Dockerfile-uv-base +++ b/docker/Dockerfile-uv-base @@ -17,11 +17,15 @@ ENV TORCH_CUDA_ARCH_LIST=$TORCH_CUDA_ARCH_LIST ENV UV_TORCH_BACKEND="cu${CUDA}" RUN apt-get update \ - && apt-get install -y wget git build-essential ninja-build git-lfs libaio-dev pkg-config curl && rm -rf /var/lib/apt/lists/* \ + && apt-get install -y wget git build-essential ninja-build git-lfs libaio-dev pkg-config curl sudo && rm -rf /var/lib/apt/lists/* \ && git lfs install --skip-repo \ - && curl -LsSf https://astral.sh/uv/install.sh | sh + && curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh -ENV PATH="/root/.local/bin:${PATH}" +# Create ubuntu user with passwordless sudo +RUN useradd -m -s /bin/bash -u 1000 ubuntu 2>/dev/null; \ + usermod -aG sudo ubuntu && \ + echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/ubuntu && \ + chmod 0440 /etc/sudoers.d/ubuntu RUN uv python install ${PYTHON_VERSION} @@ -55,3 +59,5 @@ RUN PYTHON_CP="cp$(echo $PYTHON_VERSION | tr -d '.')" && \ wget -nv "https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/download/${WHL_VERSION}/${WHL_FILE}" && \ uv pip install --no-cache-dir "${WHL_FILE}" && \ rm "${WHL_FILE}" + +RUN chown -R ubuntu:ubuntu /workspace diff --git a/scripts/cloud-entrypoint.sh b/scripts/cloud-entrypoint.sh index c98e7c0d0..e88762e13 100755 --- a/scripts/cloud-entrypoint.sh +++ b/scripts/cloud-entrypoint.sh @@ -1,8 +1,15 @@ #!/bin/bash +# Detect if running as non-root and set sudo prefix accordingly +if [ "$(id -u)" -ne 0 ]; then + SUDO="sudo" +else + SUDO="" +fi + # Export specific ENV variables to /etc/rp_environment echo "Exporting environment variables..." -printenv | grep -E '^HF_|^BNB_|^CUDA_|^NCCL_|^NV|^RUNPOD_|^PATH=|^_=' | sed 's/^\([^=]*\)=\(.*\)$/export \1="\2"/' | grep -v 'printenv' >> /etc/rp_environment +printenv | grep -E '^HF_|^BNB_|^CUDA_|^NCCL_|^NV|^RUNPOD_|^PATH=|^_=' | sed 's/^\([^=]*\)=\(.*\)$/export \1="\2"/' | grep -v 'printenv' | $SUDO tee /etc/rp_environment > /dev/null echo 'source /etc/rp_environment' >> ~/.bashrc add_keys_to_authorized() { @@ -46,19 +53,19 @@ add_keys_to_authorized() { # Set SSH port if [ ! -z "$SSH_PORT" ]; then - sed -i "s/#Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config + $SUDO sed -i "s/#Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config fi if [[ $PUBLIC_KEY ]]; then # runpod, prime intellect add_keys_to_authorized "$PUBLIC_KEY" # Start the SSH service in the background - service ssh start + $SUDO service ssh start elif [[ $SSH_KEY ]]; then # latitude.sh add_keys_to_authorized "$SSH_KEY" # Start the SSH service in the background - service ssh start + $SUDO service ssh start else echo "No PUBLIC_KEY or SSH_KEY environment variable provided, not starting openSSH daemon" fi @@ -71,7 +78,11 @@ fi if [ "$JUPYTER_DISABLE" != "1" ]; then # Run Jupyter Lab in the background - jupyter lab --port=8888 --ip=* --allow-root --ServerApp.allow_origin=* & + JUPYTER_ARGS="--port=8888 --ip=* --ServerApp.allow_origin=*" + if [ "$(id -u)" -eq 0 ]; then + JUPYTER_ARGS="$JUPYTER_ARGS --allow-root" + fi + jupyter lab $JUPYTER_ARGS & fi if [ ! -d "/workspace/data/axolotl-artifacts" ]; then @@ -86,7 +97,7 @@ SLURM_INIT="${SLURM_INIT:-/slurm-init.sh}" if [[ -f "$SLURM_INIT" ]]; then echo "[entrypoint] running $SLURM_INIT..." - bash "$SLURM_INIT" + $SUDO bash "$SLURM_INIT" fi # Execute the passed arguments (CMD)