# syntax=docker/dockerfile:1.10.0 # SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # This Dockerfile creates a local development environment for Dev Container plug-in use. # It takes a BASE image (typically the dev target) and adds local-dev specific configurations # including additional developer utilities and tools. # # Usage: # - Dev Container IDE Extension: Use directly with VS Code/Cursor Dev Container extension # - Command line: run.sh --image --mount-workspace ... # where the ubuntu user inside the container is mapped to your local user login ARG DEV_BASE="" FROM ${DEV_BASE} AS local-dev # Don't want ubuntu to be editable, just change uid and gid. ENV USERNAME=ubuntu ARG USER_UID ARG USER_GID ARG WORKSPACE_DIR=/workspace ARG ARCH # Update package lists and install developer utilities. Some of these may exist in the base image, # but to ensure consistency across all dev images, we explicitly list all required dev tools here. RUN apt-get update && apt-get install -y \ # Development utilities curl wget git vim nano \ # System utilities htop nvtop tmux screen \ # Network utilities net-tools iproute2 iputils-ping \ # Archive utilities zip unzip rsync \ # Build tools build-essential cmake autoconf automake libtool \ # Debug and analysis tools gdb valgrind strace ltrace \ # Text processing jq yq grep sed \ # File utilities tree fd-find ripgrep \ # Shell utilities zsh fish bash-completion # https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user # Configure user with sudo access for Dev Container workflows RUN apt-get install -y sudo gnupg2 gnupg1 \ && echo "$USERNAME ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME \ && chmod 0440 /etc/sudoers.d/$USERNAME \ && mkdir -p /home/$USERNAME \ && groupmod -g $USER_GID $USERNAME \ && usermod -u $USER_UID -g $USER_GID $USERNAME \ && chown -R $USERNAME:$USERNAME /home/$USERNAME \ && chsh -s /bin/bash $USERNAME # Install awk separately with fault tolerance # awk is a virtual package with multiple implementations (gawk, mawk, original-awk). # Separated because TensorRT-LLM builds failed on awk package conflicts. # This prevents main package installation failures due to awk availability issues. RUN (apt-get install -y gawk || \ apt-get install -y mawk || \ apt-get install -y original-awk || \ echo "Warning: Could not install any awk implementation") && \ (which awk && echo "awk successfully installed: $(which awk)" || echo "awk not available") # Add NVIDIA devtools repository and install development tools RUN wget -qO - https://developer.download.nvidia.com/devtools/repos/ubuntu2404/${ARCH}/nvidia.pub | gpg --dearmor -o /etc/apt/keyrings/nvidia-devtools.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nvidia-devtools.gpg] https://developer.download.nvidia.com/devtools/repos/ubuntu2404/${ARCH} /" | tee /etc/apt/sources.list.d/nvidia-devtools.list && \ apt-get update && \ apt-get install -y nsight-systems-2025.5.1 # Clean up package lists at the end RUN rm -rf /var/lib/apt/lists/* # Set workspace directory variable ENV WORKSPACE_DIR=${WORKSPACE_DIR} # Development environment variables for the local-dev target # Path configuration notes: # - DYNAMO_HOME: Main project directory (workspace mount point) # - CARGO_TARGET_DIR: Build artifacts in workspace/target for persistence # - CARGO_HOME: Must be in $HOME/.cargo (not workspace) because: # * Workspace gets mounted to different paths where cargo binaries may not exist # * Contains critical cargo binaries and registry that need consistent paths # - RUSTUP_HOME: Must be in $HOME/.rustup (not workspace) because: # * Contains rust toolchain binaries that must be at expected system paths # * Workspace mount point would break rustup's toolchain resolution # - PATH: Includes cargo binaries for rust tool access ENV HOME=/home/$USERNAME ENV DYNAMO_HOME=${WORKSPACE_DIR} ENV CARGO_TARGET_DIR=${WORKSPACE_DIR}/target ENV CARGO_HOME=${HOME}/.cargo ENV RUSTUP_HOME=${HOME}/.rustup ENV PATH=${CARGO_HOME}/bin:$PATH # Copy Rust toolchain from system directories to user home directories with proper ownership RUN rsync -a --chown=$USER_UID:$USER_GID /usr/local/rustup/ $RUSTUP_HOME/ RUN rsync -a --chown=$USER_UID:$USER_GID /usr/local/cargo/ $CARGO_HOME/ # Copy virtual environment with proper ownership using rsync instead of chown. # Why rsync instead of chown -R: # chown -R is extremely slow in Docker containers, especially on large directory trees # like Python virtual environments with thousands of files. This is a well-documented # Docker performance issue. rsync --chown is 3-4x faster as it sets ownership during copy. RUN rsync -a --chown=$USER_UID:$USER_GID ${VIRTUAL_ENV}/ /tmp/venv-temp/ && \ rm -rf ${VIRTUAL_ENV} && \ mv /tmp/venv-temp ${VIRTUAL_ENV} # At this point, we are executing as the ubuntu user USER $USERNAME WORKDIR $HOME # https://code.visualstudio.com/remote/advancedcontainers/persist-bash-history RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=$HOME/.commandhistory/.bash_history" \ && mkdir -p $HOME/.commandhistory \ && touch $HOME/.commandhistory/.bash_history \ && echo "$SNIPPET" >> "$HOME/.bashrc" RUN mkdir -p /home/$USERNAME/.cache/ ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"] CMD []