diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index adebb0e5fd..5906bc0dcc 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,7 +1,8 @@ -FROM mcr.microsoft.com/devcontainers/python:3.11 +FROM mcr.microsoft.com/devcontainers/python:3.11-bookworm # Makes installation faster ENV UV_COMPILE_BYTECODE=1 +ENV DEBIAN_FRONTEND=noninteractive SHELL ["/bin/bash", "-c"] @@ -11,66 +12,61 @@ USER root RUN rm -f /etc/apt/sources.list.d/yarn.list 2>/dev/null || true # Install required system packages + ODBC prerequisites -RUN apt-get update && apt-get install -y \ - sudo \ - unixodbc \ - unixodbc-dev \ - libgl1 \ - git \ - curl \ - xdg-utils \ - build-essential \ - && apt-get clean && rm -rf /var/lib/apt/lists/* +RUN --mount=type=cache,target=/var/cache/apt \ + --mount=type=cache,target=/var/lib/apt \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + sudo \ + unixodbc \ + unixodbc-dev \ + libgl1 \ + git \ + curl \ + xdg-utils \ + build-essential -# Install the Azure CLI, Microsoft ODBC Driver 18 & SQL tools +# Install Microsoft ODBC Driver 18 & SQL tools # Note: Debian Trixie's sqv rejects SHA1 signatures, so we use gpg directly to import the Microsoft key -RUN apt-get update && apt-get install -y \ - apt-transport-https \ +RUN --mount=type=cache,target=/var/cache/apt \ + --mount=type=cache,target=/var/lib/apt \ + apt-get update \ + && apt-get install -y --no-install-recommends \ ca-certificates \ gnupg \ - lsb-release \ && curl -sL https://packages.microsoft.com/keys/microsoft.asc \ | gpg --dearmor \ > /usr/share/keyrings/microsoft-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" \ > /etc/apt/sources.list.d/microsoft.list \ && apt-get update \ - && ACCEPT_EULA=Y apt-get install -y msodbcsql18 mssql-tools18 \ - && apt-get install -y azure-cli \ - && echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> /etc/profile.d/sqltools.sh \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + && ACCEPT_EULA=Y apt-get install -y --no-install-recommends \ + msodbcsql18 \ + mssql-tools18 \ + && echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> /etc/profile.d/sqltools.sh # audio back-ends needed by Azure Speech SDK -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive \ - apt-get install -y --no-install-recommends \ +RUN --mount=type=cache,target=/var/cache/apt \ + --mount=type=cache,target=/var/lib/apt \ + apt-get update \ + && apt-get install -y --no-install-recommends \ libasound2 \ - libpulse0 \ - && rm -rf /var/lib/apt/lists/* + libpulse0 + +# Install Node.js 24.x LTS for frontend development +RUN --mount=type=cache,target=/var/cache/apt \ + --mount=type=cache,target=/var/lib/apt \ + curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \ + && apt-get install -y --no-install-recommends nodejs # Install uv system-wide and create pyrit-dev venv -RUN curl -LsSf https://astral.sh/uv/install.sh | sh \ - && mv /root/.local/bin/uv /usr/local/bin/uv \ - && rm -rf /opt/venv \ - && uv venv /opt/venv --python 3.11 --prompt pyrit-dev \ - && chown -R vscode:vscode /opt/venv \ - && ls -la /opt/venv/bin/activate +COPY --from=ghcr.io/astral-sh/uv:0.10.8 /uv /uvx /bin/ +RUN uv venv /opt/venv --python 3.11 --prompt pyrit-dev \ + && chown -R vscode:vscode /opt/venv ENV PATH="/opt/venv/bin:$PATH" # vscode user already exists in the base image, just ensure sudo access RUN echo "vscode ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers -# Install Node.js 20.x and npm for frontend development -RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ - && apt-get install -y nodejs \ - && npm install -g npm@latest \ - && npm install -g @github/copilot@0.0.421 \ - && npm cache clean --force \ - && rm -rf /root/.npm \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - # Pre-create common user caches and fix permissions RUN mkdir -p /home/vscode/.cache/pre-commit \ && mkdir -p /home/vscode/.vscode-server \ @@ -79,7 +75,7 @@ RUN mkdir -p /home/vscode/.cache/pre-commit \ && mkdir -p /home/vscode/.cache/venv \ && mkdir -p /home/vscode/.cache/pylance \ && chown -R vscode:vscode /home/vscode/.cache /home/vscode/.vscode-server \ - && chmod -R 777 /home/vscode/.cache/pip /home/vscode/.cache/pylance /home/vscode/.cache/venv /home/vscode/.cache/uv\ + && chmod -R 755 /home/vscode/.cache/pip /home/vscode/.cache/pylance /home/vscode/.cache/venv /home/vscode/.cache/uv \ && chmod -R 755 /home/vscode/.vscode-server USER vscode @@ -95,6 +91,6 @@ RUN git config --global core.preloadindex true \ && git config --global status.showUntrackedFiles all \ && git config --global core.fsmonitor true - # Set cache directories so they can be mounted +# Set cache directories so they can be mounted ENV PIP_CACHE_DIR="/home/vscode/.cache/pip" ENV UV_CACHE_DIR="/home/vscode/.cache/uv" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ca80e23a03..2f762555c5 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -90,6 +90,14 @@ ] } }, + "features": { + "ghcr.io/devcontainers/features/azure-cli:1": { + "version": "latest" + }, + "ghcr.io/devcontainers/features/copilot-cli:1": { + "version": "latest" + } + }, "postCreateCommand": "/bin/bash -i .devcontainer/devcontainer_setup.sh", "forwardPorts": [3000, 4213, 5000, 8000, 8888] } diff --git a/.devcontainer/devcontainer_setup.sh b/.devcontainer/devcontainer_setup.sh index 3657b804ff..46033fd2db 100644 --- a/.devcontainer/devcontainer_setup.sh +++ b/.devcontainer/devcontainer_setup.sh @@ -8,7 +8,7 @@ if [ ! -d "$MYPY_CACHE" ]; then echo "Creating mypy cache directory..." sudo mkdir -p $MYPY_CACHE sudo chown vscode:vscode $MYPY_CACHE - sudo chmod 777 $MYPY_CACHE + sudo chmod 755 $MYPY_CACHE else # Check ownership OWNER=$(stat -c '%U:%G' $MYPY_CACHE) @@ -21,9 +21,9 @@ else # Check permissions PERMS=$(stat -c '%a' $MYPY_CACHE) - if [ "$PERMS" != "777" ]; then + if [ "$PERMS" != "755" ]; then echo "Fixing mypy cache directory permissions..." - sudo chmod -R 777 $MYPY_CACHE + sudo chmod -R 755 $MYPY_CACHE fi fi diff --git a/build_scripts/prepare_package.py b/build_scripts/prepare_package.py index 0eec9f3d69..8e999c8129 100644 --- a/build_scripts/prepare_package.py +++ b/build_scripts/prepare_package.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. @@ -33,7 +32,7 @@ def build_frontend(frontend_dir: Path) -> bool: print(f"Found npm version: {result.stdout.strip()}") except (subprocess.CalledProcessError, FileNotFoundError): print("ERROR: npm is not installed or not in PATH") - print("Please install Node.js 20.x and npm from https://nodejs.org/") + print("Please install Node.js 24.x and npm from https://nodejs.org/") return False # Check if package.json exists diff --git a/docker/build_pyrit_docker.py b/docker/build_pyrit_docker.py index 406647d84d..07f77abe1f 100644 --- a/docker/build_pyrit_docker.py +++ b/docker/build_pyrit_docker.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. diff --git a/docker/run_pyrit_docker.py b/docker/run_pyrit_docker.py index 63bdcbd150..c2fdad82c6 100644 --- a/docker/run_pyrit_docker.py +++ b/docker/run_pyrit_docker.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright (c) Microsoft Corporation. # Licensed under the MIT license.